Exim 4.10 as an SMTP agent for Mac OS X Server

—Joel Rennich,

7 June 2002 - Updated 18 September 2002

Sort of 10.2 OK!

Exim

Unfortunately, changes in the compiler that ships with Mac OS X Server 10.2 have made libmcrypt uncompilable as-is. Since Exim relies upon that library to function, you will find it difficult to get Exim to run in a fresh installation of 10.2; if you are upgrading from 10.1 to 10.2, however, Exim should continue to function without problem.

To help alleviate the trouble new Jaguar users will encounter, Joel has created a special Exim Installer.

An SSL-enabled, SMTP AUTH supporting, spam- and virus-checking SMTP server—for free—on Mac OS X Server; in three easy parts.

Note: the “” graphic, used below, indicates that the current and following line should be input as one, not split up.

Part 1: Installing Exim 4.10

Basic mail services are fun, but once you get your name out into the world you are bound to start getting hit with spam and virus infection attacks. These won’t do much more than annoy you, since you are using a Mac, but you can mitigate their impact on your life. This three step project will install Exim 4.10 on your server to work as an SMTP server, or Mail Transport Agent (MTA), on your machine. We will compile Exim with SSL/TLS and SMTP AUTH support in part one. In part two, we will integrate Exim with SpamAssassin, which can check incoming mail for spam in a number of different ways. Finally we will use a Java™ virus scanner from www.openantivirus.com to scan all of the mail before it gets to your users.

First of all, you need to download the GNU libmcrypt library. Exim needs some help with the encryption schemes that we will be using and this library will do the trick. It compiles cleanly on Mac OS X so all you have to do is go get it from ftp://mcrypt.hellug.gr/pub/crypto/mcrypt/libmcrypt/libmcrypt-2.4.21.tar.gz. Either use a browser—in which case StuffIt Expander will automatically unstuff it for you—or do it all from the command line:

curl -O ftp://mcrypt.hellug.gr/pub/crypto/mcrypt/libmcrypt/libmcrypt-2.4.21.tar.gz
gunzip libmcrypt-2.4.21.tar.gz
gnutar libmcrypt-2.4.21.tar

Then switch into the folder:

cd libmcrypt-2.4.21

and begin compilng the library:

./configure
make
sudo make install

Exim actually looks for the old UNIX crypt library, which libmcrypt replaces, so we need to do a little sleight of hand:

sudo cp /usr/local/include/mcrypt.h /usr/local/include/crypt.h

This makes the switch so that Exim is happy.

Next, you will need the openssl libraries. If you have Fink, you can use that tool to obtain them; otherwise, we can go from scratch:

curl -O http://www.openssl.org/source/openssl-0.9.6d.tar.gz
gnutar -xvzf openssl-0.9.6d.tar.gz
cd openssl-0.9.6d
./configure darwin-ppc-cc
make
sudo make install

Be prepared: this build can take a while. Go watch Buffy the Vampire Slayer or something while this is cooking.

Now you need to create a user for Exim. You can either do this in NetInfo or Server Admin. In NetInfo the easiest way would be to duplicate the entry for “daemon” in the users directory, and switch the name to “exim” and the uid to “88” or something else that you are not using. If you use Server Admin, create the user as normal, but set the password to “*” and set as many options to “none” as possible. The Exim user doesn’t need a home directory. Don’t make Exim an Admin user, no matter how much you like the mail server.

Whew, almost there: now all we have left is Exim itself.

curl -O ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/exim-4.10.tar.gz
gnutar -xvzf exim-4.10.tar.gz
cd exim-4.10
cp src/EDITME Local/Makefile

Now you need to edit the Makefile. You can do this either by hand from the command line, using vi or emacs, or by using TextEdit by executing

open -e Local/Makefile

Essentially, you only need to change a few things in this file. First, uncomment the line that says Exim should run as the exim user by removing the pound sign at the beginning.

EXIM_USER= exim

If you want to use virtual domains (more on that later if you are unfamiliar with the term), uncomment this line:

#LOOKUP_DSEARCH=yes

Next, you will want to comment out the line that sets up the X Windows GUI for Exim. This is cool, but you need to run X Windows to get it going.

#EXIM_MONITOR=eximon.bin

If you do decide to use this feature, read up on it in the documentation. You’ll need to create a config file for it, too.

Now you are going to need to uncomment the lines pertaining to SMTP authentication:

AUTH_CRAM_MD5=yes
AUTH_PLAINTEXT=yes
AUTH_SPA=yes

And just below that a few lines to enable TLS/SSL support:

SUPPORT_TLS=yes TLS_LIBS=-lssl -lcrypto

If you just compiled openSSL, you will need to edit the TLS_LIBS and TLS_INCLUDE variables just a few lines further into the file to:

TLS_LIBS=-L/usr/local/ssl/lib -lssl -lcrypto

and

TLS_INCLUDE=-I/usr/local/ssl/include/

If you installed openSSL with Fink you should use:

TLS_LIBS=-L/sw/lib -lssl -lcrypto

and

TLS_INCLUDE=-I/sw/include/openssl/

Now save the file and get on with the compile:

make sudo make install

You need to make a few changes to /usr/exim/configure. This file is owned by root, so you are either going to have to assume superuser rights to edit it, or change the permissions. Read through the file a bit; it is well commented, so you shouldn’t have any problems. Essentially, you need to set a domain name and what your trusted networks for relaying are. At the end of this file you will want to add the routines to have the SMTP AUTH check a password file.

######################################################################
#                   AUTHENTICATION CONFIGURATION                     #
######################################################################

