building a messaging server part four

SSL Support and SMTP Auth

Transmitting email over an insecure connection is just plain stupid. Adding SSL support to the mail server is virtually effortless -- and that's what'll be covered here.

Installing OpenSSL

In order to create an SSL connection, OpenSSL will need installed on the server.

apt-get install openssl

Creating a Certificate

Next, a certificate will need to be made. You can either purchase one from a vendor or create your own self-signed. For this article, we'll be creating a self-signed certificate.

The first step is to create a new root certificate in which all other certificates will be derived from. If you already have your own root CA up and running then skip this part. But if not, follow along.

I keep my certificates in the /srv/ssl directory. This is just because my /srv folder is on a RAID mirror.

Run the command CA.pl like so:

/usr/lib/ssl/misc/CA.pl -newca

Follow the instructions. When the command is complete, there will be a new directory called demoCA. Rename this to rootCA.

mv demoCA rootCA
cd rootCA

Inside rootCA will be a file called cacert.pem. This is the root certificate. Any client that will be accessing your server should import this root certificate. This will stop client application from displaying errors about the certificate not being trusted.

Next, copy the openssl.cnf from /usr/lib/ssl to the rootCA directory:

cp /usr/lib/ssl/openssl.cnf .

Edit the file. On line 37, change the directory to ..

The next step is to create a certificate request:

openssl req -new -out req.pem -config ./openssl.cnf

This will create two files: req.pem and privkey.pem. Rename privkey.pem to something more descriptive like mail.key.pem.

Finally, sign the request:

openssl ca -out mail.cert.pem -config ./openssl.cnf -infiles req.pem

mail.cert.pem will contain both the certificate data and some human-readable stuff. You can strip away the human-readable stuff:

mv mail.cert.pem tmp.pem
openssl x509 -in tmp.pem -out mail.cert.pem
rm tmp.pem

The mail.key.pem file is secured with the passphrase you used when creating it. This can be a pain because any time you start a server that uses this key, you'll be required to input the key. In situations where your server reboots and you're not available to type in the key, the server will just hang until you type it in. To fix this, you can remove the passphrase:

mv mail.key.pem tmp.pem
openss rsa -in tmp.pem -out mail.key.pem
rm tmp.pem

Finally, some services require both the key and cert to be combined in one file:

cat mail.key.pem mail.cert.pem > mail.certkey.pem

So now there are three files: mail.key.pem, mail.cert.pem, and mail.certkey.pem. Copy these files over to the mail server in the /etc/ssl/certs directory.

Adding SSL Support to Dovecot

As well as supporting the IMAP and POP3 protocols, Dovecot also supports their secure counterparts, IMAPs and POP3s. Turning them on in Dovecot is incredibly simple -- all it takes is modifying one line in the /etc/dovecot/dovecot.conf configuration file and adding two new ones.

The protocols line will need to be edited. It currently looks like this:

protocols = imap pop3

We'll now add support for IMAPs and POP3s:

protocols = imap pop3 imaps pop3s

Next add the following two lines:

ssl_cert_file = /etc/ssl/certs/mail.cert.pem
ssl_key_file = /etc/ssl/certs/mail.key.pem

Restart Dovecot and that's all there is to it.

Adding SSL/TLS Support to Postfix

Postfix has the ability to support TLS connetions. Basically, if a client connects to port 25 and lets Postfix know it's able to handle a secure connection, Postfix will do so.

To enable this in Postfix, add the following to /etc/postfix/main.cf:

1. smtpd_tls_cert_file = /etc/ssl/certs/mail.cert.pem
2. smtpd_tls_key_file = /etc/ssl/certs/mail.key.pem
3. smtpd_tls_CAfile = /etc/ssl/certs/cacert.pem
4. smtpd_tls_security_level = may
5. smtpd_tls_session_cache_database = btree:${queue_directory}/smtpd_scache
6. smtp_tls_session_cache_database = btree:${queue_directory}/smtp_scache

The first three lines are self-explanatory -- they're just locating the certificate files.

The forth line makes TLS connections optional.

The fifth and sixth lines define a cache for TLS connections. Creating TLS connection involves a lot of processing overhead, so to cut down, a cache is created.

Enabling SMTP Auth in Postfix

Postfix should only send email on behalf of the network it's serving. However, there are times when you might be working remotely and not have an SMTP server to send an email through. In times like this, it would be nice to be able to use the remote Postfix server, but you shouldn't open it up due to relaying attacks.

The fix for this is SMTP Auth. When enabled, a client can send Postfix a username and password. If the credentials are correct, Postfix will send mail on behalf of that user -- no matter where they are.

Recent versions of Postfix have included support for Dovecot's new SASL library. This enables Postfix to lookup the client credentials by using Dovecot as an authentication source. Basically, this allows us to use the /etc/postfix/virtual/passwd file for SMTP Auth.

Setting this up in Postfix involves a few extra lines in main.cf:

1. smtpd_sasl_auth_enable = yes
2. smtpd_recipient_restrictions = 
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination
3. broken_sasl_auth_clients = yes
4. smtpd_sasl_type = dovecot
5. smtpd_sasl_path = private/auth
6. smtpd_tls_auth_only = yes

Line one turns SMTP Auth on.

Line two modifies the Recipient Restriction rules. This is now telling Postfix to accept mail on behalf of machines in its network, authenticated users, and reject anyone else.

Line three fixes some bugs in clients such as Outlook.

Line four tells Postfix to use Dovecot for SASL.

Line five specifies where it can find the SASL socket. In this case, the full path will be:

/var/spool/postfix/private/auth

Line six restricts authentication to clients who are only using TLS.

Setting Up Dovecot for SMTP Auth

Since Dovecot will be authenticating on behalf of Postfix, some configuration needs to take place. Inside /etc/dovecot/dovecot.conf, add the following under the auth section:

socket listen {
  client {
    path = /var/spool/postfix/private/auth
    mode = 0660
    user = postfix
    group = postfix
  }
}

All this is doing is making Dovecot set up a socket called /var/spool/postfix/private/auth as user and group postfix and wait for requests. When the request is received, it will try to authenticate the user.

If your mail client supports SMTP Auth as well as TLS for the outbound mail server, you can test this out by sending an email with these options enabled. You can verify it works by purposely typing in the wrong password and see if you get an authentication error.