Postfix/dovecot SASL and SSL/TLS guide

Nota bene:

/!\ Notice: This documentation was written for CentOS 5. It may not be accurate for CentOS 6 or subsequent releases.

1. Introduction

This guide is designed to compliment the basic postfix guide. It is written for CentOS 5. Configuration will differ for CentOS 6.

2. What is SASL and do I need it?

By default, postfix uses the $mynetworks parameter to control access, i.e. who can send or relay mail through the mail server. There is no other authentication performed other than checking that the IP address of the user trying to send mail is part of a trusted network as specified in $mynetworks.

If you are only implementing a mail server where all your users are based on the same network then it is unlikely that you will need to use SASL or SSL/TLS. However, if there are mobile users that wish to use the mail server whilst away from base, we need a mechanism to authenticate them as trusted users so that they are able to send mail through the mail server.

SASL (Simple Authentication and Security Layer) provides a mechanism of authenticating users using their username and password. Probably the most well known implementation of SASL is provided by the Cyrus SASL library, but dovecot also has it’s own SASL implementation built in, and as we are already running dovecot we may as well use it for SASL rather than having to install and configure another package.

3. What about SSL/TLS?

So SASL is able to provide a mechanism to authenticate remote users by username and password who wish to send mail through the mail server. Additionally, remote users are able to retrieve mail through IMAP and/or POP3 mechanisms provided by dovecot. However, we have a problem in that these mechanisms are sending usernames and passwords in plain text across the Internet (SASL does support various encrypted authentication methods such as DIGEST-MD5 but these aren’t always universally supported by email client software). This poses a security risk as anyone can potentially intercept this information and steal login details so we need to encrypt the connection. SSL (Secure Sockets Layer), and more recently TLS (Transport Layer Security), offer a mechanism to encrypt communications between two hosts, in our case our mail server and our remote client. SSL was renamed TLS by the IETF as of version 3.1.

4. Configuring SASL in postfix

To configure SASL in postfix, we need to make the following additions to /etc/postfix/main.cf:

smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous

