Tested on:

Installing Postfix 2.1.1 with PCRE support on Mac OS X Server 10.3

—by David O’Donnell atropos@afp548.com

9 May 2004—Updated 27 May 2004

Warning!IMPORTANT: There have been some significant changes to this article since it was first written. If you followed the steps below prior to 27 May 2004, you should re-read the article carefully. If you enabled SASL Authentication, you must put Apple’s supplied distribution back where it was originally or you will experience serious difficulties performing basic authentication tasks after your next reboot!

Hello, my name is David and I am an e-mail control freak.

If you haven’t noticed by the number of articles I have written on e-mail, e-mail is a big part of my life. You could say that I am passionate about e-mail, even. When Apple disclosed that it was bundling Postfix with Mac OS X Server 10.3, I was thrilled.

Unfortunately, when Mac OS X Server 10.3 shipped it became apparent that Apple barely scratched the surface of Postfix’ power. The user interface in Server Admin is pretty, but incredibly clumsy to use. Apple completely omitted any kind of control over virtual domains, neglected to provide a way to use most of Postfix’ powerful anti-spam controls, chose to use anti-spam controls that were deprecated long before the version that shipped with Mac OS X Server 10.3, and apparently built the installed version based on unspecified code changes so that Postfix didn’t even work as its documentation claimed. It didn’t help that Server Admin happily wipes out some user-made changes made to main.cf. When I discovered that their CIDR map support was restricted to a single file that could only be modified using Server Admin, I resolved that the time had come to take charge.

Apple ships Mac OS X Server 10.3 with a version of Postfix that self-identifies as version 2.0.10. As of writing, Postfix’ current version is 2.1.1. Much as the transition from Postfix 1.x to 2.0 introduced important new features and improved reliability, Postfix 2.1.1 is a major improvement over 2.0:

There are plenty more reasons to be happy about Postfix 2.1.1; read the release notes from your favorite source mirror to get the full picture.

Let’s get started…

I assume that you are using Mac OS X Server 10.3.x (10.3.3 as of this writing) and that you have e-mail services already enabled and working. This is important because we are going to use Postfix’ upgrade procedure instead of installing a fresh copy. You can install a fresh copy if you want—it is fairly simple—but you should read the documentation beforehand.

Warning!WARNING: Following the directions in this article will replace the version of Postfix on your Server. If Apple makes any changes to their mail service setup, the changes you make from this article will be overwritten.

WARNING: While I have tested the setup below on two Servers, I make no warranty that your experience will be equally positive. You should always make a full backup of your system before modifying core components. Don’t try this on Friday or Sunday nights, either—you are just asking for trouble!

OK—now that I have the obligatory warnings out of the way, here is what we will do in this article:

  1. Obtain and install PCRE 4.5
  2. Obtain and install a full copy of Cyrus SASL 2.1.15
  3. Obtain and install Postfix 2.1.1
  4. Configure support for SASL authenticated mail relaying

(1)Obtain and Install PCRE 4.5

Perl-compatible regular expression support has been in Postfix for a long time. Unfortunately, prior to Mac OS X Server 10.3 getting PCRE to compile and install was not worth taking the time. XCode and Mac OS X 10.3 make it a snap. Postfix does already support regular expression tables but PCRE support is just that much more fun and since it is easy to include, we will.

Obtain a copy of PCRE 4.5. Expand it into your preferred source working directory and change into the resulting directory. Assume super-user permissions now, as you will be using that level of authority for all stages of the Postfix upgrade process. You could make due with using ‘sudo’ for everything, but why go through the trouble of typing it every time? Run the standard UNIX configuration command:

./configure --enable-utf8

Strictly speaking you do not need to enable support for UTF-8 encoding. Apple’s Terminal works in that mode by default and, again, it doesn’t seem to hurt anything by including support. Now issue the make/make install pair and sit back for a minute while gcc does its thing:

make
make install

When those commands are complete, you will have a fresh new copy of PCRE 4.5 on your Server. You can test to see that the installation was successful with the commands listed below.

