Gnuru.org
Productive Linux


Subscribe

 Subscribe via Feedburner in a reader

Enter your email address:

Delivered by FeedBurner


Login
Login:
Password:



Don't have an account?
Sign up to Gnuru.org
Forgot your password?

Spamassassin & Exim 3
5 March 2004 @ 17:27 GMT
by Nomad

Spam is such a problem on the internet, that almost everyone needs a way to deal with it. One common question is how to filter it while it is being handled at smtp time by the mail transport agent.

Exim uses what are called 'transports' to handle messages in its spool. Transports can be defined in any order you like and are called at the appropriate time.

To actually handle messages exim3 (exim4 works slightly differently) uses 'directors' and 'routers'. 'Routers' deal with delivery to other computers, 'directors' to the computer on which exim is running, the localhost. So, it's directors that we're interested in here.

When exim is handling an email that is intended to be delivered locally it will pass it to each director in the order they appear in the exim.conf file. Directors do various things. One director, for example, will alias addresses so that an email addressed to 'webmaster' will end up in the mailbox of a real person.

Directors call on a 'transport' to deal with the message. So to integrate spamassassin with exim we need to to define a transport and a director.

One excellent example of how to get exim and spamassassin can work together is provided by Derrick Hudson here: (http://dman.ddts.net/~dman/config_docs/)

We're going to to look at it the opposite way around then he does, because it makes it understanding what exim does easier. However, they must go into your exim configuration file, exim.conf, in the right order.

Because the order directors go in is important, this one should probably be put in after the director that handles email aliases, that way personal spam preferences can be used.

"spamcheck_director" is the name of the director.

"no_verify" means that this will be skipped if addresses are verified.

The "condition" line says that the director will be skipped if there is a header called X-Spam-Flag, which means it has already been scanned by spamassassin, if there the received header contains with 'spam-scanned', which means it has already been put through the spamcheck transport (see below), or if the email originates locally, as we don't send spam to ourselves.

"Driver = smartuser" means that all mail addressed locally is handled by the director even if they are not an actual user. I have changed this to "Driver = localuser", because mail that is not addressed to an account or exists in the aliases file is bounced and I don't want to waste CPU cycles spam checking it.

"Transport = spamcheck" sets the transport that will be used

Further up in the exim.conf you define the transport which actually calls spamassassin.

"spamcheck:" is the name of the transport.

The lines are as follows:

"driver = pipe" this sets the transport to behave as a pipe, that is email goes in and gets processed by some command.

        command = /usr/sbin/exim -oMr spam-scanned -bS

Here spamassassin spawns a sub-process. This might seem heavyweight, but it is the only way to do it in exim 3.

        transport_filter = /usr/bin/spamc -s60000 -u${local_part}

This tells exim to filter the message by piping it to spamassassin. In the above example, a machine with not enough RAM is used, hence the -s switch is used so that message greater than 60k are not scanned. The -u switch means that a certain user's preferences will be used. Because we're using the exim variable 'local_part' it is important that this transport gets placed after any transports that deal the properly resolving the local users to whom mail is to be delivered.

        bsmtp = all

This instructs exim to use batch processing. This prepares the message to be sent to a non-exim process, i.e. spamassassin.

        home_directory = "/tmp"
        current_directory = "/tmp"

These set the home and current directory for exim when using this director.

        user = mail
        group = mail

Setting the user and group for the exim sub-process.

        return_path_add = false

We don't need a return path since we're processing this ourselves

        log_output = true

This ensures it it is logged properly in whatever file you've set up as the log.

        return_fail_output = true

If this pipe ends in an error - the output is returned in the delivery

        prefix =
        suffix =

This is necessary because we're using batch smtp (see above) and need to ensure there are no prefixes or suffixes to the messages.

Because spam checking can be expensive in terms of processor time one problem that I found and others have reported is that the pipe transport times out. The default is set to 5 minutes. So far I've increased this to 20 minutes by setting the option:

smtp_receive_timeout = 20m

There have been no bounces since.

In summary, in the transport section of your exim.conf put:

spamcheck:

        driver = pipe


        command = /usr/sbin/exim -oMr spam-scanned -bS
        transport_filter = /usr/bin/spamc -s60000 -u${local_part}
        bsmtp = all
        home_directory = "/tmp"
        current_directory = "/tmp"
        user = mail
        group = mail
        return_path_add = false
        log_output = true
        return_fail_output = true
        prefix =
        suffix =

In the directors section put:

spamcheck_director:

        no_verify
        condition = "${if and { {!def:h_X-Spam-Flag:} {!eq {$received_protocol}{spam-scanned}} {!eq {$received_protocol}{local}} }{1}{0}}"
        driver = localuser
        transport = spamcheck
Tags: email exim spam



Comments disabled