Postfix + TLS + SASL on FreeBSD
by Tim Yocum, Version 1.3, 22 February 2005

Introduction

Getting postfix to work with TLS and SASL is nice, but it seems all the tutorials that currently exist all contain totally different methods to accomplish the same goal.

To that extent, here's what I did to get it working for me on FreeBSD. Each summarized item is followed by a play-by-play command entry history; if you know what you're doing please feel free to skip the steps as I've done them; we all know that there's more than one way to accomplish the same thing. Also note that if you want to skip doing this by hand, you can use FreeBSD's ports; by going into the Ports tree, finding postfix, and doing a make, it'll offer several menu choices from which you can select TLS/SASL options. This might be the best way for beginners to get TLS/SASL functionality working really fast.

Step by Step

1. Install sasl2 and saslauthd, preferably from ports. Make sure your ports tree is current before proceeding:
   cd /usr/ports/security/cyrus-sasl2
   make all install clean
   cd ../cyrus-sasl2-saslauthd
   make all install clean
2. Configure sasl2:
   cd /usr/local/lib/sasl2
   echo "pwcheck_method: saslauthd" > smtpd.conf
3. Disable unused sasl authentication methods -- if you skip this step, you will have problems with Microsoft Outlook/Outlook Express clients trying to perform NTLM auth on your server. You can also move any other unused auth methods to the "deactivated" directory if you know of others you do not plan to use or support.
   cd /usr/local/lib/sasl2
   mkdir deactivated
   mv *ntlm* deactivated
4. Download the latest Postfix source and Postfix TLS patch and unpack them:
 
   cd /tmp
   mkdir postfix-work
   cd postfix-work
   wget http://postfix.energybeam.com/source/official/postfix-2.0.15.tar.gz
   wget ftp://ftp.aet.tu-cottbus.de/pub/postfix_tls/pfixtls-0.8.16-2.0.15-0.9.7b.tar.gz
   gunzip *
   tar xf postfix-2.0.15.tar && tar xf pfixtls-0.8.16-2.0.15-0.9.7b.tar
5. Apply the TLS patch to the Postfix source per README file contained in pfixtls* package:
   patch -p0 < pfixtls-0.8.16-2.0.15-0.9.7b/pfixtls.diff
6. Build Postfix with SSL and SASL support. Your syntax may vary if your libs aren't in the right place or if you're using different versions than I am:
   cd postfix-2.0.15
   make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl \
   -DHAS_SSL -I/usr/local/include/openssl" AUXLIBS="-L/usr/local/lib \
   -R/usr/local/lib -lsasl2 -lssl -lcrypto"
If you are upgrading from an existing, known-good version of Postfix:
   make upgrade
If this is a new install:
   make install
7. Verify that the correct libraries have been linked in:
   ldd /usr/libexec/postfix/smtpd
You should see the following:
smtpd:
        libsasl2.so.2 => /usr/local/lib/libsasl2.so.2 (0x28096000)
        libssl.so.3 => /usr/local/lib/libssl.so.3 (0x280aa000)
        libcrypto.so.3 => /usr/local/lib/libcrypto.so.3 (0x280db000)
        libc.so.5 => /usr/lib/libc.so.5 (0x281df000)
If you see libsasl2, libssl, and libcrypto, congratulations -- the server is ready to support SASL and TLS.

8. Generate an SSL certificate:

   mkdir /etc/postfix/ssl
   cd /etc/postfix/ssl
   openssl req -new -x509 -nodes -out smtpd.pem -keyout smtpd.pem -days 3650
9. Enter configuration options for Postfix:
   /etc/postfix/main.cf:

   # sasl config
   broken_sasl_auth_clients = yes
   smtpd_sasl_auth_enable = yes
   smtpd_sasl_local_domain = 

   smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks
   smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks
