Configure Exim with anti-spam

Configure Exim with anti-spam


A few comments on my article The perfect network server in issue 17 requested some more in depth follow-up pieces. This is what I hope to be the first of those. It focuses on Exim, the mail transfer agent (MTA), specifically setting it up with spam scanning. It is based on setups I currently use, hosted on Debian GNU/Linux.

This is an intermediate article, I'm going to assume you are familiar with mail delivery technologies and terminology. If you don't know what SMTP, MX records and reverse DNS lookups are, you might like to do a little background reading before coming back to this article. I'll try to stick to a descriptive narrative style but some of it will inevitably involve technical language.

What Exim is not

Exim is a mail transfer agent. It receives messages, usually by SMTP, figures out what to do with them according to its configuration and transfers them to another location based on that information. The new location may be a locally based mailbox, another server or another daemon running on the same box.

Exim does not do POP3, IMAP, shared calendars or make the tea

It does not deliver mail to client machines, and does not handle mail user agent message creation functionality. In short, Exim does SMTP and related stuff. It does not do POP3, IMAP[1], LDAP, shared calendars or make the tea. It's important to note that Exim is not capable of pulling mail: it expects all messages to be delivered to it [2].

Debian Exim packages

Debian has a few packages for Exim. At the time of writing the current major version is 4. The key packages to install are exim4-base, exim4-config and one of the two exim4-daemon-? packages. If you are installing a brand new server, then you can install Exim as a task during the Debian installation stage (see The perfect network server for information on that). If you already have a Debian server then you can install it using tasksel install mail-server or with your favourite package manager.

The two Exim4 daemon packages within Debian called exim4-daemon-light and exim4-daemon-heavy. Installing either will install the exim4-base package as a dependency but not exim4-config. So, you should install exim4-config as well as it comes in handy.

The light daemon package is a perfectly adequate Exim install but leaves out things like SQL data lookups, virus/spam scanning integration and Secure Password Authentication SMTP. All of those are included in the "heavy" daemon and, as you'll want to do spam scanning, you'll need it. Note that tasksel, and thus the Debian installer, will install exim4-daemon-light but you can replace it simply by installing the heavy package afterwards. So, after all that, apt-get install exim4-daemon-heavy exim4-config does the trick.

Exim initial configuration

I'm not aware of any GUI tools to configure Exim, beyond address and account management. I started a fairly long debate on the necessity of server GUIs in the last article, but as they say, "write what you know"... so I'll stick to configuring Exim via the shell.

Having installed exim4-config, you might as well put it to good use

Having installed exim4-config, you might as well put it to good use. To use exim-config, run (either as root or sudo) the command dpkg-reconfigure exim4-config. I won't detail every step of this because each has decent explanatory text within--and I'd take up most of the article installing Exim. Here are a few pointers on the latter steps.

The debconf way to set-up EximThe debconf way to set-up Exim

Mailbox format

The Exim local_delivery transport is used to deliver messages to local mailboxes. By default that is in mbox format. There is an option to use the popular Maildir format, which you can set here. I prefer Maildir, so I choose to use it here. For a discussion on which is best I suggest you put your flame-proof suit on and hit Google or add a comment. Briefly, mbox stores all messages in a single text file. Maildir stores each message as an individual file within sub-directories of your main maildir. An advantage of Maildir is that it doesn't require file locking, so there are fewer delays.

Single or multiple config files

The next step is, as far as I know, unique to Debian (and its derivatives). You can choose to have the various routers and transports within separate config files or all lumped in one file. The former is the more usual Debian way of doing things, the latter is more common outside of the Debian world view. If you have experience of Exim on other distributions then go for the latter, otherwise the former may help you find things better. Both types will contain the same configuration options--just in different files. I have used mutiple files and refer to them here. If you choose a single file then all your configuration options will be found in /etc/exim4/exim4.conf.

SpamAssassin

The automatically generated configuration will create a perfectly usable Exim server: any local user will be able to have mail delivered to their mailbox by Exim ready for to be picked up. What it won't do as yet is any spam scanning. I'll look at spam scanning now. The traditional anti-spam approach for GNU/Linux is SpamAssassin. What's good is that v4.50 Exim has a built-in interface for SpamAssassin. This was formerly the exiscan_acl plugin.