# There are no authenticator specifications in this default configuration file.

begin authenticators
fixed_plain:
   driver = plaintext
   public_name = PLAIN
   server_condition = ${if eq{$3}
{${extract{1}{:}{${lookup{$2}lsearch{/etc/relayers}{$value}}}}}{yes}{no}}
      server_set_id = $2
   
   fixed_cram:
      driver = cram_md5
      public_name= CRAM-MD5
      server_secret = ${lookup{$1}lsearch{/etc/relayers}{$value}{fail}} 
      server_set_id = $1
   login:
      driver = plaintext
      public_name = LOGIN
      server_prompts = "Username:: : Password::"
      server_condition = ${if eq{$2}{${lookup{$1}lsearch{/etc/relayers}{$value}{no}}}{yes}{no}}
      server_set_id = $1 
   # End of Exim configuration file

You will need to create that file with

sudo touch /etc/relayers

By default, Exim uses /etc/aliases for all of the mail aliases. Mac OS X 10.1.5 finally includes this file, but prior to it you had to create the file yourself. Exim will automatically create it during the build if you don’t have it, so you don’t need to worry either way.

In these files, you can put a username with a colon and then a tab and then the alias for the alias file; for the relayers, use a username, a colon, tab, and then the user’s password.

For example, for the mail aliases:

joel: sjobs@apple.com

will cause all mail addressed to joel to be forwarded to sjobs@apple.com. This file can also be used to host virtual domains. Virtual domains allow you to host mail for more than one DNS name and still have discrete inboxes for the users in that domain. If that didn’t make sense, don’t worry—I’ll explain more at the end of this article.

Now for the relayers file:

joel: Xisgreat

will allow joel to use that username and password in most every e-mail application for authenticated SMTP relaying.

A quick note on relaying passwords: it is probably best to pick one generic username and password for relaying and have all of your users use that. This reduces the risk of any user passwords being compromised, and it makes setting up the initial relay password file a breeze.

The trickiest part about the config file is getting it to work with your POP/IMAP server. Look in the configure file for “local_delivery:” if you are going to use UW IMAP server and want to keep the mail in users' home folders, you can set it up this way:

local_delivery:
  driver = appendfile
  file = /Users/$local_part/mail/INBOX
  delivery_date_add
  envelope_to_add
  return_path_add

If you want to use Apple’s Mail Server instead, use this syntax:

ocal_delivery:
  driver = smtp
  port = 627 
  hosts = 127.0.0.1
  hosts_override = true

You will also need to set the Apple Mail Server to use this method by using the Server Admin application. Click on the Mail icon under the “Internet” tab and select “Configure Mail Service?” In the new window that pops up, click on the “Protocols” tab. The first pull-down menu will be set to “SMTP” and you need to change that to “Sendmail."

You can find a sample configure file here.

Now you should be done with the configuration, so it’s time to kick the tires and see if it will run.

sudo /usr/exim/bin/exim -bd -d

This will start Exim up and show you everything it is doing in a Terminal window. Launch another Terminal window and

telnet localhost smtp

If you make a connection everything is probably good. If not, check /var/log/exim_mainlog and /var/log/exim_paniclog for some clues as to what might be going on.

The last piece is to create a Startup Item to launch Exim when the Server boots up. Create a folder in /Library/Startupitems called Exim and copy these two files into it: Exim and StartupParameters.plist. Then edit /etc/hostconfig and add this at the end:

EXIM:=-YES-

Now, for some more information on virtual domains. Skip to the next article if you don’t want to do this.

First, some more explanation of what a virtual domain is. Let’s say you have two domains that you manage: afp547.com and afp546.com. You have an admin account in both domains. If you want e-mail to those two addresses (admin@afp547.com and admin@afp546.com) to go to the same user, you don’t need to do a thing: this is the default behavior. However, if you want to keep two separate inboxes for these accounts, you want to use virtual domains.

First, we’ll create two users on the server: “afp547admin” and “afp546admin” (Note: in Mac OS X Server 10.2, you will be able to use these long names as Short Names; in Mac OS X Server 10.1, you will need to shrink them to eight characters.) We now have two separate mailboxes to use on the server.

Next, we need to create an alias file for each domain.

sudo touch /etc/mail/afp546.com
sudo touch /etc/mail/afp547.com
sudo chmod 664 /etc/mail/afp546.com
sudo chmod 664 /etc/mail/afp547.com
sudo chown root:admin /etc/mail/afp546.com
sudo chown root:admin /etc/mail/afp547.com

We now have an alias file for both of the domains. We have made this file writable by the admin group, which most likely includes yourself, so you can make changes using TextEdit or any GUI editor. You could also create a group just for that domain that would include the administrator for that domain. This way that person could change aliases, but other admins on the system could not.

Now we need to add entries to the files. To /etc/mail/afp546.com we are going to add:

admin : afp546admin

And to /etc/mail/afp547.com:

admin : afp547admin

These aliases will redirect the mail to those the admin account in those domains to the actual mailboxes on your server. Pretty simple.

Finally we need to add a new router to the exim config file.

virtual:
  driver = redirect
  domains = dsearch;/etc/mail/virtual
  data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain}}
  no_more

This should come before the system_aliases router.

Now incoming mail gets separated between the two domains into separate users. The only tricky thing about a setup like this is that you will need to login as afp547admin and afp546admin when getting you mail over POP/IMAP. Don’t forget that and it should be smooth sailing.

In the next part of this series, we will compile and install SpamAssassin and edit the Exim configure file to pass all the mail through it.