Exim 4.10 as an SMTP agent for Mac OS X Server
24 June 2002 — Updated 22 August 2002
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 2: Finishing up the Exim install and getting SpamAssassin up and running
By now you have Exim up and running, for the most part. Now the fun really begins. SpamAssassin checks every incoming e-mail against a list of criteria to determine if it is spam or not. While it comes with a very extensive list of checks, you are free to add your own to the list. After determining an e-mail to be spam, SpamAssassin doesn’t do anything with the message—it just marks it as spam and moves on to the next one—so we are going to get Exim to bounce the e-mail back to the sender with a message that lets them know how to get around this if they need to. This is probably being way too nice, but you can modify this to best suit your needs.
First we need to download and install SpamAssassin. There are a number of ways to do this, but this is the method that worked best for me. SpamAssassin needs a perl module, so we are going to install that first. To make it even easier we will install it from CPAN, using the command below:
sudo perl -MCPAN -e shell
At the cpan> prompt, type
install Net::DNS
to install the necessary module. When it is finished, you are ready to move on to SpamAssassin. SpamAssassin is now a CPAN module; install it with the command
install Mail::SpamAssassin
When it is finished, use the quit command to leave the CPAN shell.
I urge you at this point to peruse the documentation to get a better feel for what it does. Having said that, however, SpamAssassin works quite well with just a standard configuration.
Now you need to add some pieces to the Exim configure file. The first bit is a router that directs all mail through the SpamAssassin filter. Put this in the routers section of the configure file. The order matters on this: it should go right before the localuser router that actually delivers the mail.
# Spam Assassin
spamcheck_router:
no_verify
check_local_user
# When to scan a message :
# - it isn’t already flagged as spam
# - it isn’t already scanned
condition = “${if and { {!def:h_X-Spam-Flag:} {!eq {$received_protocol}{spam-scanned}}}{1}{0}}"
driver = accept
transport = spamcheck
Now you need to add in the transport that this router uses. Add the following text to the transports section, right after the routers section, in the config file. Unlike the router, the order doesn’t matter on this one. You should make sure that the user and group settings reference the user and group you used when setting up Exim. If you followed the first article of this series, both the user and group should be “exim."
# Spam Assassin spamcheck: driver = pipe command = /usr/exim/bin/exim -oMr spam-scanned -bS use_bsmtp = true transport_filter = /usr/bin/spamc home_directory = “/tmp" current_directory = “/tmp" # must use a privileged user to set $received_protocol on the way back in! user = exim group = exim log_output = true return_fail_output = true return_path_add = false message_prefix = message_suffix =
Now you should be ready to test SpamAssassin out to see if it works. First, start up the SpamAssassin process:
sudo spamd -i0 -d -x
Now get Exim up and running and run some mail through it. Spam won’t be refused (we haven’t put that in yet) but all mail will be marked as to whether SpamAssassin thought it was spam or not and why. You can see SpamAssassin’s tagging by showing all Internet headers in your mail client.
If all is working as you think it should, it’s time to actually block spam. To do this we will be using an Exim system-wide filter. Paste the following into a text file called spamfilter in /usr/exim/.
# Exim Filter if first_delivery and $h_X-Spam-Flag: contains “YES" then logfile /var/log/exim_spamlog logwrite “$tod_log From: $h_From: Subject: $h_Subject: \n \t X-Spam-Status:$h_X-Spam-Status: Sender: $sender_address" if $h_From: is not “" then fail “<<spam filter>> Your message has been rejected because it appears
to be spam. If this is not the case, please append nospam- to the beginning of
the e-mail address and send again. For example, bobjones@example.com would
become nospam-bobjones@example.com" endif seen finish endif
You can edit the text that comes after <<spam filter>> to be whatever you want. I’ve set up this configuration to allow senders to resend the message with “nospam-” at the beginning of the address and bypass the spam checks. Again, this is being exceptionally nice and probably isn’t necessary, so remove that language if you want.
Now add these two lines to the end the first section of the Exim configure file.
system_filter = /usr/exim/spamfilter system_filter_user = eximAgain: change the user to the one you assigned to Exim. To finish up the configuration, you will want to add another router, before your spamassassin router, to allow mail with the “nospam-” prefix to bypass the spam checks. If you use the University of Washington IMAP server, or another POP/IMAP server that stores user e-mail in a flat file, add the following in before the spamassassin router in the routers section of the configure file.
# nospam- router to absolutely get an e-mail in real_localuser: local_part_prefix = nospam- check_local_user transport = local_delivery driver = accept
If you use Apple Mail Service for your e-mail, include the following lines instead:
# nospam- router to absolutely get an e-mail in real_localuser: driver = redirect local_part_prefix = nospam- check_local_user data = $local_part@yourdomainhere redirect_router = localuser
Make sure you swap your actual domain for yourdomainhere. This should keep everything groovy with Apple Mail Service.
Lastly, we need to get the whitelists setup. These setup any e-mail address that has sent you three non-spam e-mails to longer be checked. This dramatically reduces your processor overhead and keeps down the false positives.
sudo mkdir /var/spam chown exim /var/spam
This assumes, again, that you are running exim under the exim user name, if you aren't, change the last command to the value you are using.
A quick bit of housekeeping to make sure everything is where it needs to be:
sudo touch /var/log/exim_spamlog sudo chown exim /var/log/exim_spamlog
Now you are going to need to edit the global SpamAssassin config file to setup the whitelists functionality. In /usr/share/spamassassin/10_misc.cf, you need to uncomment two last two lines of the snippet below and change the path to /var/spam/whitelist as shown.
# use this for a system-wide whitelist: auto_whitelist_path /var/spam/whitelist auto_whitelist_file_mode 0666
Everything should be in place, so kill spamd if it is running and then start it up with
sudo spamd -d -F0 -a -x
Restart Exim with a SIGHUP (kill -9 on the process ID under which Exim is running) and try it out.
A mail server that I put this one recently had over 450 spam e-mails stopped in one week. About half of the 20 users on the server had reported significant spam problems before SpamAssassin was installed. Now they all say it has been reduced to a trickle or nothing at all. In that first week I only had one report of a false positive, which is arguable since while the sender was not a spammer, they were on a host of blackhole lists since they were an open relay, so SpamAssassin was just doing its job.
A quick note about getting Exim to check queues
Now that you are refusing a significant amount of mail, your outgoing queues are going to fill up a lot faster than before. You should keep an eye on your system to see what load the bounce messages are putting on your machine when you first start up SpamAssassin—not that this is going to bring your machine to the ground, but so you can run the queue at the appropriate time.
To check on your Exim queue, use the command
sudo /usr/exim/bin/exim -bp
To run the queue, use the command
sudo /usr/exim/bin/exim -q
To flush the queue as much as possible, use the command
sudo /usr/exim/bin/exim -qf
Queued items are kept in /var/spool/exim/input. You can manually delete them from here if you like, but you will need to be root, or the Exim user, to access them. Figure out when it is best to run the queue for your system: probably every 30 minutes, on an average Server. You can either set up a cron job to run the queue then, or change the Exim startup item to
/usr/exim/bin/exim -bd -q30m
Also, you will probably want to add a line under that one to launch SpamAssassin at boot:
/usr/bin/spamd -d -a -F0
Now go forth and live a spam-free life.