One of Exim's more interesting features is its built-in filtering
language. It's certainly not a general-purpose programming language,
but for simple mail-filtering tasks it's a hell of a lot easier to use
than (shudder) procmail. It's also easier on your server than spawning
a Python or Perl script, since you don't have to
you don't have to startup a big hairy interpreter. (And you don't have
to write the script and worry about all the niggling little details of
how to handle email.)
One obvious application of Exim's "system filter" feature is to inspect every email message for viruses. The original idea is due to Nigel Metheringham; he created a generic Windows executable content filter and put it on the Exim web site. This is not an all-singing, all-dancing, industrial-strength, super-powered email virus filter. However, it's Good Enough for a lot of people.
I started using Nigel's filter in July 2001, and expanded/improved it over the following months. In particular, I added the following features:
I stopped using this virus filter in June/July of 2002, because
Exim 4 provides a much better solution in the form of its
local_scan() API. I wrote
elspy to let me write
local_scan() functions in Python, and that's how I
do virus detection now. So this page is largely of historical interest.
Without further ado, here is my email virus filter for Exim. You will almost certainly need to edit it as follows before using it on your system:
logfiledirective points to Exim's reject log on your system. The default (/var/log/exim/reject.log) is for a Red Hat Linux system; Debian uses /var/log/exim/rejectlog; if you have built your own Exim, only you know where its reject log is.
savecommand (there's one for each flavour of virus detected) saves messages in a location agreeable to you; the default (/usr/local/var/archives/exim-reject) is a peculiarity of the system where this filter came from, which has lots and lots of disk space in /usr/local, but not much in /var. I prefer to put viruses in, eg., /var/mail/virus-reject .
onceoption refers to a file that Exim can create. This file is used to keep track of who has received virus rejection messages from this filter, so we don't hammer the same person with 20 rejections for 20 copies of the same virus.
Of course, you'll also have to edit Exim's configuation file to enable the filter. For Exim 3.x, you'll need to add the following:
# Virus filtering, using a filter descended from Nigel Metheringham's # filter for rejecting mail that looks like a Windows e-mail virus. message_filter = /etc/exim/system_filter message_body_visible = 5000 # These are needed so we can save, pipe, or send mail from the # system filter. message_filter_file_transport = address_file message_filter_reply_transport = address_reply # Viruses can be big, and it's not really necessary to return # every last byte. return_size_limit = 30kOf course, make sure that
message_filterrefers to where you put the filter. Also, make sure that the two transports --
address_reply-- exist; they should look something like this:
address_file: driver = appendfile # these three options are not necessary, but I like them delivery_date_add envelope_to_add return_path_add address_reply: driver = autoreply
Once you've got virus-filtering working, there are a few things to consider: