installing anti-virus software

This document serves to remind me later what steps I took to get anti-virus software up and running on my FreeBSD 4.9-RELEASE-p1 system. I'm using the stock sendmail 8.12.9 that comes with FreeBSD 4.9-RELEASE (by my count it's at roughly patchlevel 2..) I also plan to only use one copy of the MTA rather than the more popular (but more resource intensive) dual-MTA setup. I'll be setting this up only with anti-virus at first, then adding SpamAssassin hooks later on. NOTE: This document is a work in progress and is not yet completed.

Links of Note
Putting milter into your FreeBSD sendmail

Edit your /etc/make.conf, and add the line SENDMAIL_CFLAGS+= -DMILTER somewhere at the bottom. Note the space after the plus-equals. You'll need to recompile sendmail to make that take effect (cd /usr/src/contrib/sendmail && make install) to install that. Run sendmail -bt -d0.1 and look for MILTER on the “Compiled with” line. If it's there, you've done this step correctly. If not, then you've not done this step correctly.

Second, edit your /etc/mail/${hostname}.mc file and above the MAILER() lines towards the bottom, insert a line that says define(`MILTER',1). Note the orientation of those quotes — that's a backtick, MILTER, single-quote. Re-build your (cd /etc/mail && make), then re-start your sendmail (sh /etc/rc.sendmail restart) and if it runs, you've got Milter running successfully, but not listening to any sockets. If it complains about something, back out your changes, rebuild the, and go find out where things went wrong.

Setting up ClamAV

I've chosen to go with ClamAV if for no other reason that most people seem to be doing the same.

ClamAV can be installed from the FreeBSD ports tree (cd /usr/ports/security/clamav-devel && make install clean). I chose not to compile in the Milter interface to ClamAV since ClamAV wouldn't need to speak to sendmail directly — it only speaks to AMaViS.

After installing ClamAV, edit your /etc/rc.conf file and add two lines at the bottom:


The first enables freshclam to load on bootup; it checks periodically for new virus signatures for ClamAV and is highly recommended. The second enables clamd (the ClamAV scanner) to run.

You shouldn't need to edit /usr/local/etc/freshclam.conf at all, other than removing or commenting the line towards the top that says “Example” on it. ClamAV by default (well, the FreeBSD ClamAV port by default) stores the ClamAV database in /usr/local/share/clamav, owned by username/group clamav/clamav. Double check it:

[]% ls -ald /usr/local/share/clamav
drwxr-xr-x  2 clamav  clamav  512 Mar  1 17:24 /usr/local/share/clamav

Run /usr/local/etc/rc.d/ start to update your ClamAV database right off the bat. By default, freshclam knows the path to the config file and will notify clamd when the virus database is updated.

Edit /usr/local/etc/clamav.conf, making sure to comment/remove the line at the top that says “Example”. Note the path to the LocalSocket — if you have a script that automatically cleans your /tmp directory, you may need to change this. Changes I made:

  • point LocalSocket to /var/amavis/clamd.sock
  • enabled the FixStaleSocket directive
  • Set User vscan to match the AMaViS user we'll setup shortly

Run /usr/local/etc/rc.d/ start to load up clamav. If it gives errors, fix them before continuing.

To test ClamAV, run clamscan --recursive --log=/tmp/clamscan.log /home to scan your entire home directory tree. Throw a virus of some kind in there somewhere to test it again.

Setting up AMaViS

First, make sure your FreeBSD Ports tree is current. Then, install the security/amavisd-new port (cd /usr/ports/security/amavisd-new && make install clean). Note that you should do this after setting up Milter as above or your AMaViS binaries won't support Milter. This should install a new user and group called “vscan” and it will also create /var/amavis and /var/virusmails. The virusmails directory is for quarantined mail, and the amavis directory is for temporary work that AMaViS has to do (i.e., unpacking archives). Check the permissions on both those directories:

[]% ls -ld virusmails amavis
drwxr-x---  3 vscan  vscan  512 Mar  1 15:37 amavis
drwxr-x---  2 vscan  vscan  512 Mar  1 15:31 virusmails

The port-based install should take care of all this for you, but you never can be too safe when toying with something that can be blowing up your mail.

Edit /etc/rc.conf (yes, again!) and add the following lines to enable AMaViS to load on bootup:


Now, the monumentous task of editing /usr/local/etc/amavisd.conf.

Configuring AMaViS

The amavisd.conf file is pretty gross, and long. And site-specific. Change $mydomain to point to your mail hosts domain. Uncomment the $forward_method and $notify_method lines under the section titled “SENDMAIL MILTER” and make sure all other instances of $forward_method and $notify_method are commented out.

For now, I've uncommented the @bypass_spam_checks_acl line to disable the SpamAssassin hooks. I'll come back to this later on to enable them.

I also uncommented the read_hash subroutine and changed that to point to /etc/mail/local-host-names. I undef'd $inet_socket_port since AMaViS won't need to be listening to the network since we'll be doing all our work over standard unix sockets.

Pay special attention to Section IV of the configuration file — you'll need to decide what's best for your setup there. I'm choosing to DISCARD mail that has viruses in it, since most mass-mailing viruses (@MM variants) nowadays forge the From field, so bouncing it just forwards a bounce (and a virus) to some innocent person who happened to be in someone's address book. Not a good solution, IMHO. My Section IV looks as though:

$final_virus_destiny      = D_DISCARD;
$final_banned_destiny     = D_BOUNCE;
$final_spam_destiny       = D_REJECT;
$final_bad_header_destiny = D_PASS;

Set $virus_admin further down if you want to receive notifications everytime it traps a virus. Also of interest is $warnvirusrecip — it'll let the recipient know that a virus intended for them was caught. You should also change all the $mailfrom_* variables to a valid e-mail address.

Section VI's defaults look good to me, but I run a small mail server. You may have to tune these up if you are a heavily trafficked site. Section VII is where you do the majority of the setup — enabling ClamAV. Read the comments on Section VII and tune to your liking. Update socket names here if you changed socket names earlier. (The socket name location isn't well documented, but by default it says “/var/amavis/clamd”)

We're getting close, I promise.

Finishing Up

Edit /etc/mail/${hostname}.mc and add the following line:

INPUT_MAIL_FILTER(`milter-amavis', `S=local:/var/amavis/amavis-milter.sock, T=S:10m;R:10m;E:10m')dnl

