Enabling SASL in Postfix

Vincent Danen

March 25, 2008

NOTE: This is a revision of the previous "Enabling SASL in Postfix" article on MandrakeSecure.

SASL, short for Simple Authentication and Security Layer is a method for adding authentication support to connection-based protocols. In order for SASL to be used, a protocol must include a command for identifying and authenticating a user to a server and for optionally negotiating protection of subsequent protocol interactions. If it's use is negotiated, a security layer is inserted between the protocol and the connection.

That description is taken basically verbatim from the Cyrus SASL homepage. Cyrus SASL is the SASL authentication library that is provided in Mandrakelinux from version 8.0 on. Unfortunately, the description may not mean a lot to people, so let's try to simplify it a little bit. In easier terms, SASL is a means for authenticating yourself to the server without providing your password in the clear. This can also be used to provide extended capabilities based on your authorization.

In this paper, we will look at enabling SASL support in the postfix MTA. In current versions of Mandrakelinux, sendmail comes with SASL support out of the box but postfix does not. To enable SASL support in postfix, you need to configure a few things, and we will go through these step by step.

The benefit to using SASL with your SMTP server is quite simple. To understand the benefit, you need to understand some of the fundamental flaws with the SMTP protocol. In the early days of SMTP when the internet was much smaller, there was a certain amount of trust between users. Since then, due to the explosive growth of the internet and the subsequent abuse from some individuals, the lack of authentication between client and server should be considered a flaw. It basically boils down to the fact that now you can't trust everyone anymore. Servers cannot trust clients and clients cannot trust servers due to how easy it is to spoof IP protocols. Because of this, neither client nor server cannot know if the other end is legitimate.

There are other forms of authentication, but none are as efficient as using SASL. Some other methods of authentication that were conceived were POP-before-SMTP, which would require a user to POP into the server and then immediately send their mail out, thus authenticating them through the POP server. Others used DNS or IP information, both of which could be spoofed. To this end, SASL was used with the SMTP AUTH extension, as described in RFC 2554. Using SASL, protocols such as CRAM-MD5 can be used to authenticate, as well as other mechanisms such as Kerberos, the system password file, or others.

Pre-requisites

The first thing you need to do is have a version of postfix installed that has SASL support enabled. Recently, MandrakeSoft issued updates to postfix that provided fixed SASL support for 8.1 and introduced SASL support in 8.0 (for more information, view the advisory, MDKA-2002:003). These versions of postfix (postfix-20010228-6.2mdk for 8.0 and postfix-200102280-15.2mdk for 8.1) provide proper SASL support and can be upgraded via MandrakeUpdate. You will also need the Cyrus SASL library files, which you can also obtain from updates due to a security fix (MDKSA-2002:018). These updates are available for 8.0 and 8.1 also.

You will need to have the basic components installed: cyrus-sasl and libsasl7. To enable the authentication methods, you will need the appropriate plugin. For example, to enable CRAM-MD5 authentication, you will need to install the libsasl7-plug-crammd5 package; for PLAIN authentication, you will need the libsasl7-plug-plain package. You can install the specific plugin you wish, or simply download and install all of the plugins (anonymous, crammd5, digestmd5, login, or plain).

Once you have upgraded and/or installed the appropriate packages, you're ready to configure postfix and Cyrus SASL. 8.2 users can install postfix and the SASL packages from their install CDs.

Configuring postfix

To configure postfix to use SASL, you must edit the /etc/postfix/main.cf file. There are a few different options that you must enable. At the end of the main.cf file, include the following:

# Other configurable parameters
# server
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = permit_mynetworks,
  permit_sasl_authenticated, check_relay_domains
smtpd_sasl_security_options = noanonymous
# client
smtp_sasl_auth_enable = yes

Please note that that the smtpd_recipient_restrictions command should be entered on one single line, not two lines as illustrated here.