and add permit_sasl_authenticated to our smtpd_recipient_restrictions section of /etc/postfix/main.cf (if you don't have a smtpd_recipient_restrictions section, then the following example will work fine):

smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination

Next we need to configure auth default in the authentication processes section of /etc/dovecot.conf. Uncomment and/or add the following lines as necessary (be careful as this section is heavily commented, some entries already exist, others are commented out and need uncommenting such as socket listen):

auth default {
    mechanisms = plain login
    passdb pam {
    }
    userdb passwd {
    }
    user = root
    socket listen {
      client {
        path = /var/spool/postfix/private/auth
        mode = 0660
        user = postfix
        group = postfix
      }
    }
}

Restart dovecot and reload postfix configuration setting:

service dovecot restart
postfix reload

/!\ Note: For CentOS 6, which uses dovecot 2.x, please see here: http://wiki2.dovecot.org/HowTo/PostfixAndDovecotSASL

5. Testing SASL

Now we have SASL configured we need to test that it is working correctly. For the purposes of testing and/or local security considerations, it may also be useful to restrict $mynetworks to only allow 127.0.0.0/8 so that we may enforce SASL authentication, otherwise relaying from incorrectly configured local clients may still be permitted under the permit_mynetworks setting in smtpd_recipient_restrictions.

/!\ Note: The following paragraphs 'work too hard'. CentOS ships a specific tool, within an openssl option for testing this and much more. See: man s_client which is discussed here for a simpler approach.

We can telnet into the server and attempt to authenticate using our username and password. However, our username and password must be Base64 encoded (note: our username and password is encoded, not encrypted, and it is trivial to decode so is not secure at this stage). A Base64 encoded string of our username and password may be generated using perl as shown below (I used the user 'test' with password 'test1234' in this example)

$ perl -MMIME::Base64 -e 'print encode_base64("\000test\000test1234");'
AHRlc3QAdGVzdDEyMzQ=

For reference, our Base64 encoded string may be decoded with:

$ perl -MMIME::Base64 -e 'print decode_base64("AHRlc3QAdGVzdDEyMzQ=");'
testtest1234

For those that don't have perl, there is an online Base64 encoder available here.

Using our Base64 encoded string to test authentication:

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 mail.example.com ESMTP Postfix
EHLO example.com
250-mail.example.com
250-PIPELINING
250-SIZE 20480000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN AHRlc3QAdGVzdDEyMzQ=
235 2.0.0 Authentication successful
quit
221 2.0.0 Bye
Connection closed by foreign host.

If everything is working, we should see AUTH PLAIN LOGIN (and AUTH=PLAIN LOGIN) indicating that smtp auth is being offered by the mail server and we should then be able to successfully authenticate using our Base64 encoded username and password.

Now we can configure our email clients to use authentication (username and password) when sending mail.

Thunderbird: Edit > Account Settings, and select Outgoing Server (SMTP) in the left hand pane. Select the smtp server and click Edit, and in the Security and Authentication section, tick "Use name and password" and enter your User Name.

Outlook Express: Tools > Accounts > Mail tab > select an account and click properties. Then on the Servers tab, under Outgoing Mail Server, tick "My server requires authentication".

If we send a test message and tail our maillog, assuming everything is working, we should now see our email client authenticated using SASL:

tail -f /var/log/maillog
Mar 18 13:25:56 mail postfix/smtpd[22400]: connect from mail[127.0.0.1]
Mar 18 13:26:02 mail postfix/smtpd[22400]: 105892006E: client=mail[127.0.0.1], sasl_method=PLAIN, sasl_username=ned
Mar 18 13:26:02 mail postfix/cleanup[22404]: 105892006E: message-id=<47DFC2E4.30402@example.com>
Mar 18 13:26:02 mail postfix/qmgr[22338]: 105892006E: from=<ned@example.com>, size=518, nrcpt=2 (queue active)
Mar 18 13:26:02 mail postfix/smtpd[22400]: disconnect from mail[127.0.0.1]
Mar 18 13:26:02 mail postfix/local[22405]: 105892006E: to=<ned@example.com>, relay=local, delay=0.26,
       delays=0.11/0.02/0/0.14, dsn=2.0.0, status=sent (delivered to maildir)
Mar 18 13:26:06 mail postfix/qmgr[22338]: 105892006E: removed

6. Generating SSL certificates

Before we can use SSL or TLS to encrypt our connection, we must first generate the SSL certificates that will be used to identify the server and establish the encryption protocol. SSL certificates consist of a public and private key pair, and may either be self-signed or signed by a trusted root certificate authority. You can freely obtain signed certificates from CAcert and there is a guide available here. However, unfortunately CAcert isn't currently included as a trusted root certificate authority on most popular web browsers, email clients and operating systems, so the benefit of obtaining a CAcert signed certificate is somewhat diminished in that it won't automatically be accepted as trusted on many systems. Whether you use self-signed certificates or certificates signed by a trusted root certificate authority will depend on the intended usage of your server - if your users trust you, then self-signed certificates may well be perfectly acceptable to you.

There are numerous ways of generating SSL certificates using OpenSSL. You can use openssl directly or use one of the supplied scripts such as /etc/pki/tls/misc/CA or /usr/share/doc/dovecot-1.0/examples/mkcert.sh. However, perhaps the easiest method for users new to openssl is to use genkey and follow the on screen prompts.

Genkey is part of the crypto-utils package and can be installed and run from the command line (as root). The following example will generate a key pair for the server mail.example.com that is valid for 1 year:

yum install crypto-utils
genkey --days 365 mail.example.com

/!\ Note: CentOS 6.4 or later uses a version of nss that does not support md5. Because of this, the genkey command would not work. More details and a workaround can be found in the NSS_3.14 release notes. With the release of CESA-2013:1144 md5 is once again supported.

Follow the on screen prompts entering information relating to your locality. The most important entry is the common name as this must match the name users will use to connect to the server. In our example, this would be mail.example.com, but it will most likely be whatever name you have entered in your dns mx record for your mail server. Assuming smtp and imap/pop3 services are running on the same server, then you can use the same certificates for both and clients would enter mail.example.com for both imap/pop3 and outgoing smtp server settings. If you have separate smtp and imap/pop3 servers then you will need to create separate certificates for each. Genkey will also give you the option to create a certificate signing request (CSR) should you wish to obtain a signed certificate from a trusted root certificate authority. Finally, you will be offered the option to encrypt the private key with a passphrase. Do NOT encrypt your private key otherwise whenever the server (or service) restarts it will sit there waiting for you to enter the passphrase which is not very practical on a remote server!

The certificate key pair are created in the following locations:

/etc/pki/tls/certs/mail.example.com.cert  # public cert
/etc/pki/tls/private/mail.example.com.key  # private key

You can leave the certificates in their current location or copy/move them elsewhere. The private key must be owned and read/writable (0600) only by root.

7. Configuring SSL/TLS in postfix

Now we have generated our certificates, we can configure postfix to use them to encrypt SASL authentication sessions. We need to add the following to /etc/postfix/main.cf:

smtpd_tls_security_level = may
smtpd_tls_key_file = /etc/pki/tls/private/mail.example.com.key
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.example.com.cert
# smtpd_tls_CAfile = /etc/pki/tls/root.crt
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_session_cache_database = btree:/var/spool/postfix/smtpd_tls_cache
tls_random_source = dev:/dev/urandom
smtpd_tls_auth_only = yes

'smtpd_tls_security_level = may' replaces the old 'smtpd_use_tls = yes' in postfix 2.3 and enables the use of tls. We have commented out smtpd_tls_CAfile but would use this setting to specify the certificate of any issuing root authority when using signed certificates. 'smtpd_tls_loglevel = 1' will log tls sessions to the postfix mail log (setting to level 0 turns off TLS logging and level 2 may be useful for debugging purposes). The smtpd_tls_session_cache settings cache TLS session keys for 1 hour between sessions and is recommended due to the relatively high cost of repeatedly negotiating TLS session keys for each connection.

The final setting, smtpd_tls_auth_only = yes, forces the use of TLS for SASL authentication and will not allow plain text authentication to occur unless a SSL/TLS session has been established. (It may be useful to commented out 'smtpd_tls_auth_only = yes' during testing so we can test that SSL/TLS is working but still fall back to plain text SASL authentication if SSL/TLS fails).

Don't forget to reload postfix configuration settings:

postfix reload

Now we can telnet into the server and check postfix is offering TLS:

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 mail.example.com ESMTP Postfix
EHLO example.com
250-mail.example.com
250-PIPELINING
250-SIZE 20480000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
quit
221 2.0.0 Bye
Connection closed by foreign host.

If everything is working as expected, we should see the server offering STARTTLS and because we have specified 'smtpd_tls_auth_only = yes', plain text SASL authentication (AUTH PLAIN LOGIN and AUTH=PLAIN LOGIN) is no longer available.

Finally we need to configure our email clients to use encryption when sending mail:

Thunderbird: Edit > Account Settings, and select Outgoing Server (SMTP) in the left hand pane. Select the smtp server and click Edit, and in the Security and Authentication section, under "Use secure connection" select TLS (or "TLS, if available")

Outlook Express: Tools > Accounts > Mail tab > select an account and click properties. Then on the Advanced tab, under Outgoing Mail (SMTP), tick "This server requires a secure connection (SSL)".

If we send a test message and tail our maillog, assuming everything is working, we should now see a TLS session established that encrypts the subsequent SASL authentication:

tail -f /var/log/maillog
Mar 21 01:51:42 jessie postfix/smtpd[1893]: connect from unknown[192.168.0.20]
Mar 21 01:51:42 jessie postfix/smtpd[1893]: setting up TLS connection from unknown[192.168.0.20]
Mar 21 01:51:44 jessie postfix/smtpd[1893]: TLS connection established from unknown[192.168.0.20]:
       TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)
