The ClamAV Plugin
This plugin submits the entire email to a locally running \[http://www.clamav.net/ Clam AntiVirus\] 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)". Wiki Markup
Code
clamav.cf:
No Format |
---|
loadplugin ClamAV clamav.pm
full CLAMAV eval:check_clamav()
describe CLAMAV Clam AntiVirus detected a virus
score CLAMAV 10
add_header all Virus _CLAMAVRESULT_
|
clamav.pm:
No Format |
---|
package ClamAV; use strict; # version 2.0, 2010-01-07 # - use SA public interface set_tag() and add_header, instead of # pushing a header field directly into $conf->{headers_spam} # our $CLAMD_SOCK = 3310; # for TCP-based usage our $CLAMD_SOCK = "/var/run/clamd.basic/clamd.sock"; # change me use Mail::SpamAssassin; use Mail::SpamAssassin::Plugin; use Mail::SpamAssassin::Logger; 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$pms, $fulltext) = @_; dbg("ClamAV: invoking File::Scan::ClamAV, port/socket: %s", $CLAMD_SOCK); my $clamav = new File::Scan::ClamAV(port => 3310$CLAMD_SOCK); 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; }# elseinclude { the virus name in Mail::SpamAssassin::Plugin::dbg("ClamAV: Error, unknown return code: $code");SpamAssassin's report $pms->test_log($virus); } else { $header = "Error (Unknown return code from ClamAV: $code)"; } $permsgstatus->{main}->{conf}->{headers_spam}->{"Virus"} = $headerdbg("ClamAV: result - $header"); $permsgstatus->{main}->{conf}->{headers_ham}->{"Virus"} = $header$pms->set_tag('CLAMAVRESULT', $header); # add a metadatum so that rules can match against the result too $permsgstatus$pms->{msg}->put_metadata('X-Spam-Virus',$header); return $isspam; } 1; |
How To Use It
...
First of all, you need to install \[http://www.clamav.net/ ClamAV\] and ensure that scanning a mail with *clamscan* works. During your initial setup you will need to set up ClamAV to use an IP port (3310) not a unix port (the default method by ClamAV)
Second, you need to install the \[http://search.cpan.org/~cfaber/File-Scan-ClamAV/lib/File/Scan/ClamAV.pm File::Scan::ClamAV\] perl module. Wiki Markup
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. You should edit the clamav.pm file and change the setting for '$CLAMD_SOCK' to match where your ClamAV installation has put its named pipe.
Restart the spamd daemon if you're using that, and you should be all set.
...
To get a different score based on virus type, see ClamAVMultipleScores.
Caveats
Some find this plugin very useful. However \[http://bugzilla.spamassassin.org/show_bug.cgi?id=2408 others do have a different opinion\] of the safety or logic of such a plugin that you should probably read -- [– AndrewFerrier] Wiki Markup
actually, having a plugin that does this, rather than building support directly into the core, is exactly what the "others" in question preferred . So this is good – JustinMason
Very true I have to say my experiences with this plugin so far have been very promising, I can recommend it to anyone suffering from the increasingly blurred distinction between spam and viruses. – AndrewFerrierCategorySoftware