Attention: open in a new window. PDFPrint

Yet another mail filtering article

Why such a tutorial again?

Well… I know that there are tons of tutorials out there, how you get mail filtering running on your mailserver using courier imap, maildrop, spamassassin and clamav. So this might look like an other: "Hey, look, I've got it running post...".

I do not want to reeplain, how to configure spamassassin or clamav or something like this. I just want to show you in a brief article, how you can call spamassassin and clamav directly from a maildrop script. My problem with most of the solutions out there has been, that I use a mysql database for account management and vmail on my server which allows transport daemon selection per domain or account. So it is no option for me to use spamassassin before maildrop in the mail handling queue. An other reason most descriptions did not fit is, that I did not want to change my mailservers configuration ("never touch a running system"). So just updating the filter script was the easiest option for me.

 

Prerequisites

I assume that you have a running maildrop installation and that you know, how to write simple maildrop filter roules or at least know, where you have to put your rules you want to use with maildrop.

Installing the packages

First, make sure you installed and configured spamassassin. Using debian or ubuntu or systems like this you might try:

apt-get update ; apt-get upgrade
apt-get install spamassassin

Afterwards you might change your spamassassin configuration on your needs or leave them as they are. One little thing you need to do on mostly all debian based systems is, setting ENABLED=1 in /etc/default/spamassassin. Otherwise debian will not start spamassasin. Afterwards, just run

/etc/init.d/spamassassin restart

To make sure that spamassassin has been started.

For virus checking, I use clamassassin as it reads the mail from a pipe and adds a virus header to the stream. So I installed clamav using

apt-get install clamav clamassassin

Email tagging

As I wanted to tag mail mail subject, I also added a small bash-script to /sbin/tagmailsubject:

#!/bin/bash
TAG=$1
awk "/^Subject:.*/ && c++==0 {\$2=\"$TAG \" \$2; print; next} {print}"

This does nothing other than searching for the first line starting with Subject: and adding the String supplied by the first parameter to the subjects text.

You can also write the awk-line into your mailfilter-file but it would look very ugly.

Putting it all together

As I told you above, I am using a virtual mail solution which means, that I use a vmail-user that owns all mail directories. That user has it own mailfilter file that is applied on all virtual mail users. This file imports the user specific configurations like forwardings and so on. To attach the spam and virus checking, I changed the global configuration to force mail checking for all users. So this are the changing I placed into my configuration file found at /home/vmail/.mailfilter:

# call virus check
exception {
  include "$HOME/mailfilters/antivir"
} # call antispam
exception {
  include "$HOME/mailfilters/antispam"
}

The first block includes the anti virus checking rules, the second one includes the spam checking rules placed. As you can see, both files are placed in /home/vmail/mailfilters and are named antivir and antispam. So this does my antivir file look like:

xfilter "/usr/bin/clamassassin"

# viruscheck
if (/^X-Virus-Status: *No/)
{
  echo "virus check: ok"
  xfilter "/sbin/tagmailsubject \"(virus checked)\""
}
else
{
  echo "virus check: failed"
  EXIT
}

The filter calls clamassassin and pipe the nessage through it. xfilter forces maildrop to use the result of the pipe output as current mail. Clamassassin adds some header tags to the mail. One is X-Virus-Status: No, if the mail does not contain any virus. So, the script checks, if clamassassin marked the message as clean. If it is clean, it attaches (virus checked) to the subject and continues with mail filtering, otherwise, the mail is dropped by the EXIT statement, which means, that the mail is rejected and not delivered anywhere. You might check this against some

xfilter "/sbin/tagmailsubject \"(infected)\""

if you want to keep the mail and not reject it.

So lets take a look on my antispam file:

xfilter "/usr/bin/spamc"

# spamcheck
if (/^X-Spam-Level: *\*\*\*\*\*.*$/)
{
  echo "SPAMLEVEL: high"
  cc "|/usr/bin/sa-learn --single --spam"
  xfilter "/sbin/tagmailsubject \"*** HIGH SPAMLEVEL ***\""
}
else
{
  if (/^X-Spam-Level: *\*\*\*.*$/)
  {
    echo "SPAMLEVEL: medium"
    xfilter "/sbin/tagmailsubject \"*** MEDIUM SPAMLEVEL ***\""
  }
  else
  {
    if (/^X-Spam-Level: *\*.*$/)
    {
      echo "SPAMLEVEL: low"
    }
    else
    {
      echo "SPAMLEVEL: zero"
      cc "|/usr/bin/sa-learn --single --ham"
    }
  }
}

This is mostly the same like the antivir-file. I use xfilter to pass my mail through spamassassin and then check the spam level. If the spamlevel is *****, the mail is marked with *** HIGH SPAMLEVEL *** and used for spamassassin training (cc-line). If the spamlevel is *** the mail is marked as *** MEDIUM SPAMLEVEL ***. If the spamlevel is empty, it is used for non-spam training and kept as it is.

After doing this procedure you can perform any other mail checking on the spam and virus checked mail you like. The next I do is including the user specific filter rules using the following lines in my /home/vmail/.mailfilter-file:

# call user filters
exception {
  `touch "$HOME/mailfilters/$LOGNAME"`
  include "$HOME/mailfilters/$LOGNAME"
}

The script includes the users file in /home/vmail/mailfilters/[user login] and performs further checking.

Feel free to experiment with the options above to create a spam and virus filter on your own needs.