Mar 21 01:51:44 jessie postfix/smtpd[1893]: D756E2006F: client=unknown[192.168.0.20], sasl_method=PLAIN, sasl_username=ned
Mar 21 01:51:44 jessie postfix/cleanup[1897]: D756E2006F: message-id=<47E314AE.1070702@example.com>
Mar 21 01:51:44 jessie postfix/qmgr[711]: D756E2006F: from=<ned@example.com>, size=511, nrcpt=2 (queue active)
Mar 21 01:51:45 jessie postfix/local[1898]: D756E2006F: to=<ned@example.com>, relay=local, delay=0.17,
       delays=0.13/0.02/0/0.02, dsn=2.0.0, status=sent (delivered to maildir)
Mar 21 01:51:45 jessie postfix/qmgr[711]: D756E2006F: removed
Mar 21 01:51:45 jessie postfix/smtpd[1893]: disconnect from unknown[192.168.0.20]

8. Configuring SSL/TLS in dovecot

SSL/TLS support is enabled in dovecot by default out of the box. The dovecot package even ships with it's own SSL certificates which we renamed and replaced with our own earlier in this guide. The settings of interest are all contained in /etc/dovecot.conf:

protocols = imap imaps pop3 pop3s
#disable_plaintext_auth = no
#ssl_disable = no
ssl_cert_file = /etc/pki/tls/certs/mail.example.com.cert
ssl_key_file = /etc/pki/tls/private/mail.example.com.key
ssl_cipher_list = ALL:!LOW:!SSLv2 

