Virus scanning
This article outlines how to setup virus scanning using
AMaViS (A Mail Virus Scanner),
ClamAV, and Postfix.
The actions describe below are particular to a FreeBSD system and are applicable to other operating
systems by altering the path to the configuration files, and adjusting for other OS-specific issues.
What? Virus scanning on non-windows? Well, yes. My mail server happens to be running FreeBSD.
It also happens to have many clients which are running Windows. Let’s just stop the viruses before
they get past my mail servers. Thank you. 🙂
This article is written as a reminder to me for the next time I configure
virus scanning with amavisd. It is very high level.
Installation
The two main things I install are clamav and amavis. I have
written about Postfix previously. This
article concentrates on amavis and clamav. Clamav is a virus scanner used by amavis. Both run as daemons.
Postfix can be configured to use a content scanner and pass the email it receives to amavis for validation.
In turn, amavis contacts clamav to inspect the email.
To install the clamav, issue the following command:
cd /usr/ports/security/clamav make install clean
Similarly, for amavis, I did this:
cd /usr/ports/security/amavisd-new make install clean
I used the default configuration settings for both ports.
Allowing things to run
The following configuration items in /etc/rc.conf allow the daemons to run:
clamav_clamd_enable="YES" clamav_freshclam_enable="YES" amavisd_enable="YES" amavisd_ram="512m" # Optionally enable amavisd tmp ram disk with: (example 512k)
Permissions and groups
I added clamav to the vscan group by editing /etc/group. The following
output shows what to expect. If your results differ, there is something
wrong (assumimg you’re running on FreeBSD 6.2 or similar).
# id clamav uid=106(clamav) gid=106(clamav) groups=106(clamav),6(mail),110(vscan) # id vscan uid=110(vscan) gid=110(vscan) groups=110(vscan)
amavis configuration
In /usr/local/etc/amavisd.conf, change the values for these settings:
$mydomain $myhostname
Search through the file for those settings and adjust them as appropriate for your environment.
Starting things up
To start the daemons, issue these commands:
/usr/local/etc/rc.d/clamav-freshclam start /usr/local/etc/rc.d/clamav-clamd start /usr/local/etc/rc.d/amavisd start
After starting amavis, should see something like this in /var/log/messages:
starting. /usr/local/sbin/amavisd at nyi.example.org amavisd-new-2.5.2 (20070627), Unicode aware Perl version 5.008008 Module Amavis::Conf 2.091 Module Archive::Zip 1.20 Module BerkeleyDB 0.31 Module Compress::Zlib 2.005 Module Convert::TNEF 0.17 Module Convert::UUlib 1.09 Module DBD::Pg 1.49 Module DBI 1.52 Module DB_File 1.814 Module Digest::MD5 2.36 Module Digest::SHA1 2.11 Module IO::Socket::INET6 2.51 Module MIME::Entity 5.420 Module MIME::Parser 5.420 Module MIME::Tools 5.420 Module Mail::Header 1.74 Module Mail::Internet 1.74 Module Mail::SpamAssassin 3.002001 Module Net::DNS 0.60 Module Net::Server 0.96 Module Razor2::Client::Version 2.84 Module Time::HiRes 1.9707 Module URI 1.35 Module Unix::Syslog 0.100 Amavis::DB code loaded Amavis::Cache code loaded SQL base code NOT loaded SQL::Log code NOT loaded SQL::Quarantine NOT loaded Lookup::SQL code NOT loaded Lookup::LDAP code NOT loaded AM.PDP-in proto code loaded SMTP-in proto code loaded Courier proto code NOT loaded SMTP-out proto code loaded Pipe-out proto code NOT loaded BSMTP-out proto code NOT loaded Local-out proto code loaded OS_Fingerprint code NOT loaded ANTI-VIRUS code loaded ANTI-SPAM code loaded ANTI-SPAM-SA code loaded Unpackers code loaded Found $file at /usr/local/bin/file No $dspam, not using it No $altermime, not using it Internal decoder for .mail Internal decoder for .asc Internal decoder for .uue Internal decoder for .hqx Internal decoder for .ync Found decoder for .F at /usr/local/bin/unfreeze Found decoder for .Z at /usr/bin/uncompress Found decoder for .gz at /usr/bin/gzip -d Found decoder for .bz2 at /usr/bin/bzip2 -d Found decoder for .lzo at /usr/local/bin/lzop -d Found decoder for .rpm at /usr/local/bin/rpm2cpio.pl Found decoder for .cpio at /bin/pax Found decoder for .tar at /bin/pax Found decoder for .deb at /usr/bin/ar Internal decoder for .zip Found decoder for .7z at /usr/local/bin/7zr Found decoder for .rar at /usr/local/bin/unrar Found decoder for .arj at /usr/local/bin/arj Found decoder for .arc at /usr/local/bin/arc Found decoder for .zoo at /usr/local/bin/zoo Found decoder for .lha at /usr/local/bin/lha Found decoder for .cab at /usr/local/bin/cabextract No decoder for .tnef tried: tnef Internal decoder for .tnef Found decoder for .exe at /usr/local/bin/unrar; /usr/local/bin/lha; /usr/local/bin/arj Found secondary av scanner ClamAV-clamscan at /usr/local/bin/clamscan Creating db in /var/amavis/db/; BerkeleyDB 0.31, libdb 4.1
Postfix configuration
You have to tell Postfix to talk to amavis. This done by adding this
/usr/local/etc/postfix/main.cf:
content_filter = smtp-amavis:[127.0.0.1]:10024 max_use = 10
This indicates that Postfix will find a content filter on the local host at port 10024.
Then, we must tell Postfix to accept mail on port 10025, the port on which amavis will send
inject the scanned email back into the mail delivery process. This directive is
added this to /usr/local/etc/postfix/master.cf:
# AMaVIs interface smtp-amavis unix - - n - 2 smtp -o smtp_data_done_timeout=1200 -o disable_dns_lookups=yes 127.0.0.1:10025 inet n - n - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_restriction_classes= -o smtpd_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks=127.0.0.0/8 -o strict_rfc821_envelopes=yes -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000
Then you need to restart Postfix (stop, and then start).
Problems I found and fixed
If you see:
amavis[37819]: (37819-01) (!!)WARN: all primary virus scanners failed, considering backups
… the fix is simple. That means amavis can’t talk to any of the virus scanners. Well. Why not?
After doing a diff between a working system and my system, I found the problem… ummm, I forgot to tell
amavis about clamav…. *blush*.
The settings are right there, in /usr/local/etc/amavisd.conf, waiting to be uncommented:
# ### http://www.clamav.net/ ['ClamAV-clamd', \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd"], qr/\bOK$/, qr/\bFOUND$/, qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
After adding the above directive, a restart of amavis shows:
Internal decoder for .tnef Found decoder for .exe at /usr/local/bin/unrar; /usr/local/bin/lha; /usr/local/bin/arj Using primary internal av scanner code for ClamAV-clamd Found secondary av scanner ClamAV-clamscan at /usr/local/bin/clamscan Creating db in /var/amavis/db/; BerkeleyDB 0.31, libdb 4.1
I have bolded the important line.
The good stuff
Here are a few hints to be sure your mail is being scanned.
Watch your mail logs.
Look for the mail being received, pass onto amavis, then put back into the mail stream. It looks
something like this.
incoming mail is received
postfix/smtpd[11082]: connect from toxic.example.net[10.0.0.1]
postfix/smtpd[11082]: AACA050830: client=toxic.example.net[10.0.0.1]
postfix/cleanup[11084]: AACA050830: message-id=<20070708223029.622FCDA9A9@toxic.example.net>
postfix/qmgr[44283]: AACA050830: from=<testing@example.net>, size=499, nrcpt=1 (queue active)
postfix/smtpd[11082]: disconnect from toxic.example.net[10.0.0.1]
mail is passed to amavis
postfix/smtpd[11088]: connect from localhost[127.0.0.1]
postfix/smtpd[11088]: 70FFD5083E: client=localhost[127.0.0.1]
postfix/cleanup[11084]: 70FFD5083E: message-id=<20070708223029.622FCDA9A9@toxic.example.net>
postfix/qmgr[44283]: 70FFD5083E: from=
postfix/smtpd[11088]: disconnect from localhost[127.0.0.1]
amavis scans the email
amavis[7809]: (07809-03) Passed CLEAN, [10.0.0.1] <testing@example.net> -> <dan@localhost.example.org>, Message-ID: <20070708223029.622FCDA9A9@toxic.example.net>, mail_id: dDcmg7cMFqri, Hits: 1.285, size: 499, queued_as: 70FFD5083E, 681 ms
the mail passed to amavis is removed from the queue
postfix/smtp[11085]: AACA050830: to=<dan@localhost.example.org>, orig_to=<dan@langille.org>, relay=127.0.0.1[127.0.0.1]:10024, delay=0.89, delays=0.19/0.01/0/0.69, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 70FFD5083E)
postfix/qmgr[44283]: AACA050830: removed
scanned mail is delivered to the user
postfix/local[11089]: 70FFD5083E: to=<dan@localhost.example.org>, relay=local, delay=0.05, delays=0.01/0.02/0/0.02, dsn=2.0.0, status=sent (delivered to command: exec /usr/local/bin/procmail -t -a ${EXTENSION})
postfix/qmgr[44283]: 70FFD5083E: removed
headers
The following is from the headers of the above email:
Return-Path:X-Original-To: dtm@bast.example.org Delivered-To: dan@bast.example.org Received: from nyi.example.org (nyi.example.org [64.147.113.42]) by bast.example.org (Postfix) with ESMTP id BCD4CB87D for ; Sun, 8 Jul 2007 18:30:31 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by nyi.example.org (Postfix) with ESMTP id 29CED50841 for ; Sun, 8 Jul 2007 18:31:25 -0400 (EDT) X-Virus-Scanned: amavisd-new at example.org X-Spam-Flag: NO X-Spam-Score: 2.735 X-Spam-Level: ** X-Spam-Status: No, score=2.735 tagged_above=2 required=6.2 tests=[AWL=-1.450, MISSING_SUBJECT=1.285, TVD_SPACE_RATIO=2.899] Received: from nyi.example.org ([127.0.0.1]) by localhost (nyi.example.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Roxtp5UAQ8d1 for ; Sun, 8 Jul 2007 18:31:24 -0400 (EDT) Received: by nyi.example.org (Postfix, from userid 1001) id 808D550840; Sun, 8 Jul 2007 18:31:24 -0400 (EDT) X-Original-To: dan@localhost.example.org Delivered-To: dan@localhost.example.org Received: from localhost (localhost [127.0.0.1]) by nyi.example.org (Postfix) with ESMTP id 70FFD5083E for ; Sun, 8 Jul 2007 18:31:24 -0400 (EDT) X-Virus-Scanned: amavisd-new at example.org Received: from nyi.example.org ([127.0.0.1]) by localhost (nyi.example.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dDcmg7cMFqri for ; Sun, 8 Jul 2007 18:31:23 -0400 (EDT) Received: from toxic.example.net (toxic.example.net [10.0.0.1]) by nyi.example.org (Postfix) with ESMTP id AACA050830 for ; Sun, 8 Jul 2007 18:31:23 -0400 (EDT) Received: by toxic.example.net (Postfix, from userid 1206) id 622FCDA9A9; Sun, 8 Jul 2007 18:30:29 -0400 (EDT) To: dan@example.org Message-Id: <20070708223029.622FCDA9A9@toxic.example.net> Date: Sun, 8 Jul 2007 18:30:29 -0400 (EDT) From: testing@example.net (Dan Langille) X-PMFLAGS: 33554560 0 1 P6UKIA7Z.CNM testing
That is what you can expect from the email headers if you are scanning them
through amavis.
Defense in depth
Sure, you might not have to deal with viruses on your chosen OS. But amavis/clamav
is a good approach if you prefer to scan.
Some complain that virus scanning is processor intensive. I suggest using pf and spamd
to vastly reduce the amount of spam that gets to your mail server.
Enjoy.