Note: If your shell is tcsh, you will need to rehash before you can execute the commands below.

pcre-config --version
pcre-config --libs
./RunTest

Do not be alarmed by the ”not compatible” notes in RunTest’s output.

(2)Obtain and Install SASL 2.1.15

Apple includes SASL Authentication in their custom-rolled version of Postfix. Unfortunately, they neglect to include any of the SASL headers or SASL tools. To get around this limitation so we can enable SASL Authentication in our distribution-clean version of Postfix, we need to obtain and compile the Cyrus SASL library.

As of this writing, the current version of Cyrus SASL is 2.1.18. While this version compiles cleanly on Mac OS X, the saslpasswd2 tool does not properly create entries in /etc/sasldb2.db. I am the farthest thing from a UNIX developer, so I am more than happy to defer to anyone with a more complete understanding of Cyrus SASL and Mac OS X 10.3.4 Server (like the Apple developers). Extensive Googling on the Internet proved unsuccessful, although I did find out that there is a different method of setup prefered by just about everyone who has tried to enable SASL Authentication with Postfix on any UNIX or UNIX-like platform.

Before you build SASL, you need to check to see if /usr/include/pam has been symlinked to /usr/include/security and if not, symlink it:

ln -s /usr/include/pam /usr/include/security

You could also edit SASL’s source code to account for their including security/pam.h, but this is easier.

Maintaining your presence as the super-user, change to your favorite source directory and obtain the source for Cyrus SASL 2.1.15. Unarchive and decompress it and change into the resulting directory. Make sure that you have a copy of libdl.dylib in /usr/lib; if not, you should install XCode and the Mac OS X 10.3 SDK before proceeding. Once you are satisfied that the correct file is where it should be, run the normal UNIX compilation and creation process:

./configure
make
make install

Note: SASL 2.1.15 uses ndbm on Mac OS X Server; if you have custom-compiled a more recent version of, e.g., BerkeleyDB, you will need to account for this in the configuration line.

Cyrus SASL is installed in /usr/local/lib/sasl2 by default, and wants to by symlinked to /usr/lib/sasl2. We are going to use Apple’s libraries instead of the Cyrus distribution, so ignore the symlink request. The last step we need to do here is:

