We want to allow users to relay mail using SMTP, but we don’t want anyone else to be able to. SASL is used to add authentication to the SMTP protocol, which in itself does not include any authentication. The package postfix-tls will enable SASL support in postfix.
NOTE: you must install the package libsasl-modules-plain or smptd will die a horrible death when trying to use sasl. The sasl package doesn’t come with any auth modules by itself. We need at least some, and we choose to use plaintext, since we are requiring the session is ssl anyway.
Postfix and SASL¶
A note from /usr/share/doc/postfix/SASL_README.gz:
“To run software chrooted with SASL support is an interesting exercise. It probably is not worth the trouble.”
Ok, so we disable chroot for smtpd in /etc/postfix/master.cf
. To do so, change
the 5th entry for smptd to ‘n’ from ‘-’:
It is possible to run postfix chrooted, but it causes a whole lot of confusion to all involved and when you look at the postfix-users list people are told constantly by the postfix author not to run it chroot (he disagrees with the debian package maintainer to ship it chrooted)
Allow postfix access to the saslauthd mux (socket) located in /var/run/saslauthd postfix by putting it in the sasl group:
gpasswd -a postfix sasl
Configure postfix to rely mail via sasl, require authentication and tsl:
/etc/postfix/main.cf
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
smtpd_tls_auth_only = yes
If using saslauthd, make sure its started:
/etc/init.d/saslauthd start
SASL authentication via PAM¶
A note from /usr/share/doc/postfix/SASL_README.gz:
“To run software chrooted with SASL support is an interesting exercise. It probably is not worth the trouble.”
Ok, so we disable chroot for smtpd in /etc/postfix/master.cf. To do so, change the entry for smtp to ‘n’ from ‘-’, so it looks like this:
smtp inet n - n - - smtpd
Configure sasl to use the pam in /etc/postfix/sasl/smtpd.conf:
pwcheck_method: pam
SASL authentication via saslauthd¶
Configure sasl to use the saslauthd:
/etc/postfix/sasl/smtpd.conf
pwcheck_method: saslauthd
mech_list: plain login
We need the following packages in order to get saslauthd to work:
apt-get install sasl2-bin libsasl2-modules
/etc/default/saslauthd
START=yes
MECHANISMS="ldap"
PARAMS="-O /etc/sasl/saslauthd.conf"
create /etc/sasl/saslauthd.conf and edit it:
> mkdir /etc/sasl
> cat >> /etc/sasl/saslauthd.conf
ldap_servers: ldap://localhost/
ldap_search_base: ou=People,dc=riseup,dc=net
ldap_auth_method: bind
ldap_filter: uid=%u
- For virtual domains:
%r
in filter is for the realm (%u
is the user). - I couldn’t get the other (faster) ldap_auth_methods to work.
Note: since saslauthd just does a ldap bind as the user trying to
authenticate, i think that it could be run as any user. Ergo, it
should not be run as root.
See /usr/local/src/cyrus-sasl-2.1.12/saslauthd/LDAP_SASLAUTHD for more information.
Postfix and TLS¶
You will need the following TLS options configured:
# common TLS parameters
tls_random_source = dev:/dev/urandom
tls_daemon_random_source = dev:/dev/urandom
# Client side TLS
smtp_use_tls = yes
smtp_tls_key_file = /etc/certs/your.domain.here/key.pem
smtp_tls_cert_file = /etc/certs/your.domain.here/cert.pem
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_CAfile = /etc/certs/roots/cacert-root.pem
smtp_tls_session_cache_database = sdbm:/var/postfix/smtp_scache
smtp_tls_per_site = hash:$tls_dir/tls_per_site
smtp_tls_loglevel = 1
# Server side TLS
smtpd_use_tls = yes
smtpd_tls_key_file = /etc/certs/your.domain.here/key.pem
smtpd_tls_cert_file = /etc/certs/your.domain.here/cert.pem
smtpd_tls_CAfile = /etc/certs/roots/cacert-root.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_database = sdbm:/var/postfix/smtpd_scache
smtpd_tls_ask_ccert = yes
You will need to have a valid certificate created and installed in the directory referenced above. If
you dont have one, you need to create one now.
In order to actually do SMTPAuth over TLS, you need to enable the smtps daemon, which runs on port 465. To do this, you may need to uncomment these lines from the postfix/master.cf:
smtps inet n - - - - smtpd
-o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
Also, be sure any firewall you have allows this port.
Anonymized SMTP¶
If you do not anonymize your authenticated SMTP, then every email that a user sends out will include their home IP address!
Versions of postfix prior to 2.3 made it difficult to anonymize SMTP. Newer versions of postfix have the option that makes this much easier. You need to enable smtpd_sasl_authenticated_header = yes
, which adds SASL information to your header. Once this information is there, header_checks
can be put into place that rewrite the headers to anonymize their content.
The regular expression needs to be on one line, with a newline between the expression and the REPLACE line. If anyone knows how to get newlines in there, I’d like to know. This works for postfix >= 2.5):
/^Received: from (.* \([-._[:alnum:]]+ \[[.[:digit:]]{7,15}\]\)).*\(Authenticated sender: ([^)]+)\).*by ($HOSTNAME\.$DOMAIN\.$TLD) \(([^)]+)\) with (E?SMTPS?A?) id ([A-F[:digit:]]+).*/
REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: $2) with $5 id $6
This will replace the SASL authenticated hostname with ‘localhost’ and the resulting header will look like this:
Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: micah@petrel.riseup.net) with ESMTP id 17E6C86A for <micah@riseup.net>; Sun, 12 Nov 2006 16:54:56 -0800 (PST)
NOTE: Be careful if you decide to use this regexp, you will need to replace $HOSNAME, $DOMAIN and $TLD to match your system. Also, be careful if you change this regexp, some clients present different headers, I’ve seen some people have different information sent as ‘helo’ and not all say where the message is for.
Testing authenticated SMTP¶
For testing you are going to need the special telnet that supports SSL/TLS connections:
apt-get install telnet-ssl
This package will allow you to telnet over a ssl connection. For example telnet -z ssl mail.riseup.net 25
will establish a ssl connection to port 25 of host mail.riseup.net.
Step 1: ensure no unecrypted auth
Since we only want to allow authentication when using TLS, first lets check to make sure we are not advertising AUTH to mail clients when they are not using TSL:
shell> telnet auk.riseup.net
out> Trying 204.13.164.27...
out> Connected to auk.riseup.net.
out> Escape character is '^]'.
out> 220 auk.riseup.net ESMTP
you> EHLO me
out> 250-riseup.net
out> 250-PIPELINING
out> 250-SIZE 10240000
out> 250-ETRN
out> 250-STARTTLS
out> 250-XVERP
out> 250 8BITMIME
you> quit
out> 221 Bye
(out> is what is printed out by postfix, you> is what you type).
If you see 250-AUTH in the response to the EHLO, then you have a problem!
Step 2: ensure encrypted auth is supported
Connect to postfix using ssl and make sure that it lists the AUTH mechs (the second line is for the broken outlook clients):
telnet -z ssl willow.riseup.net 25
Trying 216.162.217.193...
Connected to willow.riseup.net.
Escape character is '^]'.
220 riseup.net ESMTP Postfix
EHLO me
250-riseup.net
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-STARTTLS
250-AUTH NTLM LOGIN PLAIN DIGEST-MD5 CRAM-MD5
250-AUTH=NTLM LOGIN PLAIN DIGEST-MD5 CRAM-MD5
250 8BITMIME
Step 3: generate a base64 encoded username and password pair
In order to auth with postfix, we need to base64 encode a string that consists of:
username + \0 + username + \0 + password
Usename is repeated and there is a \0 twice in there!
perl -MMIME::Base64 -e 'print encode_base64("micah\0micah\0passwd");'
l7ajTWgJbs4jfWgBGW4hZFBXbg==
Step 4: attempt to authenticate with base64 string
AUTH PLAIN l7ajTWgJbs4jfWgBGW4hZFBXbg==
235 Authentication successful