Friday, December 28, 2007

Getting SpamAssassin's spamc to work with Qmail

One of the recommended ways of setting up SpamAssassin to work with Qmail is to move the binary "qmail-queue" to a different name, say qmail-queue.orig, then create a shell script named qmail-queue which passes the email through SpamAssassin then on to the original qmail-queue. 

One problem with that set up which I've been noticing is that it passes every email through the spam filter, even though the vast majority of email coming into the server is addressed to non-existent users. The time taken to scan all those emails was noticeably slowing down the system. 

So what I really wanted to do was call the spam filter from the .qmail files for real users. 

Qmail's default delivery mechanism, set to contain just "#" in .qmail-default, will then drop all emails sent to non-existent users without calling SpamAssassin. 

I wanted to use the spamc utility, written in C, as a filter to call the already running spamd deamon from the user's spamc with the "-c" switch so that non-spam messages will return 0 (zero)  and thus pass on to delivery. One small problem, though, is that the exit value for an email determined to be spam is 1. Qmail will interpret an exit value of 1 as a temporary failure and keep trying to deliver the message. This will create a backlog of undelivered messages and slow down the email server. 

To get around this, I changed the exit value for spam emails in spamc. First I downloaded the latest SpamAssassin and untarred the download file. In the "spamc" subfolder I found a file named "libspamc.h". On or around line 85 is the line:

#define EX_ISSPAM   1

I simply changed this to 

#define EX_ISSPAM   99

and then completed the installation steps:

perl Makefile.PL
make
sudo make install

which installed SpamAssasissin including spamc with the altered exit value.

Lastly, from my user .qmail files, I call spamc. For example for .qmail-devin:

|/usr/local/bin/spamc -c
./devin/Maildir/

and now SpamAssassin is run only for email coming to real users and all messages determined to be spam are silently dropped. The return value of 99 tells Qmail that the message has been completely processed and no further delivery steps need be taken. 


No comments: