Exim 4.10 as an SMTP agent for Mac OS X Server 10.2

—by Joel Rennich, mactroll@afp548.com

21 October 2002

Note: This article is explicitly designed to work with Mac OS X Server 10.2 only. Please see Joel’s other article for a 10.1-compliant version.

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.

Installing Exim on 10.2 has gotten much easier than in previous builds. Apple has been spending some time putting the UNIX things back in the places that they should be. However, Exim hasn’t yet caught up with 10.2. It’s not really Exim’s fault, since a new version hasn’t been released since 10.2 came out, so we’re going to a little work to help it out.

First you need to create a user for Exim. You can either do this in NetInfo or Workgroup Manager. In NetInfo the easiest way would be to duplicate the entry for “daemon” in the users directory, then switch the name to “exim” and the uid to “88” or something else that you are not using. If you use Workgroup Manager, 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.

Now for 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

First, we need to change the header file to get Exim compiling right:

open -e OS/os.h-Darwin

This will open up the file in Text Edit where you can swap what it contains with:

/* Exim: OS-specific C header file for Darwin (Mac OS X) */

/* #define CRYPT_H */  /* Apparently this isn’t needed */

#define HAVE_MMAP
#define HAVE_SYS_MOUNT_H
#define SIOCGIFCONF_GIVES_ADDR

#define NO_IP_VAR_H
#define GLIBC_IP_OPTIONS
#define __GLIBC__       3

#define F_FREESP     O_TRUNC
typedef struct flock flock_t;

#define BASE_62 36  /* HFS+ aliases lower and upper cases in filenames.
                       Consider reducing MAX_LOCALHOST_NUMBER */

/* End */

Save this and go back to the Terminal.

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

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/include/openssl -lssl -lcrypto

and

TLS_INCLUDE=-I/usr/include/openssl/

Last uncomment the line about where Exim puts its logs.

LOG_FILE_PATH=/var/log/exim_%slog

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:

local_delivery:
  driver = appendfile
  home_directory = /var/mail
  file = /var/mail/$local_part
  delivery_date_add
  envelope_to_add
  return_path_add

You may need to

sudo chmod 1777 /var/mail 

if you run into issues with the Apple Mail Server not being able to pick up the mail. You will also need to set up the Apple Mail Server using Server Settings to use another SMTP agent.

Or if you want to do it the old way where Apple Mail Server picked it up from port 627

local_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 Settings application. Click on the Mail Service 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."

Finally you’ll need to create a few log files.

sudo touch /var/log/exim_mainlog
sudo touch /var/log/exim_rejectlog
sudo touch /var/log/exim_rejectlog
sudo chown exim /var/log/exim*

If you want to have the logs rotated then you can add this to your crontab

05 4 * * 6 root sh /usr/exim/bin/exicyclog

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.

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". 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.