A crash course in using SASL with Postfix

Red Hat's Postfix RPMs include support for both SASL and TLS.  SASL, the
Simple Authentication and Security Layer, allows Postfix to implement RFC
2554, which defines an extension to ESMTP, SMTP AUTH, which compliant
ESMTP clients can use to authenticate themselves to ESMTP servers.
Typically, this is used to allow roaming users to relay mail through a
server safely without configuring the SMTP server to be an open relay.
Inclusion of TLS support allows Postfix to implement RFC 2487, which
defines an extension to ESMTP, SMTP STARTTLS, which compliant ESMTP
clients and servers can use to encrypt the SMTP session.  This is a
security enhancement -- normally SMTP is transmitted as cleartext over the
wire, making it vulnerable to both passive sniffing and active alteration
via monkey-in-the-middle attacks.  In addition, STARTTLS can also be
used by either or both server and client to verify the identity of the
other end, making it useful for the same sorts of purposes as SMTP AUTH.
The two can even be combined.  Typically, this is done by first starting
TLS, to encrypt the SMTP session, and then issuing the SMTP AUTH command,
to authenticate the client; this combination ensures that the username
and password transferred as part of the SMTP AUTH are protected by the
TLS encrypted session.

SMTP AUTH is implemented using SASL, an abstraction layer which can
authenticate against a variety of sources.  On Red Hat, SASL can use
the /etc/shadow file, or it can use PAM libraries, or it can use its own
password database (/etc/sasldb), or it can do various more exotic things.
Since most of Postfix runs as non-root and access to authentication
via PAM routines or to /etc/shadow requires root, we'll only discuss
authentication using sasldb; if you're interested in anything else,
take a look at the <sarcasm>copious</sarcasm> SASL documentation and
the /usr/lib/sasl/smtpd.conf configuration file.

To authenticate against sasldb, you'll first have to create accounts.
These accounts are entirely separate from system accounts, and are used
only by connecting SMTP clients to authenticate themselves.  Use the
saslpassword command:

saslpasswd -u realm -c user

to create an account named user which can log into realm.  For the
realm, make absolutely certain that you use the same value as is set for
myhostname in /etc/postfix/main.cf.  If you don't, it likely won't work.

Also, be aware that saslpasswd is somewhat buggy.  The first time you
run it, it may generate an error message while initializing the sasldb.
If it does, just add that user a second time.

After you've added all the user accounts you need (use sasldblistusers
to verify), you'll have to copy the SASL database into the Postfix
chroot jail:

# cp /etc/sasldb /var/spool/postfix/etc/sasldb

and set permissions on it so that the Postfix daemons can read it:

# chgrp postfix /var/spool/postfix/etc/sasldb
# chmod g+r /var/spool/postfix/etc/sasldb

Now, you'll need to modify /etc/postfix/main.cf to tell it to
support SASL.  The complete options you might want to use are in the
sample-auth.cf file in the Postfix documentation directory.  An option
you will definitely need is:

# enable SASL support
smtpd_sasl_auth_enable = yes

If you want to allow your already configured users to still use your SMTP
server, and to allow users authenticated via SMTP AUTH to use your server
as well, then modify your existing smtpd_recipient_restrictions line to;

# also allow authenticated (RFC 2554) users
smtpd_recipient_restrictions = permit_sasl_authenticated ...

If you want to restrict use of your server to just authenticated clients
(note:  this is a Bad Idea for public mail servers), then instead use:

# restrict server access to authenticated (RFC 2554) clients
smtpd_delay_reject = yes
smtpd_client_restrictions = permit_sasl_authenticated ...

SASL supports several password types which have differing security
properties.  Different SMTP clients may support some or all of these
password types.  When the client issues an EHLO command, the server
tells it which types it supports:

$ telnet station6 25
Trying 10.100.0.6...
Connected to station6.example.com.
Escape character is '^]'.
220 station6.example.com ESMTP Postfix
ehlo station7
250-station6.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5
250-XVERP
250 8BITMIME

Here, the server supports PLAIN, LOGIN, DIGEST-MD5, and CRAM-MD5 password
methods.

The client then chooses the first of these listed methods which it also
supports, and issues an SMTP AUTH request.

For security, PLAIN and LOGIN methods are typically disabled.  These two
methods use trivially decryptable encryption, making the username and
password issued by the client vulnerable to interception via a sniffer
in between the server and client.  Unfortunately, they can't always
be disabled.  Some popular SMTP clients, including MS Outlook 5.x,
only support PLAIN authentication, for example.

To limit the login methods offered by the server:

# disable unsafe password methods
smtpd_sasl_security_options = noplaintext noanonymous

Available options are:

noplaintext, which disables LOGIN and PLAIN
noanonymous, which disables disables ANON
nodictionary, which disables methods vulnerable to dictionary attacks
noactive, which disables methods vulnerable to active attacks

The last two are rarely used, since almost all supported methods are
vulnerable to those attacks ;-).

Also be aware that some broken clients mis-implement the SMTP AUTH
protocol, and send commands using incorrect syntax (AUTH=foo instead of
the correct AUTH foo).  MS Outlook 4.x clients have this bug, amongst
a legion of others....  If you need to support these clients, use:

# support braindead MS products
broken_sasl_auth_clients = yes

You might also need to set the SASL authentication realm to whatever
realm you used when you created your sasldb; by default, this is set to
$myhostname, but you instead might need something like:

# set SASL realm to domain instead
smtpd_sasl_local_domain = $mydomain

To help prevent spoofing, you can also create a map file of SASL login
names which are allowed to use specific envelope sender (MAIL FROM)
addresses.  If you choose to do this, you also have to tell Postfix to
reject addresses which don't match login names:

# prevent spoofing by authenticated users
reject_sender_login_mismatch
smtpd_sender_login_maps=type:/path/to/file

Configuration of SASL clients is much simpler.  Postfix itself can be
made a SASL client; this is typically useful when roaming users run Linux
on their laptop and need to relay mail back through the organization's
main server.

To enable Postfix to act as an SMTP AUTH client, simply add to
/etc/postfix/main.cf:

# support authentication (RFC 2557) when relaying through a server
smtp_sasl_auth_enable = yes

and tell Postfix where to find the usernames and passwords it should
use to authenticate:

# location of passwords for authentication client
smtp_sasl_password_maps = type:/path/to/file

The file itself should have the format:

destination     username:password

where destination is the name of the server, and username:password are
the username and password which should be presented to that server to
authenticate when connecting to it as a client.

Optionally, the authentication methods to be used can be specified for
the Postfix client, just as they can be for the Postfix server:

# disable plaintext and anonymous
smtp_sasl_security_options = noplaintext noanonymous

Many popular end-user MUAs can also be configured as SMTP AUTH clients.
Clients capable of this supplied with Red Hat include pine, Netscape,
and Mozilla.

---

Please send any comments / corrections to Chris Ricker
<kaboom@gatech.edu>.  This material can be freely modified and
redistributed.
