This is another page on setting postfix to use SASL and TLS.  The references I used are the following:

plus random mailing lists archives for troubleshooting problems I encountered.

Motivation

The motivation for this is to be able to use a public internet box hosted at OVH as a secure mail relay for my laptop based postfix installation. By default, mail relaying is forbidden or more precisely limited to the my_destination parameter of the postfix server. I know the basics of SMTP and mail relay but are by no mean a guru, so theses notes shall also serve me in case I would have to redo the installation.  

The setting is:

Server configuration

Install SASL

apt-get install libsasl2
aptitude install sasl2-bin 
apt-get install libsasl2-modules

The last line is very important: It took me a whole hour to figure that this was missing and prevented postfix from properly recognizing the presence of the sasl daemon !

Edit /etc/default/saslauthd, this is the file that configures the SASL authentication daemon on startup. Note that the working dir, which is to contain the socket for communication between client (postfix) and server (saslauthd), is set to a directory relative to the chroot jail of the postfix daemon:

START=yes
PWDIR="/var/spool/postfix/var/run/saslauthd"
PARAMS="-m ${PWDIR}"
PIDFILE="${PWDIR}/saslauthd.pid"
MECHANISMS="pam"
OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd"

dpkg-statoverride --force --update --add root sasl 755 /var/spool/postfix/var/run/saslauthd
/etc/init.d/saslauthd start
testsaslauthd -u user -p secret -f /var/spool/postfix/var/run/saslauthd/mux

Don't know what the first line is for. The second one obviously starts the daemon (check with ps ax), and the third one is used to test the deamon using some referenced user on the host. Don't forget the -f parameter as the socket is  not in its standard place.

Edit /etc/postfix/sasl/smtpd.conf

saslauthd_version: 2
pwcheck_method: saslauthd
mech_list: plain login

It is theoretically possible to add more methods in the mech_list parameter, eg. cram-md5 or digest-md5, but this prevents the client to authenticate properly (or so I think).  

Edit /etc/postfix/main.cf

# sasl support for relaying mails
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
smtpd_recipient_restrictions =
   permit_sasl_authenticated,
   permit_mynetworks,
   check_relay_domains

Note that there is a smtpdsaslpath that is somewhat confusing: this is not the path to the config file, but an arbitrary token that is passed to the server (kind of realm ?).

Then restart postfix:

/etc/init.d/postfix restart

If everything goes well, one can test with the following connection:

telnet www.oqube.com 25
Trying 213.251.185.91...
Connected to www.oqube.com.
Escape character is '^]'.
220 www.oqube.com ESMTP Postfix (Debian/GNU)
EHLO localhost
250-www.oqube.com
...
250-AUTH PLAIN LOGIN
...

The line 250-AUTH should list the available mechanisms defined in the smtpd.conf file.

Install the sasldb2 file correctly:

cp /etc/sasldb2 /var/spool/postfix/etc/
chown root:sasl /var/spool/postfix/etc/sasldb2 
chmod 660 /var/spool/postfix/etc/sasldb2
sed -i -e 's/\(sasl:.*\)/\1postfix/g' /etc/group

For some reason, this file was not installed in the chroot jail by package configuration, and postfix need to access it (don't know why however because I did not use sasldb mechanism for authenticating).  

Troubleshooting

I spent lot of a time working around a cryptic error appearing in postfix logs:

Feb 21 13:41:45 ns35748 postfix/smtpd[9736]: warning: xsasl_cyrus_server_get_mechanism_list: no applicable SASL mechanisms
Feb 21 13:41:45 ns35748 postfix/smtpd[9736]: fatal: no SASL authentication mechanisms
Feb 21 13:41:46 ns35748 postfix/master[26660]: warning: process /usr/lib/postfix/smtpd pid 9736 exit status 1
Feb 21 13:41:46 ns35748 postfix/master[26660]: warning: /usr/lib/postfix/smtpd: bad command startup -- throttling
This error was due to the missing installation of libsasl2-modules

Then I got:

Feb 21 14:52:04 ns35748 postfix/smtpd[15470]: warning: SASL authentication problem: unable to open Berkeley db /etc/sasldb2: No such file or directory
Feb 21 14:52:04 ns35748 postfix/smtpd[15470]: warning: SASL authentication problem: unable to open Berkeley db /etc/sasldb2: No such file or directory
Feb 21 14:52:04 ns35748 postfix/smtpd[15470]: warning: SASL authentication failure: no secret in database
Feb 21 14:52:04 ns35748 postfix/smtpd[15470]: warning: LMontsouris-152-62-50-113.w80-13.abo.wanadoo.fr[80.13.68.113]: SASL DIGEST-MD5 authentication failed: 
authentication failure

Which I resolved by removing digest-md5 from the list of authentication mechanisms and setting up sasldb2 correctly.

Install TLS

We use plaintext authentication because we plan to use TLS, which creates a encrypted tunnel between the two hosts that prevent (hopefully) capture of passwords. TLS can also be used for client certificate authentication which is somewhat better as far as security is concerned. I plan to switch to that at some time in the future.

Edit /etc/postfix/main.cf

# activation of TLS
smtpd_tls_auth_only = yes
smtp_use_tls = yes
smtpd_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtpd_tls_key_file = /path/to/server.key
smtpd_tls_cert_file = /path/to/server.crt
smtpd_tls_CAfile = /path/to/CACertificatesList.crt
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes 
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

The important things to note are:

IN the logs (/var/log/mail.log), one can see TLS in action:

Key generation

openssl genrsa -out /etc/ssl/private/oqube.key 1024
openssl req -x509 -new -key /etc/ssl/private/oqube.key -out /etc/ssl/certs/oqube.crt -days 3650 -subj '/CN=mail.oqube.com'

An example of failed certifcate validation (probably the remote server is using a self-signed certificate):

Feb 22 09:05:21 ns35748 postfix/smtp[28926]: certificate verification failed for exchange.norsys.fr: num=20:unable to get local issuer certificate
F

A succesful TLS connection from a client:

Feb 22 06:41:11 ns35748 postfix/smtpd[22745]: connect from artima.com[63.246.23.132]
Feb 22 06:41:11 ns35748 postfix/smtpd[22745]: setting up TLS connection from artima.com[63.246.23.132]
Feb 22 06:41:11 ns35748 postfix/smtpd[22745]: TLS connection established from artima.com[63.246.23.132]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)

If everything works properly, one can see:

Trying 213.251.185.91...
Connected to www.oqube.com.
Escape character is '^]'.
220 www.oqube.com ESMTP Postfix (Debian/GNU)
EHLO localhost
250-www.oqube.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN


The option is offered as 250-STARTTLS.  

Client configuration

I now want to configure the client postfix that will relay mail to my server. This is easier. First SASL, edit /etc/postfix/main.cf

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl/sasl_passwd
smtp_sasl_type = cyrus
smtp_sasl_security_options = noanonymous

And install sasl:

apt-get install libsasl2
aptitude install sasl2-bin 
apt-get install libsasl2-modules

Then edit /etc/postfix/sasl/sasl_passwd file:

[www.oqube.com]    user:secret
Of course, the user should be authenticated on the server ! The reference to the server allow using different credentials for different servers.  

Don't forget then to activate mail relaying:

relayhost = [www.oqube.com]
The brackets around the server name instructs postfix to use this name directly, not to try resolving MX for the host's domain.

Then TLS, once again editing /etc/postfix/main.cf

smtp_use_tls=yes
smtp_tls_loglevel=0