Restart the dovecot service after making any changes:

service dovecot restart

To use SSL/TLS encryption, you must enable the imaps (port 993) and/or pop3s (port 995) protocols. Commented settings represent the default values. When set to yes, disable_plaintext_auth will disable all plain text authentication methods (with the exception of connections from the same IP as these are considered secure). The ssl_cipher_list setting allows us to specify the list of allowed ciphers to be used. In addition to the default list, we block all low strength ciphers together with the less secure SSLv2 protocol.

There are a number of ways we can address local and remote security considerations. To enforce encryption to be used on all local and remote connections, we could simply disable insecure imap and pop3 protocols, and only offer imaps and pop3s in combination with setting 'disable_plaintext_auth = yes'. Alternatively, we may want to allow local users to use plain text imap and pop3 protocols whilst still enforcing that remote users use encryption. One way to achieve this might be to allow all connections to imaps and pop3s (ports 993 and 995, respectively) whilst restricting connections on imap and pop3 ports (143 and 110, respectively) to our local network via firewall rules. For example:

# IMAP(S)
# Accept only local network connections for IMAP
iptables -A INPUT -i eth0 -p tcp -s 192.168.0.0/24 --dport 143 -j ACCEPT
# Accept all connections for IMAPS
iptables -A INPUT -i eth0 -p tcp --dport 993 -j ACCEPT
#
# POP3(S)
# Accept only local network connections for POP3
iptables -A INPUT -i eth0 -p tcp -s 192.168.0.0/24 --dport 110 -j ACCEPT
# Accept all connections for POP3S
iptables -A INPUT -i eth0 -p tcp --dport 995 -j ACCEPT

Don't forget to set appropriate rules at the perimeter firewall and forward the appropriate ports.

Finally we must configure our email clients to use SSL encryption.

Thunderbird: Edit > Account Settings, and select the mail account "Server Settings" in the left hand pane. Under the "Security Settings" section, select SSL. Note the port number should now have changed to either 993 or 995 for IMAPS or POP3S, respectively.

Outlook Express: Tools > Accounts > Mail tab > select an account and click properties. Then on the Advanced tab, under Incoming Mail (POP3), tick "This server requires a secure connection (SSL)". Note the port number should now have changed to either 993 or 995 for IMAPS or POP3S, respectively.

If we tail our mail log and check for new email in our email client, we should be able to see that TLS encryption is now being used:

# tail -f /var/log/maillog
Mar 21 15:10:15 jessie dovecot: pop3-login: Login: user=<ned>, method=PLAIN, rip=::ffff:192.168.0.20, lip=::ffff:192.168.0.2, TLS
Mar 21 15:10:15 jessie dovecot: POP3(ned): Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0

If "TLS" is missing from the end of the first line, then something went wrong and the connection wasn't encrypted.

9. Links

http://wiki.dovecot.org/HowTo/PostfixAndDovecotSASL

http://wiki.dovecot.org/SSL/DovecotConfiguration

http://www.postfix.org/SASL_README.html#server_sasl

http://www.postfix.org/TLS_README.html#server_tls

http://postfix.state-of-mind.de/patrick.koetter/smtpauth/

...

HowTos/postfix sasl (last edited 2013-08-10 08:31:29 by ChristophGaluschka)