What more could you want?
Postfix with SASL and TLS
So, I decided to add a little security to the mail system with SASL auth and TLS. We’ll discuss TLS configuration first because I set Postfix up to only allow TLS logins, so testing whether or not SASL is working later requires that TLS be set up, in this particular case.
First, create a cert that we can use for Postfix, and drop the cert in /etc/pki/tls/certs and the key in /etc/pki/tls/private. Call them what you like, and Google for how to create a self-signed cert with OpenSSL. It’s easy.
TLS support is already built into the CentOS Postfix package. I looked at the documentation on Postfix’s site, and followed the directions, mostly. I added these configuration options to /etc/postfix/main.cf:
smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
smtpd_tls_key_file = /etc/pki/tls/private/postfix.pem
smtpd_tls_mandatory_ciphers = high
smtp_tls_mandatory_protocols = SSLv3, TLSv1
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
tls_random_source = dev:/dev/urandom
Many of these values’s meanings are obvious, such as the cert and key filenames, and the mandatory ciphers and protocols (which are great for PCI compliance, btw).
Really, the most important option here is smtpd_tls_auth_only, which disallows SMTP authentication if not connected with TLS. We’ll look at this more after we have SASL configured.
I also added the smtpd_tls_security_level option, even though may is the default value because I wanted to bring up an interesting point, also discussed in Postfix’s TLS docs. This value can be set to “encrypt”, which will enforce the use of TLS. This sounds great, but it also has an unwanted side effect: it causes Postfix to accept no mail without TLS encryption! According to RFC 2487, this should not be done on a public-facing SMTP server.
The smtpd_tls_received_header variable sets the Received: header to include regarding which protocols and ciphers were used, as well as the client and issuer Common Name (or domain name). It looks like this:
Received: from 1.2.3.4
(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
(No client certificate requested)
(Authenticated sender: me)
by mail.ozymo.com (Postfix) with ESMTP id 8060188280
Once the configuration is in /etc/postfix/main.cf, restart Postfix. On CentOS:
# service postfix restart
With this, simply configure your mail client to use TLS security for the connection and you are set up. Let’s move on to SASL auth.
I installed the Cyrus-SASL packages on my CentOS box with the following command:
# yum install cyrus-sasl
Once that was done, I needed to configure Postfix to correctly use the SASL libraries. I added these configuration options to /etc/postfix/main.cf:
## SASL Configuration
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_path = smtpd
smtpd_sasl_security_options = noanonymous
smtp_sasl_security_options = noplaintext
broken_sasl_auth_clients = yes
Once this configuration is in place, we have to make sure that the right settings are in the SASL smtpd.conf file. The locate command will be helpful in locating this file. On my box, 64-bit CentOS, it’s here:
$ locate smtpd.conf
/usr/lib64/sasl/smtpd.conf
/usr/lib64/sasl2/smtpd.conf
The one we want is in sasl2.
$ cat /usr/lib64/sasl2/smtpd.conf
pwcheck_method: saslauthd
These settings authenticate against the regular UNIX password database, ./etc/passwd and /etc/shadow. There are plenty of other ways to do this, but they are beyond the scope of this doc. Below, when we connect via telnet, you’ll see the default list of authentication mechanisms that SASL uses. To adjust this, add in the mech_list: section, as follows:
mech_list: PLAIN LOGIN
PLAIN and LOGIN are very common, and are the most often used.
After I had all my configurations in place, I restarted postfix, and logged into the server via telnet (snippet here):
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
So where is SASL? TLS is there, but no SASL. I’ve configured it in main.cf, and restarted Postfix. So what gives? Here’s the kicker:
smtp_sasl_security_options = noplaintext
So, if I login via regular port 25, I do not get the option to authenticate with SASL. When this is combined with:
smtpd_tls_auth_only = yes
then SASL authentication can only occur when connecting with TLS security, giving two layers. Let’s connect with openssl and check things out:
$ openssl s_client -connect oz:25 -starttls smtp
CONNECTED(00000003)
. . . {cert info}
SSL handshake has read 1770 bytes and written 351 bytes
—
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
. . . {TLS session info}
250 DSN
EHLO mail.ozymo.com
250-mail.ozymo.com
250-AUTH CRAM-MD5 DIGEST-MD5 PLAIN LOGIN
250-AUTH=CRAM-MD5 DIGEST-MD5 PLAIN LOGIN
250-8BITMIME
250 DSN
As you can see, the SASL lines are now present:
250-AUTH CRAM-MD5 DIGEST-MD5 PLAIN LOGIN
250-AUTH=CRAM-MD5 DIGEST-MD5 PLAIN LOGIN
According to Postfix’s SASL doc, referenced above, older Microsoft SMTP client software implements a non-standard version of the AUTH protocol syntax, and expects that the SMTP server replies to EHLO with “250 AUTH=mechanism-list” instead of “250 AUTH mechanism-list”. If you look at the config above, you can see that this is the reason both lines show up. Otherwise, we’d just see the first. Ah, to pine over a perfect Microsoft-free world! We’re down one app for now, though.
Via telnet, you can login by issuing AUTH LOGIN at the prompt followed by a hash of your username and password:
AUTH PLAIN AHRlc3QAdGVzdHBhc3M=
235 2.0.0 Authentication successful
The above is a hash of user “test” and password “testpass” so it won’t work; sorry. To generate a hash is as simple as a line of perl, but I wrapped it in a script I call smtpencode64. Here’s the source:
#!/bin/bash
if [ -z "$2" ]
then
echo “Usage: smtpencode64 <username> <password>”
else
perl -MMIME::Base64 -e “print encode_base64(\”\000$1\000$2\”)”
fi
Put it in your ~/bin and give it execute permissions, and you should be al set. Run it like so:
$ smtpencode64 test testpass
AHRlc3QAdGVzdHBhc3M=
Don’t forget to update your mail client, or you will be denied access to that ever-important new message.
/cs
| Print article | This entry was posted by chuck on August 26, 2009 at 9:51 pm, and is filed under Uncategorized. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |