HOWTO HOWTO: Adding SASL Support to Postfix on FreeBSD 4.x

Glenn Sidman, gsidman@tuxweb.net
Created: January 25, 2004



 


 

1.0 About This HOWTO

This HOWTO assumes you have at least some experiance with the Postfix MTA and a POP3 or IMAP server. If not, please refer to my earlier HOWTOs: Replacing Sendmail with Postfix on FreeBSD 4.x and Adding POP3 to Postfix with akpop3d as this is an extension of those HOWTOs. The purpose of this HOWTO is to rebuild Postfix with a mechanism allowing mail clients connecting via POP3 or IMAP to authenticate though SMTP and relay mail to other domains. In other words, allow users to send mail to users outside of our own domain. Along the way, we will also build a foundation for TLS (Transport Layer Security) that can later be added to encrypt communications, including passwords, between our server and mail clients.

The following versions were used for this HOWTO:

 


 

2.0 Introducing SASL And The Mail Relay Challenge

Before Postfix will relay mail from untrusted networks, the client must open a trust with Postfix. There are two popular ways to accomplish this. The first is to use pop-before-smtp, which usually involves a perl script that checks the mail log for successful POP3 or IMAP connections (users checking their mail) and adds the user's IP address to a list of trusted users for a specified period of time. Now, when the external user attempts to send (relay) mail, Postfix checks the listed of trusted IP address, finds the client's address, and allows the relay. The biggest annoyance of pop-before-smtp is the fact that some popular mail clients will try to send mail before they check mail. If the pop-before-smtp timer has elapsed since the last time the client has checked mail, the attempt to send will fail with "relay access denied". To add insult to injury, these popular mail clients will not even attempt to check mail after the send fails. You have to remove your message from the "outbox", check mail to re-establish your "trusted" connection, and only then can you send your message! The fix, obviously, is to set the mail client to check mail at least once before the timer runs out. If you are interested in pop-before-smtp for FreeBSD, I would begin by looking at DRAC.

The second method of developing a trust with Postfix is through the use of the SMTP AUTH extension specified in RFC 2554. From here on, I will cover how to use SASL (Simple Authentication and Security Layer) from Project Cyrus to provide this functionality. The Postfix site has a number of links detailing SASL and Postfix support under Postfix Documentation, Howtos and FAQs. Though it is intended for Mandrake Linux, Vincent Danen's provides a good overview of SASL in Enabling SASL support in postfix. I would also recommend Tim Yocum's Postfix SASL + TLS + FreeBSD tutorial.

In short, SASL provides an authentication layer to SMTP, and as far as I know, all mail clients are able to authenticate through SASL. (Alexey Melnikov offers a list of mail clients and their supported authentication types here.) Whereas pop-before-smtp instructs Postfix to trust the client's IP address, SASL allows the client to truly authenticate with Postfix. There is no need to check mail before receiving mail and no time-out counter. At this time, SASL appears to be fairly secure provided we use a reasonable mechanism to verify usernames and passwords such as SASLAUTH which I will cover in this HOWTO. If you have been researching SASL and Postfix, you have no doubt noticed a lot of references to TLS (Transport Layer Security). TLS is not required by SASL or Postfix, but rather it provides data encryption and additional verification through the use of certificates. I will not cover TLS in this HOWTO, however, I will explain how to add TLS support when we build Postfix. Chances are, if you are using SASL you will likely also be interested in TLS. This way we have Postfix built with TLS support which and be enabled later.


 

3.0 But first, Some Initial Configuration

By default, Postfix trusts clients on our local network (subnet). Thus, there is no need for our internal clients to use pop-before-smtp or SASL before relaying mail. This make troubleshooting SASL difficult if you have no practical way of connecting to your mailserver from the outside. For this reason, as well as additional security, my first recommendation is to change Postfix's default behavior from "permit_mynetworks" to don't permit anyone to relay mail. This is set via the "smtpd_recipient_restrictions" in /usr/local/etc/postfix/main.cf. Before you go searching, I should probably let you know that Postfix does not normally add "smtpd_recipient_restrictions" to the main.cf file. Its absence tells Postfix to use the default which would look like:

smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination

If "smtpd_recipient_restrictions" is already present, remove "permit_mynetworks". If not, add the following for now. (All on one line without a leading white space or tab):

smtpd_recipient_restrictions = reject_unauth_destination

