Penguin
Note: You are viewing an old revision of this page. View the current version.

SpamAssassin is a neat mail filter that tags incoming mails it thinks are spam. It can be set up to be a bit nastier about this, but the default is good enough.

You can use procmail(1) to run SpamAssassin, or you might want to use MailScanner to run it on all your incoming mail. You might even want to plug VipulsRazor into it.

Its homepage can be found here.

SpamAssassin is written in Perl and is licensed under the same license as Perl itself.

(Note, this product will assassinate Spam, but will leave SPAM well alone!)


How to make SpamAssassin run on your local e-mail machine (with Evolution in mind)

  • get and install SpamAssassin, test that it works by piping a good email and a spam email through it
  • check that fetchmail(1) works, write a .fetchmailrc file
  • check that procmail(1) works, write a .procmailrc file
  • disable the regular pop mailboxes in Evolution
  • add a new "local delivery" mailbox to Evolution
  • write a tiny script I called "getmail" that does "fetchmail -m procmail" and make sure that it gets your email from the POP3 server correctly
  • add getmail to your crontab to run every 5 minutes
  • add a filter rule to Evolution: if specific header X-Spam-Flag = YES, drop the email in my Spam folder
.fetchmailrc

poll mail.myisp.co.nz protocol POP3

user "pop3user" password "secret" is user "localuser" here mda "/usr/bin/procmail";

.procmailrc

:0 fhw | formail -I "From " -a "From "

:0fw | spamassassin

Note: older versions of spamassassin needed a "-P" option to tell it to read from a pipe, but that is now the default. The formail line corrects incoming messages for programs like evolution and mail by readding the From line.

/bin/getmail
  1. /bin/bash

/usr/bin/fetchmail >> /log/fetchmail

crontab
  • /5 * * * * /home/localuser/bin/getmail

The ClamAV Plugin

This plugin submits the entire email to a locally running ClamAV server for virus detection. If a virus is found, it returns a positive return code to indicate spam and sets the header "X-Spam-Virus: Yes ($virusname)".

Code


clamav.cf

loadplugin ClamAV clamav.pm full CLAMAV eval:check_clamav() describe CLAMAV Clam AntiVirus detected a virus score CLAMAV 10


clamav.pm

package !ClamAV; use strict; use Mail::!SpamAssassin; use Mail::!SpamAssassin::Plugin; use File::Scan::!ClamAV; our @ISA = qw(Mail::!SpamAssassin::Plugin);

sub new {

my ($class, $mailsa) = @_; $class = ref($class) || $class; my $self = $class->SUPER::new($mailsa); bless ($self, $class); $self->register_eval_rule ("check_clamav"); return $self;

}

sub check_clamav {

my ($self, $permsgstatus, $fulltext) = @_; my $clamav = new File::Scan::!ClamAV(port => 3310); my ($code, $virus) = $clamav->streamscan(${$fulltext}); my $isspam = 0; my $header = ""; if(!$code) {

my $errstr = $clamav->errstr(); Mail::!SpamAssassin::Plugin::dbg("ClamAV: Error scanning: $errstr"); $header = "Error ($errstr)";

} elsif($code eq 'OK') {

Mail::!SpamAssassin::Plugin::dbg("ClamAV: No virus detected"); $header = "No";

} elsif($code eq 'FOUND') {

Mail::!SpamAssassin::Plugin::dbg("ClamAV: Detected virus: $virus"); $header = "Yes ($virus)"; $isspam = 1;

} else {

Mail::!SpamAssassin::Plugin::dbg("ClamAV: Error, unknown return code: $code"); $header = "Error (Unknown return code from ClamAV: $code)";

} $permsgstatus->{main}->{conf}->{headers_spam}->{"Virus"} = $header; $permsgstatus->{main}->{conf}->{headers_ham}->{"Virus"} = $header; return $isspam;

} 1;


How To Use It

First of all, you need to install ClamAV and ensure that scanning a mail with 'clamscan' works.

Second, you need to install the File::Scan::ClamAV perl module.

Finally, save the two files above into the /etc/mail/spamassassin/ directory. You can adjust the default score of 10 in 'clamav.cf' if you like. Restart the spamd daemon if you're using that, and you should be all set.

If you'd like to sort virus emails to a separate folder, create a rule looking for the "X-Spam-Virus: Yes" header.