Installing Postfix 2.1.1 with PCRE support on Mac OS X Server 10.3
9 May 2004—Updated 27 May 2004
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:
- Postfix now supports CIDR (Classless Inter-Domain Routing) tables. This allows significantly finer control over IP addresses in anti-spam controls.
- Postfix automatically rejects mail addressed to “user@” addresses. The malformed addressing style has lately come into vogue among certain classes of spammer and now Postfix repulses that spam automatically.
- All documentation has been rewritten. Commands and configuration is now explained better than in previous editions, and documentation is also available in HTML format. HTML documentation can be installed in an administrator-designated location during the build process.
- Support for the SMTP “XCLIENT” command. This new command makes debugging anti-spam controls (and general configuration) a snap.
- A new configuration option to thwart spamhavens. Although originally designed to defeat Verisign’s co-opting of “*.com’ “[t]his can be used to block mail from so-called spammer havens (all domains that are served by the same DNS server, all domains that resolve to the same MX host), from sender addresses that resolve to Verisign’s wild-card mail responder, or from domains that claim to have mail servers in reserved networks such as 127.0.0.1.” (from the release notes).
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: 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:
- Obtain and install PCRE 4.5
- Obtain and install a full copy of Cyrus SASL 2.1.15
- Obtain and install Postfix 2.1.1
- Configure support for SASL authenticated mail relaying
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.
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.
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!
(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: 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!