mv /usr/lib/sasl2/disabled/* /usr/lib/sasl2

This enables a couple of useful plugins that Apple had turned off.

(3)Obtain and install Postfix 2.1.1

Because Postfix is a popular MTA, the developers prefer that you download the source code from a mirror site that is located near you on the network. Please do so and place the archive in your favorite source code directory before expanding it. Change into the resulting directory.

As a precautionary measure, you may want to backup the old Postfix executibles before installing the new version. The following commands may be used as an example of how to do this (remember to be super-user):

cd /usr/sbin
mkdir -p postfix-2.0.10.apple
cp -p post* postfix-2.0.10.apple
cp -p /usr/bin/mailq postfix-2.0.10.apple
cp -p /usr/bin/newaliases postfix-2.0.10.apple
cp -p sendmail postfix-2.0.10.apple
cd /usr/libexec
mkdir -p postfix-2.0.10.apple
cp -Rp postfix/* postfix-2.0.10.apple

Change back to your Postfix source directory. You will now configure the Postfix make process. We will include support for PCRE, LDAP, and SASL. We will also install the HTML documentation at /Library/WebServer/Documents/PostfixDocs (change this location to suit your desires) and the sample README files in /etc/postfix/readmes.

Note: In the command sequence below, a backslash (“\”) at the end of a line is used to signify a long command line broken into smaller segments. If you desire, omit the backslashes and enter the command as one long line.

make tidy
make -f Makefile.init makefiles \
CCARGS='-DHAS_LDAP -I/usr/include \
-DUSE_SASL_AUTH -I/usr/local/include/sasl \
-DDEF_HTML_DIR=\"/Library/WebServer/Documents/PostfixDocs\" \
-DDEF_README_DIR=\"/etc/postfix/readmes\" ' \
AUXLIBS='-L/usr/lib -lldap -L/usr/lib -llber -L/usr/lib -lsasl2'
make
make upgrade

At this point you have a fully-functional Postfix 2.1.1 installation. Check to see if the proper SASL library has been linked by using the command below:

otool -L /usr/libexec/postfix/smtpd | grep sasl

You should see “/usr/lib/libsasl2.2.0.1.dylib (compatibility version 3.0.0, current version 1.0.0)” returned. Issue the commands

postfix check
postfix reload

to restart Postfix with the new version. Be sure to check out the Documentation for all the new goodies in Postfix 2.1.1, and remember:

Do not ever use the Server Admin interface again to make changes to mail service!

(4)(Optional) Setup SASL Authenticated relaying

If you have wandering users—or you wander networks yourself—setting up SASL authenticated mail relaying makes it easy to properly send mail to the Internet using your Server no matter where on the Internet you may be. SASL Authenticated relaying means no more configuring a mail server for every location you visit!

Warning!WARNING: SASL Authenticated relaying assumes that your users’ passwords are secure. While it is unlikely that spammers or other malcontents will attempt to subvert your mail server to their nefarious ends by trying to break into SASL Authentication, past history has shown that miscreants will stop at nothing to try to violate security—and with the rise of hacker gangs in the employ of spammers, it is possible that attempts on SASL will be made. You should always encourage your users to maintain strong security in their passwords.

Some of the information in this section is based on Calabar Bean’s article on enabling Postfix with TLS and SASL on Mac OS X 10.3.3. The full article is worth reading, especially if you want to use TLS. (Note: as of 2004-05-27, Mr Bean’s article appears to have disappeared off the network. Google may have a cache.)

Because we have departed from Apple’s supplied SASL authentication implementation, we will need to “roll our own” and go the traditional UNIX way. Luckily, Mac OS X Server 10.3 is setup to let us do this with little trouble. First, we need to configure the PAM service to work with SMTP. SMTP uses the same facilities as FTP, so we copy the existing FTP file to become SMTP (remember to be super-user!):

cp -p /etc/pam.d/ftpd /etc/pam.d/smtp

Now we need to configure SASL’s smtpd file. Create the file “/usr/lib/sasl2/smtpd.conf” with the following two lines in it:

auxprop_plugin: sasldb
pwcheck_method: auxprop
mech_list: plain login cram-md5

Additional authentication mechanisms exist, but I like to use CRAM-MD5. If you like, add others based on the SASL documentation.

We need to configure Postfix support for SASL now. If you previously enabled SMTP Authentication in the Server Admin mail module (under the Advanced tab), some of these lines will already exist in /etc/postfix/main.cf:

# SASL Authentication Support
#
enable_server_options            = yes
smtpd_use_tls                    = no
smtpd_enforce_tls                = no
smtpd_tls_loglevel               = 0
smtpd_sasl_auth_enable           = yes
smtpd_sasl_security_options      = noanonymous
smtpd_sasl_local_domain          = $myhostname
smtpd_sasl_application_name      = smtpd
broken_sasl_auth_clients         = no
smtpd_use_pw_server              = yes
smtpd_pw_server_security_options = plain,login,cram-md5
server_enabled                   = 1

Note that we do not enable or enforce TLS in this configuration; if you want to use TLS, please read Calabar Bean’s article as a jumping-off point. We elect to refuse ANONYMOUS authentication, which makes good security sense. Also make note of the “smtpd_sasl_local_domain = $myhostname” setting. Postfix only supports one domain per smtpd daemon so it is important that you set this value correctly. The value for this setting will be used to build the SASL authentication database and must be correct for authentication to occur properly.

Note: After extensive Google searches and digging through reference books, it appears that you can safely omit $myhostname from the smtpd_sasl_local_domain line; and that doing so may be recommended if you handle mail for multiple domains.

You will need to modify your smtpd restrictions in main.cf to add support for SASL authentication. For example:

smtpd_recipient_restrictions = 
    permit_mynetworks,
    permit_sasl_authenticated …

Read the Postfix documentation on restriction classes and SASL authentication for more information.

The last thing we need to do is create and populate the SASL authentication database, /etc/sasldb2.db. If you previously tried setting up SMTP or IMAP authentication using Server Admin, that file may already exist. If so, you need to give Postfix access to it:

chgrp postfix /etc/sasldb2.db
chmod 640 /etc/sasldb2.db

Then for each user who you will permit to relay using SASL Authentication, execute the following command:

/usr/local/sbin/saslpasswd2 -c -u `postconf -h myhostname` userid

Replace “userid” with the user’s Short Name (i.e., johndoe instead of John Doe). If you do not use “smtpd_sasl_local_domain = $myhostname” you should change myhostname to the variable you use or replace `postconf -h myhostname` with a static value.

Note: You may notice that the method I recommend requires that you manually add every authenticating user to the SASL database. This departs from the method Apple uses, which uses one-time passwords. There are two reasons for this: first, my research led me to multiple authors who asserted that the SASL database is more secure; and second, because it was the only way I could get authentication to work.

At this point, you should be able to configure a mail client to use SASL Authentication to relay mail through your server. Look for log entries like the following (lines have been formatted for easier reading):

May 27 02:08:02 localhost postfix/smtpd[909]: connect from foo.bar.org[11.22.33.44]
May 27 02:08:02 localhost postfix/smtpd[909]: getPasswordRec returning -1
May 27 02:08:02 localhost postfix/smtpd[909]: getPasswordRec returning -1
May 27 02:08:02 localhost postfix/smtpd[909]: warning: SASL authentication failure: no user in db
May 27 02:08:02 localhost postfix/smtpd[909]: getPasswordRec returning -1
May 27 02:08:02 localhost postfix/smtpd[909]: C56AB7A2CC: client=foo.bar.org[11.22.33.44], sasl_method=CRAM-MD5, sasl_username=atropos
May 27 02:08:02 localhost postfix/cleanup[912]: C56AB7A2CC: message-id=<C9CF3370467A2199289AD6A8@foo.bar.org>
May 27 02:08:02 localhost postfix/qmgr[908]: C56AB7A2CC: from=<atropos@fates.org>, size=918, nrcpt=1 (queue active)
May 27 02:08:02 localhost postfix/smtpd[909]: disconnect from foo.bar.org[11.22.33.44]

Although Postfix complains that there is no user in the database, there is. Had the user misauthenticated, or someone not authorized attempted to authenticate, you would see something like this:

May 27 02:10:52 localhost postfix/smtpd[1020]: connect from foo.bar.org[11.22.33.44]
May 27 02:10:54 localhost postfix/smtpd[1020]: getPasswordRec returning -1
May 27 02:10:54 localhost postfix/smtpd[1020]: getPasswordRec returning -1
May 27 02:10:54 localhost postfix/smtpd[1020]: warning: SASL authentication failure: no user in db
May 27 02:10:54 localhost postfix/smtpd[1020]: warning: SASL authentication failure: no user in db
May 27 02:10:54 localhost postfix/smtpd[1020]: getPasswordRec returning -1
May 27 02:10:54 localhost postfix/smtpd[1020]: getPasswordRec returning -1
May 27 02:10:54 localhost postfix/smtpd[1020]: warning: SASL authentication failure: no secret in database
May 27 02:10:54 localhost postfix/smtpd[1020]: warning: foo.bar.org[11.22.33.44]: SASL CRAM-MD5 authentication failed

I hope that at some point, I will be sufficiently well-versed in the ins-and-outs of what goes on behind the scenes to eliminate the irritating first no user error; in the meanwhile, you are set up to use SASL Authentication for those users who you trust not to abuse it.

Thus endeth today’s lesson. Have fun tweaking Postfix to eke out the most of your mail server, and serve some damage to those who want to serve you spammage!