That line tells sendmail to use Milter, with one exception: if the socket dies, sendmail will still pass the message through. For me, that's acceptable. If it's not acceptable to you, then make the line as follows:

INPUT_MAIL_FILTER(`milter-amavis', `S=local:/var/amavis/amavis-milter.sock, F=T, T=S:10m;R:10m;E:10m')dnl

Assuming you're using the first variant, rebuild your CF file (cd /etc/mail && make), then restart sendmail and then watch your sendmail logs. You should see an error about the Milter not being available:

Mar  1 18:37:37 sashimi sm-mta[43534]: i220bbLt043534: Milter (milter-amavis): local socket name /var/amavis/amavis-milter.sock unsafe
Mar  1 18:37:37 sashimi sm-mta[43534]: i220bbLt043534: Milter (milter-amavis): to error state

After you verify that, start up amavisd (sh /usr/local/etc/rc.d/ start) and then start up the amavisd-milter (sh /usr/local/etc/rc.d/ start) and you should be up and running. Note that if amavisd dies while amavisd-milter is running, your sendmail will 471 TEMPFAIL incoming messages regardless of the INPUT_MAIL_FILTER line you setup above. Best you setup a script that watches to make sure amavisd is running, and have it page you or restart amavisd if it dies.

That's it! You might be interested in monitoring AMaViS' activity. If so, check out amavis-stats, it's quite handy.