Now issue "postfix reload" to reload the main.cf configuration file. You should no longer be able to relay mail though your mailserver from any client. (You can send mail to another account on your own mailserver, but you should not be able to send (relay) mail to any other account on another mailserver.).


 

4.0 Building Postfix with SASL support (Installing SASL)

Postfix must be compiled with SASL support, specifically Cyrus SASLv2. (Jump to "Verifying SASL2 Support in Postfix:" if you suspect your current build may already support SASL2.) If you want to compile from the tarbal, check out Postfix + TLS + SASL on FreeBSD by Tim Yocum. Happily, the Postfix port now provides a "Postfix Configuration Options" menu and compiling from the tarbal is no longer required. The easiest way to install SASL2 is by simply specifying its support when installing the Postfix port. This will download and install all necessary components.

 

          NOTE: If you have already installed Postfix from the ports collection without SASL2 support, you will need to uninstall and reinstall Postfix. I am not aware of a way to "upgrade" with SASL2 support through the ports collection. Also,"make reinstall" will not work. Before removing Postfix, be sure to backup /usr/local/etc/postfix/main.cf. If it is running, kill postfix with "postfix stop", change to the Ports directory from which you built Postfix (probably /usr/ports/mail/postfix-current). Issue "make deinstall" then "make reinstall". If "make deinstall" fails, then find the correct name of the Postfix package with "pkg_info" and then "pkg_delete postfix-2.X.XX.xxxxx". Now, you can install Postfix again with "make install" for the Ports collection. Got it?

 

The Postfix installation procedure is fundamentally the same as covered in "HOWTO: Replacing Sendmail with Postfix on FreeBSD 4.x", though I will go over the steps again here. We just need to select SASL2 support from the initial Postfix configuration options menu as shown below:

Postfix Configuration Options

In this example, I have also selected TLS (SSL and TLS) to provide support for encrypted passwords. Without TLS support, the passwords used to authenticate with SASL are passed over the network in plain text. If you are interested in TLS support, select it now, otherwise you will need to rebuild later. Compiling Postfix with TLS support does not enable TLS, however, you will be able to enable it later in your Postfix main.cf file (you will also need to generate certificates). Now let us move on to the build.

cd /usr/ports/mail/postfix-current
make install

From the "Postfix configuration options" menu select "SASL2" (select by using the space bar) along with any other compile options you may require.

The Postfix install will ask the following questions:
 

          You need user "postfix" added to group "mail". Would you like me to add it [y]? Select YES
Would you like to activate Postfix in /etc/mail/mailer.conf [n]? Select YES

At this point, SASL2 should be installed and Postfix should be built with support for SASL2. We will verify in the next section. There are some additional configurations, which I will not be covering her, that need to be completed before Postfix can be. I am only covering the configuration of SASL support in this HOWTO. If you need assistance with Postfix configuration, please visit my "HOWTO: Replacing Sendmail With Postfix on FreeBSD 4.x" HOWTO, or the documentation page at www.Postfix.org/docs.html.


 

5.0 Verifying SASL2 Support In Postfix:

We can easily verify by which libraries Postfix's smtpd binary supports with ldd. The default directory of Postfix's smtpd for FreeBSD 4.x is /usr/local/libexec/postfix. So, we issue the following:

ldd /usr/local/libexec/postfix/smtpd

The below example ldd output shows support for SASL2 (libsasl2.so.2) as well as TLS (libssl.so.3).

 

/usr/local/libexec/postfix/smtpd:
     libsasl2.so.2 => /usr/local/lib/libsasl2.so.2 (0x28091000)
     libpam.so.1 => /usr/lib/libpam.so.1 (0x280a3000)
     libcrypt.so.2 => /usr/lib/libcrypt.so.2 (0x280ad000)
     libssl.so.3 => /usr/lib/libssl.so.3 (0x280c6000)
     libcrypto.so.3 => /usr/lib/libcrypto.so.3 (0x280f5000)
     libpcre.so.0 => /usr/local/lib/libpcre.so.0 (0x281ec000)
     libc.so.4 => /usr/lib/libc.so.4 (0x281f7000)


 

6.0 Installing saslauthd (SASL authentication server)

There are a variety of ways that SASL2 can authenticate including PAM, shadow, sasldb, and pwcheck. Most are either insecure, complex, or simply broken. I prefer to use saslauthd. (Although, I hear PAM can work well with SASL2 and Postfix if you are familiar with it.) Moving on with saslauthd, we will need to install and start it:

Lets locate the saslauthd port:

cd /usr/ports
make search name=saslauthd

The "path=" should be /usr/ports/security/cyrus-sasl2-saslauthd. Now change to the saslauthd directory and install:

cd security/cyrus-sasl2-saslauthd
make install

Note that we only need to install cyrus-sasl-saslauthd-2.1.15_3. The cyrus-sasl-2.1.15 and rc_subr-1.16 dependencies will be installed automatically

Provided we have saslauthd.sh in our /usr/local/etc/rc.d directory, saslauthd will start automatically the next time we boot. If instead you have saslauthd.sh.sample, just rename it to saslauthd.sh (mv saslauthd.sh.sample saslauthd.sh). Now lets start saslauthd:

/usr/local/etc/rc.d/saslauthd.sh start

You should be greeted with "Starting saslauthd". If you get errors, you will need to fix this before moving on. Try Google. If all else fails, you can look into using a different authentication method.


 

7.0 Configuring SASL2 Support in Postfix

First, we need to notify SASL2 of our preferred authentication method. This is done by adding "pwcheck_method: saslauthd" to /usr/local/lib/sasl2/smtp.conf. You may want to check to see if you already have an smtp.conf file. If so, rename it. Otherwise, I have always had to create my own. We will use echo here just to be cool.

cd /usr/local/lib/sasl2
echo "pwcheck_method: saslauthd" > smtpd.conf

Now we need to disable the NTLM (NT Lan Manager) authentication method if you will have MS Outlook clients attempting to authenticate. This is straight from "Postfix + TLS + SASL on FreeBSD" by Tim Yocum in which he creates a "disabled" directory for unused authentication methods/modules.

cd /usr/local/lib/sasl2
mkdir deactivated
mv *ntlm* deactivated

Now we get into the serious configuration. The following options will be added to the Postfix configuration file /usr/local/etc/postfix/main.cf. I strongly encourage you to look at "smtpd_recipient_restrictions" and "smtpd_sender_restrictions" in Postfix Configuration - UCE Controls before making changes. (Note: Tabs represent a new line. Avoid whit space at the beginning of a configuration line unless you really mean for it to be an extension of the previous line.) Below are the parameters we need to add and/or modify. I will follow with an explanation.

cd /usr/local/etc/postfix
cp main.cf main.cf.pre-sasl2
ee main.cf

Add the following anywhere, though I would recommend at the end, to your main.cf. Remember that "smtpd_recipient_restrictions" may already exist. If not, just add it. Also, your "smtpd_recipient_restrictions" may differ. We just need to be sure "permit_sasl_authenticated" gets added as the first value.

# UCE Controls: permit SASL2, reject all others
smtpd_recipient_restrictions = permit_sasl_authenticated, reject_unauth_destination

# SASL2 specific options
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain =
	
Remember "smtpd_recipient_restrictions" from earlier where we "killed" the default of "permit_mynetworks" to disallow mail relaying from anyone and everyone? Well, now we are going to add "permit_sasl_authenticated" as the first value to allow SASL2 authenticated users to relay mail. (Once we are done testing, you can append this parameter with "permit_mynetworks".)

The "broken_sasl_auth_clients = yes" is to accommodate broken mail clients which are expecting to see "250-AUTH=PLAIN... " rather than the correct "250-AUTH PLAIN... " without the "=". This is why we will later see the 250-AUTH banner twice--once without the equal sign and once with. (Outlook Express 4 may be the only mail client that requires this.)

The "smtpd_sasl_auth_enable = yes" is self explanitory..... I hope.

The "smtpd_sasl_local_domain = " is tricky and I don't fully understand it. It is required though. This tells SASL2 which realm to use when authenticating the user. I leave it blank which works for me. If you set the value to $myhostname, you will need to specify the realm as well as the username. I have had very little luck when specifying $myhostname. You will probably want to leave it blank as well.

 

          A note about "smtpd_sender_restrictions", not Not to be confused with "smtpd_recipient_restrictions". The Postfix default is to accept sender address from anyone, which if added to the main.cf would look like: "smtpd_sender_restrictions = ". I have very often seen this changed to: "smtpd_sender_restrictions = permit_sasl_authenticated". I am NOT an expert in UCE controls, but this seems pointless to me and appears to be ignored by Postfix. I very well could be incorrect, and if so, please let me know. If you are concerned, lookup "smtpd_sender_restrictions at Postfix Configuration - UCE Controls and think about it.

 

Ok, we're configured! Time to test. If Postfix is already running, reload the configuration file with "postfix reload". Otherwise, start Postfix with "postfix start".

One last thing. Newer versions of Postfix with SASL2 enabled seem to require read and write access to /etc/opiekeys. As far as I know, opiekeys is solely used for OTP (One Time Password) schemes such as Secure ID cards or RSA Tokens. We are not using it, but Postfix will complain if we do not provide read and write permissions. So, lets add the mail group and provide the owner and group with read/write permissions. (A couple of notes: Use caution if you are actually using OTP. If you are not sure, then you are probably not using OTP. Also, this assumes you have added the postfix account to the mail group. If you followed this HOWTO, then you did.)

chown root:mail /etc/opiekeys
chmod 660 /etc/opiekeys

 

8.0 Our First Test of SASL2 Support

From a console (or telnet) on our mail server, lets telnet to SMTP port 25 to see if Postfix will offer SASL authentication. First we connect with "telnet localhost 25":

telnet localhost 25
 Trying 127.0.0.1...
 Connected to localhost.test.local.
 Escape character is '^]'.
 220 mailserver.test.local ESMTP Postfix
Now, we say hello with "ehlo" followed by any domain name you chose. Your result should include "250-AUTH" at least once, or in the following example, twice. Once with an RFC complient "250-AUTH" and once for broken clients "250-AUTH="

ehlo me.test.local
 250-mailserver.test.local
 250-PIPELINING
 250-SIZE 10240000
 250-VRFY
 250-ETRN
 250-AUTH PLAIN DIGEST-MD5 CRAM-MD5
 250-AUTH=PLAIN DIGEST-MD5 CRAM-MD5
 250-XVERP
 250 8BITMIME
Use "quit" to get out of your SMTP session.

The values immediately following the AUTH-250 banner are important as they advertise Postfix's supported authentication types which in this example are: PLAIN (plain text), DIGEST-MD5 (Message Digest 5) and CRAM-MD5 (Older Message Digest authentication for LDAP v3 servers). If you see NTLM in the list, usually at the beginning, Microsoft mail clients will try to use it and fail. In such case, you will be asked for a username, password, and domain. Below is an example from Outlook Express 6. If you see this, you will need to remove all NTLM authentication types as mentioned earlier. (You will also need to reboot your Windows client if you already tried to connect when NTLM was enabled.)

Outlook Express asking for username pw and domain


 

9.0 Configuring The Mail Client

Assuming you were able to get the "250-AUTH" banner, then we are ready to setup our mail client for a real-world test. We need to be sure that our mail client attempts to authenticate before sending mail. Obviously this setup varies between clients. I will use Outlook Express 6 for the following example, though other clients, such as Mozila Mail, will attempt outgoing mail authentication by default. Mozila will simply ask you for a password the first time it sees the "250-AUTH" banner.

Configuring Outlook Express: Once you have your standard mail account setup, simply go to "Tools" > "Accounts" > select "Mail" tab > and double-click on your mail account. Select the "Servers" tab on your mail account properties. Under "Outgoing Mail Server" check the "My server requires authentication" box.

Mail Properties Box

Now select "Settings" and ensure that the "Use same settings as my incoming mail server" radio button is selected. I believe you can also select "Log on using" provided you enter your username and password.

Outgoing Mail Server

Some final notes: Some antivirus programs, specifically Norton Antivirus, can cause problems with SASL and TLS when outgoing mail scanning is enabled. If you are having issues, try using different mail clients or a different client machine if available. A telnet session, as we did earlier from our mail server's console, is an particularly useful tool. Unfortunately, the MS Windows telnet session does not allow you to see what you are typing once you connect. It will work just the same, but you will be typing blind. So, if you are going to use telnet from a remote machine, try to find one that is not a MS Windows machine.


 

10.0 Additional Resources

The Home of Postfix:
www.postfix.org

Project Cyrus:
http://asg.web.cmu.edu/cyrus/

Postfix + TLS + SASL on FreeBSD by Tim Yocum :
http://yocum.org/faqs/postfix-tls-sasl.html

Enabling SASL support in postfix by Vincent Danen:
http://www.mandrakesecure.net/en/docs/postfix-sasl.php

List of mail clients and supported authentication types:
http://www.sendmail.org/~ca/email/mel/SASL_ClientRef.html



Please feel free to contact me with comments, corrections, or additions.

Glenn Sidman
gsidman@tuxweb.net
 






 








Previous page: doc.nettools.ru/UnixMain page: www.nettools.ru