The smtpd_sasl_auth_enable keyword tells postfix to use SASL authentication, and advertises AUTH in the ESMTP capabilities.

The smtpd_sasl_local_domain keyword should contain the authentication realm that the postfix smtpd process attempts to authenticate sessions against. This currently has no effect if you are not using the sasldb. This should be set to $myhostname as there is no provision for clients to specify a realm and postfix has no support for multiple authentication domains.

The smtpd_sasl_security_options keyword tells postfix which methods to use. You can set this to "noplaintext" to disable the use of PLAIN and LOGIN methods (which use plaintext passwords). "noanonymous" tells postfix to disable methods that use anonymous authentication (ANON). Setting this to "nodictionary" tells postfix not to advertise methods that are vulnerable to passive (or dictionary) attacks. Finally, if set to "noactive", postfix will not use methods that are vulnerable to active (or non-dictionary) attacks.

You can also use the keyword broken_sasl_auth_clients. If this is set to "yes", then postfix will support older clients that expect the server to return AUTH= instead of AUTH, which will result in postfix providing two AUTH banners. This is typically only useful if you have clients using Outlook Express 4.x.

The smtpd_recipient_restrictions keyword specifies restrictions on recipient addresses that clients can send in RCPT TO commands. There are a lot of different restrictions that can be configured here, if you're interested in a full list of the available restrictions, look in the /usr/share/doc/postfix-20010228/sample/sample-smtpd.cf file (it's described starting at line 245). To describe the options shown in the above example, the "permit_mynetworks" will permit if the client address matches $mynetworks (which is a default in postfix); the "permit_sasl_authenticated" permits if the client successfully authenticates with SASL authentication (which is what we want to enable here), and "check_relay_domains" permits if a series of tests are successfully passed (also a default in postfix, but describing the tests is beyond the scope of this paper).

To obtain more details on the different SASL-related options, you can view the /usr/share/doc/postfix-20010228/sample/sample-auth.cf file.

On a final note, postfix logs the username provided by the remote host, the requested authentication method, and the sender address during authenticated sessions.

The above options handle incoming AUTH requests in the SMTP server (smtpd). The following options handle outgoing AUTH requests in the SMTP client (smtp). You do not need to use authentication on outgoing sessions, and it is perfectly reasonable to use authentication only for incoming sessions. The following are the options you can use to handle outgoing authentication:

The smtp_sasl_auth_enable keyword tells postfix to attempt to authenticate on all outbound connections.

The smtp_sasl_password_maps keyword tells postfix what maps store outgoing credential information. This is not the same as your sasldb; the sasldb cannot be used for outgoing credentials. An example might be "hash:/etc/postfix/sasl_passwd".

The smtp_sasl_security_options keyword uses the same values as the smtpd_sasl_security_options keyword noted above.

If you decide to use outbound authentication, you will need to create the map that postfix will use (identified by smtp_sasl_password_maps). The file must be plaintext using the following syntax:

destination   username:password

or

destination   username

if a password is not required. The destination must be the fully qualified domain name (FQDN) of the remote host or a domain name that is serviced by multiple hosts. Postfix will attempt first to find the server hostname in this map, and if it doesn't it will attempt to find the destination hostname. If the destination is a group of SMTP servers that all share the same authentication database, you should set the destination to the domain name instead of adding one line per server.

The only oddity of SMTP client AUTH is that the host information matched in the client password map must also exist in DNS. This is even if you are using NIS or the /etc/hosts file.

Once you have completed your postfix configuration you should execute the following commands to make sure you have made no syntax errors:

# postfix check
# postfix reload

Configuring Cyrus SASL

The next step it to configure Cyrus SASL. This only deals with incoming authentication sessions. The first thing to do is to tell the SASL library where to pull the authentication from. This is done by editing the /usr/lib/sasl/smtpd.conf file. You have a few choices that you can select:

