Friday, June 26, 2009

Getting mail on my iPhone

We got our iPhones 3GS on the launch day, and I spent part of the weekend getting mail working right. I did hit a few issues, but I have everything working acceptable now. This is all based on my previous post on configuring a mail proxy.

The issues I hit were:
  • Can't seem to get the phone to connect on a user specified port for either IMAP or SMTP. There are options for that, but I could never get my phone to (reliably) use them.
  • I could never get starttls to work with the iPhone. Other clients, mail.app, worked just fine. This is annoying, but not such a big deal. The password for the login is still encrypted and the mail itself would normally be going outside of my systems anyway.
  • There is no "advanced" or "expert" UI for initially setting up email accounts on the iPhone (nor on mail.app). This means that you have to wait as the phone walks through a lot of default mail options (ports to connect on, SSL or no SSL, etc) before you get a chance to adjust anything.
So here are the steps. There was some bit of trial and error, but I tried to record everything accurately.
  1. Before you try to setup any mail accounts on the phone, you should import all of your self signed certs to the phone. To do this, simply upload all of the certs, renamed to something.crt to a web server and then load that site in Safari on your iPhone. That means to put the .crt files into a directory you can access from your phone (or any browser), not to use the certs to SSL encrypt the site. When you load each of those files in Safari (like going to http:///your.site.tld/file/mycert.crt), you'll get a new application to import the cert into your profile.
  2. Now create the accounts on the iPhone as you would otherwise. The settings for your connections are:
    ConnectionUsernameAuthenticationSSL
    IncomingusernamePasswordOn
    Outgoingusername@domainCRAM-MD5Off

  3. When making the initial IMAPS connection, you will be prompted to accept the certificate. Click to continue/accept the cert. I would have thought that importing the certs to my phone's profiles would have taken care of this, but it didn't. Of course there is probably some nuance of PKI that I don't grok (feel free to enlighten me if you know the details).
  4. After much waiting as the phone tries various incarnations of SMTP connections, you'll get prompted to attempt to proceed un-encrypted. Say NO here. If you say "yes"it seems to screw up the IMAPS connection that is actually working fine at this point.
  5. Now go into the mail settings and fix the SMTP connection to work right. Turn off SSL and set the authentication to CRAM-MD5.
  6. Open mail on the phone and you should mail working fine. Try reading some of your mail and try sending some to make sure it all works right.
That's about it. This is far from perfect, but seems to be working reliably and the boss (wife) approves. If someone has details on how to make this better or more efficient, please let me know.

Monday, June 15, 2009

OpenBSD + SMTP AUTH/TLS + IMAPS Proxy

Problem

I want to securely access my home email from my newly ordered iPhone 3GS. Since my mail repository is at home (vs on some one's webmail/freemail platform) and I want to be able to send email from my domain, I need to connect from essentially anywhere to my home systems.

Solution

I have an existing bastion host running OpenBSD to which I added the mail functions. Documentation that I found was a bit out dated or didn't quite put everything together, so I'm putting it all together here. This article is based on what is available with OpenBSD 4.5.

First, what are the different pieces in this puzzle?
  • Retrieve/view mail: I keep all of my mail on a server at home and provide access via IMAP(S). I extended this by using dovecot as an IMAP proxy on the bastion host. This allows you to view your mail.
  • Sending mail: Sendmail is the base MTA I'm using (it's part of the base install of OpenBSD) and to get the secure authenticated connection for remotely sending mail, two different things are needed.
    • TLS: For my purposes, this encrypts the connection via starttls(8)
    • Authentication: This provides the ability to authenticate users and allow authenticated users to relay mail through the server. This is done via cyrus-sasl.
Dovecot/IMAP Configuration

The configuration for dovecot is rather simple, but I never found it explicitly called out. Acting as a proxy for a particular user is done as part of an entry in the user database. Larger installations with many users can use a database for this, but for a small handful of users, this is more easily done with a passwd-file.
  1. Install dovecot. Either build it from source via ports or install the package. See the OpenBSD FAQ for how to do this.
  2. In /etc/dovecot.conf, find the section specifying the password database as a passwd-file and uncomment it such that you end up with the following. See AuthDatabase/PasswdFile section of the dovecot wiki for more details.
    # passwd-like file with specified location
    #
    passdb passwd-file {
    # [scheme=] [username_format=]
    #
    args = username_format=%n /etc/dovecot.passwd
    }
  3. Create the passwd file, /etc/dovecot.passwd, in your favorite editor filling in the fields as described in the Passwd-file documentation. You should end up with something that looks like the following:
    fred:{PLAIN-MD5}b40ac4fe40284c9de587b992c08f167::::::proxy=y host=my.proxy.domain.tld port=143
    The last fields, the extra fields, are the ones that make the proxy actually work. Note that the TLS/SSL options discussed in the dovecot documentation are only available in newer versions (1.2.rc4+) and not in the stable versions. That means I'm stuck with an un-encrypted connection between my bastion host/proxy and my real mail server. This isn't the perfect solution, but I prefer using the proxy to just allowing a direct connection from anywhere on the internet to my internal servers. Create the md5 passphrase hash with the md5(1) command:
    md5 -s password
  4. Configure dovecot to start at boot (if you didn't when you installed it) and start up dovecot. In /etc/rc.local add:
    if [ -x /usr/local/sbin/dovecot ]; then
    echo -n ' dovecot'; /usr/local/sbin/dovecot
    fi
Sendmail TLS Configuration

This is the easy part to write up. Follow the steps in the starttls(8) man page. Remember, this just gives you encryption when connecting to send mail.

Sendmail Authentication

This requires installing the Cyrus-SASL libraries, configuring users and saslauthd, recompiling sendmail and configuring sendmail.
  1. Install cyrus-sasl. Either build it from source via ports or install the package. See theOpenBSD FAQ for how to do this.
  2. Configure the sasl auth daemon for authentication from sendmail:
    echo pwcheck_method: saslauthd > /usr/local/lib/sasl2/Sendmail.conf
  3. Create users (these are the users and passwords for sending mail) with saslpasswd2(8) with the following command (you'll be prompted for a password). This will create /etc/sasldb2.db. You will use username@domain as the username for authentication.
    saslpasswd2 -c -u domain username
  4. Configure saslauthd to start at boot by adding the following to /etc/rc.local :
    if [ -x /usr/local/sbin/saslauthd ]; then
    echo -n ' saslauthd'; /usr/local/sbin/saslauthd -a getpwent
    fi
  5. Start saslauthd with /usr/local/sbin/saslauthd -a getpwent
  6. Rebuild sendmail with sasl support:
    • Add WANT_SMTPAUTH=YES to /etc/mk.conf
    • If you don't have the OpenBSD source code installed, install it. See the OpenBSD FAQ for details on doing so if needed.
    • cd to /usr/src/gnu/usr.sbin/sendmail/ and build and install sendmail with make clean obj depend && make && make install
  7. Configure sendmail for all of the new options. Edit /usr/share/sendmail/cf/openbsd-proto.mc as follows:
    • Uncomment (remove the "dnl" from the beginning of the line) the section for TSL/SSL support.
      dnl
      dnl TLS/SSL support; uncomment and read starttls(8) to use.
      dnl
      define(`CERT_DIR', `MAIL_SETTINGS_DIR`'certs')dnl
      define(`confCACERT_PATH', `CERT_DIR')dnl
      define(`confCACERT', `CERT_DIR/mycert.pem')dnl
      define(`confSERVER_CERT', `CERT_DIR/mycert.pem')dnl
      define(`confSERVER_KEY', `CERT_DIR/mykey.pem')dnl
      define(`confCLIENT_CERT', `CERT_DIR/mycert.pem')dnl
      define(`confCLIENT_KEY', `CERT_DIR/mykey.pem')dnl
    • Add the following options for SMTP AUTH.
      dnl
      dnl Set SMTP AUTH options
      dnl
      define(`confAUTH_MECHANISMS',`PLAIN LOGIN CRAM-MD5 DIGEST-MD5')dnl
      TRUST_AUTH_MECH(`PLAIN LOGIN CRAM-MD5 DIGEST-MD5')dnl
      define(`confAUTH_OPTIONS',`p,y')dnl
      define(`confPRIVACY_FLAGS',`authwarnings,goaway')dnl
  8. Rebuild the cf files and install them by:
    • cd /usr/share/sendmail/cf
    • make distribution
  9. Configure sendmail to listen for connections over the network (default configuration is to listen only on localhost) by adding sendmail_flags="-L sm-mta -bd -q30m" to /etc/rc.conf.local
  10. Kill the running sendmail, source the new configuration options and restart sendmail:
    kill `head -n1 /var/run/sendmail.pid`
    . /etc/rc.conf
    /usr/sbin/sendmail $sendmail_flags
That's it! You should now have everything setup and working. In trouble shooting and testing my configuration, I found it very handy to watch traffic with tcpdump(8) with a command like tcpdump -n -s 1500 -vvvX port 25 .

Credits:
A good bit of the SMTP AUTH configuration steps where taken from http://www.dsrw.org/~dlg/sysadmin/sendmail/ which was written for OpenBSD 3.3. Some things have changed by OpenBSD 4.5 partly compelling me to write this article.


Wednesday, June 10, 2009

Squid Proxy for Security

The Problem

It's pretty standard these days for everyone connected to the Internet to sit behind some kind of firewall. These firewalls are typically configured to block/filter inbound connections, but allow any connections initiated from inside. This is great for blocking the many scans and connection attempts from the outside, but misses what is the more common risk scenario.

Some non-trivial number of exploits aren't sourced by a connection initiated externally. Things such as spyware get introduced into a system via some means such as email attachments or, more commonly, a web browser exploit and a compromised web site. Once installed, they collect data and perform their real nastiness by sending that collected data back to its owner. All of this is done through connections allowed by the firewall policy.

Another issue is that once a nefarious soul has gained access/control of a machine, they'd like to use it to make connections to other machines to conduct various kinds of mischief. Control of the machine is often through some kind of bot that (a) must connect to some control site to get instructions and (b) must be able to make outbound connections to effect trouble on others.

A Solution

A solution to this is to block all outbound access by default and then only allow what is very specifically needed -- only specific hosts can make outbound connections on specific ports to specific destinations. This can seriously limit the usefulness of your systems to a possible attacker. If they can't call home to get commands, can't ship your personal information back to their home base and can't use your machine(s) to attack others, your systems just aren't very interesting. The problem is that without the ability to connect to various places on the internet, your machine(s) become very un-interesting to you, too.

My solution to this is to proxy all of the outbound connections through one host and only allow that one host to make the out bound connections. This provides several advantages:
  • Regardless of hosts coming and going on my network, I don't have to constantly update firewall rules.
  • With a proxy, I can log all of the outbound connections. This provides an audit source and a place to see what is really requested when outbound connections are made.
  • For a bot or spyware to make an outbound connection, they must understand how to use a proxy and know how to grab the proxy settings. Though this isn't necessarily very hard, but it is another hoop that must be jumped through.
  • If I haven't specifically configured my proxy for a given protocol, then outbound connections aren't possible, stopping the exploit from being effective.
For many years, I've used squid as a cacheing proxy to locally cache web content. This made squid an obvious choice to extend for security purposes. The configuration comprised of three steps. First, configure squid to proxy the various protocols I needed to proxy. Second, configure my firewall to only allow the host running squid to have outbound access as needed. Third, configure various clients to use the proxy.

Squid Configuration

I'll assume you have a working squid installation that is already proxying http(s) and ftp traffic. If not, there are a number of how-tos and other documents available on the web for configuring squid for this (and they will do a much better job than I will).

My configuration supports proxying AIM, Yahoo! IM, Google IM/Gtalk (Jabber), MSN Messenger, and rsync. Simply add the following to your squid.conf and restarting squid should allow these protocols to be proxied. I've collected some of these configurations from various places on the web, so I can't claim credit for figuring it all out.

In your squid.conf file add:
################
#
# allow AIM access
#
acl AIM_ports port 5190
acl AIM_domains dstdomain .oscar.aol.com .blue.aol.com
acl AIM_domains dstdomain .messaging.aol.com .aim.com
acl AIM_hosts dstdomain login.oscar.aol.com login.glogin.messaging.aol.com
acl AIM_nets dst 64.12.0.0/255.255.0.0
acl AIM_methods method CONNECT
http_access allow AIM_methods AIM_ports AIM_nets
http_access allow AIM_methods AIM_ports AIM_hosts
http_access allow AIM_methods AIM_ports AIM_domains
#
################

################
#
# allow Google IM (Gtalk) access
#
acl GTALK_ports port 5222 5050
acl GTALK_domains dstdomain .google.com
acl GTALK_hosts dstdomain talk.google.com
acl GTALK_methods method CONNECT
http_access allow GTALK_methods GTALK_ports GTALK_hosts
http_access allow GTALK_methods GTALK_ports GTALK_domains
#
################

################
#
# allow MSN Access
#
acl MSN_ports port 1863 443 1503
acl MSN_domains dstdomain .microsoft.com .hotmail.com .live.com .msft.net .msn.com .passport.com
acl MSN_hosts dstdomain messenger.hotmail.com
acl MSN_nets dst 207.46.111.0/255.255.255.0
acl MSN_methods method CONNECT
http_access allow MSN_methods MSN_ports MSN_hosts
#
################

################
#
# allow Yahoo IM Access
#
acl YIM_ports port 5050
acl YIM_domains dstdomain .yahoo.com .yahoo.co.jp
acl YIM_hosts dstdomain scs.msg.yahoo.com cs.yahoo.co.jp
acl YIM_methods method CONNECT
http_access allow YIM_methods YIM_ports YIM_hosts
http_access allow YIM_methods YIM_ports YIM_domains
#
################

################
#
# allow rsync proxy
#
acl RSYNC_ports port 873
acl RSYNC_methods method CONNECT
http_access allow RSYNC_methods RSYNC_ports
################

Now the rest is up to configuring your firewall appropriately and setting your various clients to use the proxy.