SpamAssassin requires you to enable it before it will run

Once installed (e.g. apt-get install spamassassin), SpamAssassin requires you to enable it before it will run. Edit /etc/default/spamassassin and set ENABLE = 1. You can also have SpamAssassin's rules updated on a nightly basis by setting CRON = 1 in the same file. Once you've done that, you can start the spamd daemon with /etc/init.d/spamassassin start.

There are plenty of good SpamAssassin resources on the web. Including this wikiThere are plenty of good SpamAssassin resources on the web. Including this wiki

By default SpamAssassin listens on port 783. If you install exim4-daemon-heavy, Exim will be already set to look for it on that port. If your SpamAssassin listens on a different port you should change the setting in /etc/exim4/conf.d/main/02_exim4-config_options accordingly.

Access Control Lists (ACLs)

You need to tell Exim how and when to use SpamAssassin. This can be done either in a router (which is run on messages after they've been received), or within an Access Control List (ACL). I'll do it within an ACL. ACLs are run against messages during SMTP sessions. Exim usually runs an ACL during the SMTP RCPT command and one after DATA command. Spam checking is generally made on the body, so you need to edit the latter ACL. This assumes SpamAssassin is installed and running. The settings we need to change are within the /etc/exim4/conf.d/acl/40_exim4-config_check_data. Uncomment and amend the default setting as follows:

  warn
     spam = Debian-exim
     condition = ${if <{$message_size}{100k}{1}{0}}
     message = X-Spam_score: $spam_score\n\
               X-Spam_score_int: $spam_score_int\n\
               X-Spam_bar: $spam_bar\n\
               X-Spam_report: $spam_report

This ACL runs every message below 100k in size through SpamAssassin as it is received. The 100k limit eases the server load by not checking larger messages with attachments that are more likely to contain malware than spam. The ACL adds some additional headers to the message defining the spam "score". I will use these in filters later.

Rejecting suspect spam

This configuration will warn you about problems, but will still relay suspicious messages. Why not deny relaying to them? It's certainly possible to have the ACL reject messages above a certain threshold. I'm not sure that this is necessarily a good idea though.

SpamAssassin is good at its job but it will produce false positives

SpamAssassin is good at what it does but it will produce false positives. In particular I've found badly written and configured HTML e-mail newsletters to be an issue. Whilst it's tempting to shut out such messages, it may not be practical for your users. It is perhaps better to accept the message with an additional header and act upon that later. To do that in Exim you use filters.

Filtering messages

Many clients allow you to setup a filter to detect and examine a header. You could, for example, set a client-filter to check the X-Spam-Score header for a value above 9.9 and dump any messages that match directly in the client's trash or a separate spam folder. Your users may feel slightly better for not seeing higher scoring messages though. Even when client-side filters work, many have found that reducing the amount of delivered spam goes down well with users.

Exim has an extensive filtering system which can be used by individual users on messages delivered to them or globally on all messages relayed by the server. The latter is a system filter and you can have one per Exim installation. Specify the location of your system filter within any of the main config files. I put mine at the top of the /etc/exim4/conf.d/main/02_exim4-config_options. Add something similar to this:

system_filter = "/etc/exim4/system.filter"
system_filter_user = Debian-exim
system_filter_group = Debian-exim
system_filter_pipe_transport = address_pipe
system_filter_file_transport = address_file
system_filter_reply_transport = address_reply

The filter itself is a series of conditions and resulting actions. Here's a sample condition for a system filter:

if $h_X-Spam_score_int is above 99 
    and foranyaddress $recipients ($thisaddress contains "@mydomain.com")
    save /var/mail/suspect_spam
    mail to $thisaddress
    subject "[ SPAM Witheld ] $h_subject:"
    from "Company Mail Server <no-reply@mydomain.com>"
    text "This Message is sent automatically by e-mail software, please do not
    reply to it\n\nThe server suspects that a message sent to you by $h_From: 
    is spam. It scored : $h_X-Spam_score: .\n The spam report is:\n 
    $h_X-Spam-report: \n.\nThe original message has not been sent to you, but
    stored on the server.\n If you were expecting it, please contact your system
    administrator with the reference\n $message_id
finish endif

The second line will loop through all the recipient (To, CC, BCC) addresses for one that contains mydomain.com. This is done to ensure we only run this on inbound messages. Once matched, it appends the original message into a local file and sends a notification to the intended recipient, rewriting the subject. Note the use of the other additional headers in the notification text.

Now you need to handle messages scoring between 4.9 and 9.9. You can do this with another condition which rewrites the Subject header.

if $h_X-Spam_score_int is below 99 
    and $h_X-Spam_score_int is above 49
    and foranyaddress $recipients ($thisaddress contains "@mydomain.com")
    then
    headers add OldSubject "$h_Subject"
    headers remove "Subject"
    headers add Subject "[ SPAM ] $h_OldSubject
    headers remove "OldSubject"
finish endif

Header manipulation happens on-the-fly in Exim filters; so you needed to save the existing subject before using it in the new one.

Final words

Exim is a little like chess: straightforward to learn, a lifetime to master. SpamAssassin is really the same , so coming up with a comprehensive guide article that covers all questions is almost impossible. What I have tried to do is give some introductory guidance on configuring both on Debian GNU/Linux. Think of it as whetting your appetite. If you are looking to deploy an Exim server with SpamAssassin and other features I've not had room to mention, such as virtual users, virus and malware scanning etc. I would suggest you do some more reading before you start. The Exim website has comprehensive documentation but is perhaps not best suited to the beginner. A better place to start will be http://www.exim-new-users.co.uk.

Bibliography

[1] Have a look at something like Courier IMAP,Cyrus, Qpopper et al for POP3 or IMAP servers.

[2] Try fetchmail for something that pulls mail from another server and feeds it into Exim for local delivery. The two work very well together.

Category: 
License: 

Comments

bignellrp's picture
Submitted by bignellrp on

Can i use the above as a global spam filter for virtual mysql users?

E.G

# Exim filter
if $h_subject: contains "{SPAM?}"
then
save /var/mail/${domain}/${local_part}/.Junk\ E-mail/cur/
finish
endif

...to work with my transport below.

local_mysql_delivery:
driver = appendfile
directory = /var/mail/${domain}/${local_part}/
maildir_format
delivery_date_add
envelope_to_add
return_path_add
user = mail
group = mail
mode = 0660

Ryan Cartwright's picture

In Exim a global filter (one that is applied to every inbound message) is called a system filter. The one you've shown above would work if placed in a system filter file and you called it using the system filter directive as shown on page 3 of my article. (It would also work if placed in a .forward file but then only for that one user).

As your filter checks the domain and local_part of the recipient envelope (calculated from the "To:" header of the message), the fact that the account is a virtual one is irrelevant. The transport is irrelevant too as the save command won't use it. It uses the appendfile driver but independently of the transport.

A couple of things about your filter though. It will save any message with that string in the subject into the junk folder. This includes ones that perhaps got inadvertently flagged by some other companies' mail system (with the same string) and they've since replied to you. In my expereince it's better to add a header to indicate that your server thinks it's spam and detect that, rather than do your detection on an arbitrary string in the subject. This is what I do in the article, it's just the resulting action that differs.

Secondly you'll probably confuse matter saving to the "cur" folder below .Junk\ Email as it'll show up as a directory in the user's mail folders. If this is an Imap store then I'd save it to ".Junk\ Email/" and be done with it. If it's POP then don't even bother saving it to t separate folder if you want the user to see it, let the POP client do that bit.

Hope this helps

Ryan

Equitas IT Solutions - fairness, quality, freedom http://www.equitasit.co.uk

bignellrp's picture
Submitted by bignellrp on

That does help explain things. But at the moment:

# Exim filter
if $h_subject: contains "{SPAM?}"
then
save /var/mail/${domain}/${local_part}/.Junk\ E-mail/
finish
endif

doesnt work. Firstly it complained at the space between .Junk\ Email

then when i changed to .Junk it didnt seem to do anything with this spam mail. Could it be that my spamassassin isnt tagging the mail until after my system_filter is called? Or am i doing something else wrong?

Most forwarded

Interview with Dave Mohyla, of DTIDATA

Dave Mohyla is the president and founder of dtidata.com, a hard drive recovery facility based in Tampa, Florida.

TM: Where are you based? What does your company do?
DTI Data recovery is based in South Pasadena, Florida which is a suburb of Tampa. We have been here for over 10 years. We operate a bio-metrically secured class 100 clean room where we perform hard drive recovery on all types of hard disks, from laptop hard drives to multi drive RAID systems.

Anybody up to writing good directory software?

Since the very beginning, directories (of any kind) have had a very central role in the internet. (I have recently grown fond of Free Web Directory. Even Slashdot can be considered a directory: a collection of great news and invaluable user-generated comments. As far as software is concerned, doing a quick search on Google about software directories will return the free (as in freedom) software directories like Savannah, SourceForge, Freshmeat and so on, followed by shareware and freeware sites such as FileBuzz, PCWin Download Center and All Freeware (great if you're looking for shareware and freeware, but definitely less comprehensive than their free-as-in-freedom counterparts).

Interview with Mark Shuttleworth

Mark Shuttleworth is the founder of Thawte, the first Certification Authority to sell public SSL certificates. After selling Thawte to Verisign, Mark moved on to training as an astronaut in Russia and visiting space. Once he got back he founded Ubuntu, the leading GNU/Linux distribution. He agreed on releasing a quick interview to Free Software Magazine.

Is better education the key to finding better software?

I read David Jonathon's article Anybody Up To Writing Good Directory Software? the other day, which got me thinking about software directories in general. As David mentioned, many of the software directories one finds when doing a quick google search are free as in beer, not as in freedom. But what interests me is the software directories that already exist, providing a combination of both free as in beer software, and open source software. Sites such as Freeware Downloads and Shareware Download don't advertise themselves as providing free as in liberty software, but each of them have a good selection of open source software available... if you know where to look.

Most emailed

Free Open Document label templates

If you’ve ever spent hours at work doing mailings, cursed your printer for printing outside the lines on your labels, or moaned “There has got to be a better way to do this,” here’s the solution you’ve been looking for. Working smarter, not harder! Worldlabel.com, a manufacture of labels offers Open Office / Libre Office labels templates for downloading in ODF format which will save you time, effort, and (if you want) make really cool-looking labels

Creating a user-centric site in Drupal

A little while ago, while talking in the #drupal mailing list, I showed my latest creation to one of the core developers there. His reaction was "Wow, I am always surprised what people use Drupal for". His surprise is somehow justified: I did create a site for a bunch of entertainers in Perth, a company set to use Drupal to take over the world with Entertainers.Biz.

Update: since writing this article, I have updated the system so that the whole booking process happens online. I will update the article accordingly!

So, why, why do people and companies develop free software?

More and more people are discovering free software. Many people only do so after weeks, or even months, of using it. I wonder, for example, how many Firefox users actually know how free Firefox really is—many of them realise that you can get it for free, but find it hard to believe that anybody can modify it and even redistribute it legally.

When the discovery is made, the first instinct is to ask: why do they do it? Programming is hard work. Even though most (if not all) programmers are driven by their higher-than-normal IQs and their amazing passion for solving problems, it’s still hard to understand why so many of them would donate so much of their time to creating something that they can’t really show off to anybody but their colleagues or geek friends.

Sure, anybody can buy laptops, and just program. No need to get a full-on lab or spend thousands of dollars in equipment. But... is that the full story?

Fun articles

Santa Claus - the most successful open source project

It dawned on me the other day, as I was shopping for the dozens of gifts it seems I have to buy every December, that Santa Claus is the most successful open source project in history. (Bridget @ Illiterarty would agree with that). Santa Claus is essentially a marketing development that is embodied by everyone who stuffs a sock, gives a gift, hosts a dinner or wishes Merry Christmas over the holiday season.

Most emailed

Editorial

When I first started thinking about Free Software Magazine, I was feeling enthusiastic about the dream. I had Dave, Gianluca, and Alan willing to help me, I had established members of the free software community willing to help me out, I had writers volunteering their time and energy for free, and I had a generous offer from OpenHosting for servers, all before I'd proved myself. There was a sense of excitement in the air, and I thought maybe, just maybe, I could make this work.

Free Software Magazine uses Apollo project management software and CRM for its everyday activities!