Your settings for the two "restrictions" lines may vary, but it is important to note that the sasl inclusion must be the first entry in the list.
   # tls config
   smtp_use_tls = yes
   smtpd_use_tls = yes 
   smtp_tls_note_starttls_offer = yes 
   smtpd_tls_key_file = /etc/postfix/ssl/smtpd.pem
   smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.pem
   smtpd_tls_CAfile = /etc/postfix/ssl/smtpd.pem
   smtpd_tls_loglevel = 1
   smtpd_tls_received_header = yes
   smtpd_tls_session_cache_timeout = 3600s
   tls_random_source = dev:/dev/urandom
10. Pray.

11. Start the SASL auth daemon:

   /usr/local/etc/rc.d/saslauthd.sh start
12. Start your mail server:
    postfix start
13. Test to ensure that the server is actually able to accept TLS connections and SASL auth:
    telnet localhost 25
    EHLO example.com
You should see several lines of text, including these three:
   250-STARTTLS
   250-AUTH LOGIN PLAIN OTP DIGEST-MD5 CRAM-MD5
   250-AUTH=LOGIN PLAIN OTP DIGEST-MD5 CRAM-MD5

If you have all three, your server is ready to authenticate via SASL and TLS, and can also negotiate TLS connections with other TLS-aware mail servers.

14. Fire up a mail client, configure it to use authentication on outbound SMTP and try sending a message. You should see a log entry similar to the one below each time a user authenticates to send a message. If the message shows up, that's good - it's likely they're authenticating properly and their message will be relayed. Make sure that Postfix actually relays the message, though, because if you've not configured main.cf correctly, it'll still bounce the message.

Sep 12 11:40:29 hostname postfix/smtpd[79381]: C5FA32855D: client=unknown[x.x.x.x], sasl_method=LOGIN, sasl_username=joeuser

15. Test TLS/SSL. This part is easy. Go back to your mail client and find the checkbox where you specify that the connection for outgoing mail should be authenticated *and* use SSL. Enable it, and try sending a message. You should see some TLS negotiation banners similar to the following in the same mail log:

Sep 12 12:56:04 hostname postfix/smtpd[79849]: setting up TLS connection from machine.example.com[x.x.x.x]

Sep 12 12:56:04 hostname postfix/smtpd[79849]: TLS connection established from machine.example.com[x.x.x.x]: TLSv1 with cipher RC4-MD5 (128/128 bits)

Now the fun part is watching to see what other mail servers can speak TLS. Now that your server is TLS-aware, it will attempt to negotiate a TLS session with any mail server that supports it. Surprisingly, I noticed at least ten servers supporting it as they relayed mail to users on my hosts.

If you're upset with the fact that the certificate you generated is self-signed, you can get your own signed cert at SSL.com among others. Clients will likely display a message indicating the certificate received is not valid; users can safely dismiss this message and should not see it again. Once you use a signed cert, users will not see an error when using your TLS-aware server.

Notes

  • You may need to change permissions on /etc/opiekeys if you receive errors about opie, OTP, or an unreadable keyfile.
  • You may need to add the postfix user to the 'mail' group so that it can read /var/state/saslauthd/* if you receive errors complaining about SASL not being able to connect to saslauthd.
  • Users running Outlook and Norton Anti-Virus report that you must disable email scanning in order for outbound TLS connections to work correctly. I have not been able to test this myself, but after disabling scanning, outgoing mail seems to work just fine.
  • Be sure to check your client configuration when sending mail via TLS/SASL -- most mail clients have different sets of options and use different levels of encryption.
  • Check the logs!

    Thanks

    Many thanks to Adam Rothschild and Aaron Monfils for testing the above steps for completeness.

    Feedback

    Were you able to avoid seven hours of hair-pulling frustration by using this document and some clue as a roadmap to TLS/SASL nirvana? Are some of the steps above not clear or not working on your platform? Please let me know.

    Revision History

    20 Nov 03, 1.0: First publication.
    23 Nov 03, 1.1: Corrected several inconsistancies noted by users of FreeBSD 5.x.
    05 Dec 03: 1.2: Added information regarding ports, and how this can be accomplished using that method instead.

    Google