pam: this tells SASL to integrate with your system's PAM libraries and to authenticate against the database specified by pam. This can be used with plaintext protocols such as PLAIN and LOGIN, and should allow you to authenticate against other services such as LDAP and RADIUS. On most systems, pam will be configured to authenticate logins against the system passwd file. Unfortunately, the only way I could make pam authentication work was if the /etc/shadow file was mode 644, which is definately not a good idea. This is only useful if you have pam authenticate against something like LDAP. If you want to authenticate local users, you should use pwcheck or shadow.

shadow: this tells SASL to look for the username and password using the system /etc/shadow file. Again, /etc/shadow must be mode 644 in order for this authentication mechanism to work.

sasldb: this tells SASL to use the /var/lib/sasl/sasl.db database to check passwords and secrets. This method must be used to allow DIGEST-MD5 or CRAM-MD5 authentication. Users must be added to this database using the saslpasswd utility. You must add at least one user to the database for it to be properly initialized. This file must also be readable by the postfix user; Mandrakelinux installs the file with 0644 permissions. However, this seems to be ok as regular users cannot read information from the sasldb using the sasldblistusers program.

pwcheck: this is similar to the shadow method except you do not need to give the postfix user read access to the file (a very good idea). This method interfaces with the pwcheck daemon, which runs as root to read the /etc/shadow file instead of permitting postfix to do it. Using pwcheck is very simple, and if you want to authenticate against local users without using sasldb, you should use pwcheck. It uses the /usr/sbin/pwcheck daemon, which runs as root, to check against your /etc/shadow file. This means you don't have to change the permissions of /etc/shadow to something insecure like mode 644. pwcheck is a daemon that must be started as root and immediately launches itself into the background. Since there is no initscript for pwcheck, you can simple add to the end of your /etc/rc.d/rc.local file the following:

/usr/sbin/pwcheck

For simplicity's sake, I recommend using the sasldb method. Your /usr/lib/sasl/smtpd.conf file should then look like this:

pwcheck_method:sasldb

If you wish to use a different authentication method noted above, simply replace "sasldb" in the above example with your chosen authentication method (pam, shadow, sasldb, or pwcheck).

The next step is to populate the database. This is done with the saslpasswd program. Execute saslpasswd like this:

# saslpasswd -a smtpd -c username

This will add "username" to the application "smtpd". You will be prompted for the password interactively. The "-c" option tells saslpasswd to create an entry for the user if the user doesn't already exist. You can use the "-d" flag to delete the specified user. You can also use "-u [domain]" to specify the user domain (realm) which also corresponds with the smtpd_sasl_local_domain keyword. If you set the keyword to $myhostname, do not use the "-u" option as saslpasswd will automatically set the domain to the system's hostname (which is the equivalent of the $myhostname macro in postfix).

You can use the sasldblistusers program to list the users in the database. It will display the username, realm, and authentication mechanism available.

Once you have completed all of this, you should restart postfix using:

# service postfix restart

Testing Your Configuration

The final thing to do is to test that you have set everything up properly. The easiest way to test is to launch the Evolution mail client. In the Tools, Mail Settings, Accounts, Edit, Sending Mail menu define the server name as the SMTP server. Click on the "Check for supported type" button so that Evolution probes the server to determine what authentication types can be used. If you have installed the crammd5 and digestmd5 plugins, you should have Evolution return that Passwd, DIGEST-MD5, CRAM-MD5, and NT Login are available. Of course, make sure that you have defined the username in Evolution to be the same as that which you added to the SASL database, or a user on the SMTP server if you use the pwcheck method.

Finally, send a test message via Evolution. When you send the message, you should be asked for your SASL password. If the message is sent and the recipient has received it (best thing to do is send to another account you control or to a friend's account), you know you've done it right.

Configuring SASL support in postfix may seem a little clumsy or time consuming, but it is worth it. Requiring authentication on the SMTP server can prevent people from abusing your postfix server and ensure that only those people authorized to use it actually do use it.

Resources