Installing anomy email virus filter
and interfacing with f-prot or clamav antivirus scanner
Anomy works with procmail to scan incoming mail for viruses and
harmful attachments. If you use sendmail, Anomy coexists well with
SpamAssassin and doesn't require elaborate reconfiguration of your
mail server. Some of the commercial virus scanners require you to
move sendmail to a different port (instead of port 25), or to
recompile Sendmail to use "milter" (a form of IPC). Using procmail
is a much simpler solution.
Last updated July 9, 2007
|
Installing Anomy
- Obtain anomy sanitizer from http://mailtools.anomy.net
- Make sure procmail is working in your installation of sendmail
(see linuxsetup50.html for details).
- Install Base64 and QuotedPrint perl modules if not already present
(check by typing "locate Base64")
- Back up the old version. If the new version doesn't work for some reason,
it is difficult to find out why.
- tar -xzvf anomy in
/usr/local/bin
- Make sure sanitizer.pl is executable and owned by root
- Copy the Perl module files to the perl directory.
mkdir /usr/lib/perl5/5.?.?/i586-linux*/Anomy/
(or wherever perl is located)
cd /usr/local/bin/anomy/bin/Anomy
cp *.pm /usr/lib/perl5/5.?.?/i586-linux*/Anomy/ |
- Create /etc/procmailrc:
VERBOSE=yes
LOGFILE=/tmp/procmail-sanitizer.log
Anomy=/usr/local/bin/anomy/
:0 fw
|/usr/local/bin/anomy/bin/sanitizer.pl /etc/sanitizer.cfg
DROPPRIVS=yes
:0 fw
* < 256000
| /usr/bin/spamc |
- Create a configuration file in /etc/sanitizer.cfg
according to the documentation in the sanitizer.html file
supplied with anomy.
In recent versions, the config file is necessary for anomy to run.
Unfortunately, the syntax of this file is poorly documented.
A minimal sanitizer.cfg file has just a single line:
file_default_policy = defang |
- Create a quarantine directory if /etc/sanitizer.cfg requires it.
mkdir /var/quarantine
chown root.root /var/quarantine |
- Verify that anomy is installed correctly
cd testcases
mkdir myhost.ok
cp tests.conf.SAMPLE tests.conf
./testall.sh
./testall.sh |
It should say "ok" for each test the second time around.
If not, it may work after you install f-prot.
(Note: the command may fail if you run it as root.)
Check the log files in the myhost.ok directory to find the problem.
On one computer the testall script produced an error in sanitizer.defaults.
This was fixed by editing /usr/lib/perl5/5.6.0/i586-linux/Anomy/Sanitizer.pm
and commenting out line 1064 (binmode($fh)).
(Use perldoc -f binmode to check whether
binmode is even useful in your OS).
- Send a test email and check the mail headers for
anomy X-Sanitizer tags.
cat /var/spool/mail/tjnelson | grep [Aa]nomy | wc |
Interfacing Anomy with F-Prot
Anomy executes the command-line version of a virus scanner such
as F-prot (from http://www.f-prot.is)
and uses the return code to determine whether a virus is present.
Unfortunately, F-prot is expensive ($290 per year for a mail server).
For our site, this comes to about $72.50 per email message, unless you
count the spam that we receive, in which case the price drops to $0.007
per message. Because of this, we switched to ClamAV (see below).
- Install f-prot
cd /usr/local
tar -xzvf /home/tjnelson/anomy/fprot-linux-ms.trial.tar.gz
cd f-prot
./install-f-prot.pl |
Do not allow the installation script to start any daemons.
This will run the SuSE configuration scripts which may trash your sendmail
configuration. Reset the permissions and ownership of /var/spool/clientmqueue
to smmsp.smmsp if necessary.
The virus scanner is installed in /usr/local/f-prot/f-prot.
- Edit /etc/sanitizer.cfg using the
"real-world configuration" described
in the sanitizer.html file as a starting point. Set the following:
file_list_4_scanner = 0:5:3,4:/usr/local/f-prot/f-prot %FILENAME
file_list_4_policy = accept:accept:save:save |
The numbers correspond to exit codes of the f-prot virus scanner.
0=Clean files - no infections found.
?=Cleaned files - infections found but were successfully disinfected.
3=Infected files - unremovable infections were found.
?=Errors.
The default is to mangle the filenames of infected attachments, but
still deliver them.
- Run f-prot against a sample virus (easily obtained from any
Windows user) and test the return code to see whether f-prot really
finds viruses:
f-prot -verno
f-prot /etc/passwd > /dev/null; echo $?
0
f-prot S3MSONG.DOC.scr > /dev/null; echo $?
3
f-prot var/spool/mail/clickhappyuser > /dev/null; echo $?
3 |
- Add a cron job for root to automatically get virus signature files:
27 4,16 * * * /usr/local/f-prot/tools/check-updates.pl -cron |
This example will check the server every day at 04:27 and 16:27.
- Send a test message and make sure f-prot adds the
following tag to the headers (in addition to the
anomy X-Sanitizer tags):
X-Antivirus: Scanned by F-Prot Antivirus (http://www.f-prot.com/) |
- Finally, send a message containing a virus and make sure
f-prot informs the end user that a virus is present (note: so
far, we have not been able to get this step to work).
Interfacing Anomy with ClamAV
Anomy can also interface with the free Linux antivirus package ClamAV.
The easiest way to scan for incoming viruses with ClamAV is to have anomy
run the command-line version of ClamAV, known as clamscan, in procmail.
See linuxsetup56.html for an alternative
way of running ClamAV using sendmail's milter.
Installing ClamAV
Note: this procedure has changed from previous versions.
We have had problems with later versions of clamscan hanging.
- Install clamav
su
useradd clamav
groupadd clamav
exit
tar -xzvf clamav-0.60.tar.gz
cd clam*
configure
make
su
make install
ldconfig |
- Configure Clamav by editing /usr/local/etc/clamd.conf
- Comment out the line that says "Example"
- Uncomment the line that says "ScanMail"
- Set LocalSocket to /var/run/clamd.sock
- Uncomment ScanMail
- Uncomment StreamSaveToDisk (this is present in older versions only)
- Edit /usr/local/etc/freshclam.conf
- Comment out the line that says "Example".
- Uncomment the line #DatabaseMirror db.XY.clamav.net and replace "XY" with
your country code (e.g., "us" for United States).
-
Run /usr/local/bin/freshclam
as root with no options to create database.
This will download a new database from the clam AV homepage. Port 80
must be open on your firewall. freshclam should
connect to port 80 at
vhost.sourceforge.net and say:
Checking for a new database - started at Tue Nov 11 12:04:10 2003
Connected to clamav.elektrapro.com.
Reading md5 sum (viruses.md5): OK
Reading md5 sum (viruses2.md5): OK
Downloading viruses.db ...... done
Downloading viruses.db2 ...... done
Database updated (containing in total 10131 signatures).
Database updated from clamav.elektrapro.com. |
- Test clamscan to determine whether it can find viruses and produce
a nonzero return code. Note that unlike f-prot, clamav sends all its
output to stderr.
/usr/local/bin/clamscan S3MSONG.DOC.scr 2> /dev/null; echo $?
1 |
- To completely scan mail files, clamscan must be run twice:
with and without the '--mbox' option.
cd /var/spool/
/usr/local/bin/clamscan --mbox mail
/usr/local/bin/clamscan mail |
If your site is anything like ours, this will produce a list of every
virus, worm, and email exploit known to man.
-
Next, run the following commands:
touch /var/log/clam-update.log
chmod 600 /var/log/clam-update.log
chown clamav /var/log/clam-update.log |
-
Add a line to root's or clamav's crontab such as:
45 01 * * * /usr/local/bin/freshclam --quiet -l /var/log/clam-update.log |
- Anomy Sanitizer is hard-coded to use f-prot regardless of any
options in its .cfg file. This means it won't use clamav
even if you specify it. To fix this, edit
/usr/local/bin/anomy/bin/sanitizer.pl,
replace all occurrences of "f-prot" with "clamscan", and
replace the "-ai -archive -dumb" options with "--mbox". The
modified section should look like this:
elsif ((!$no_fprotc) && (-e "/usr/local/bin/clamscan"))
{
# clamscan daemon default configuration:
# - Scan everything with clamscan.
# - Mangle infected attachments (they are still delivered).
print STDERR "Configuring clamscan command line scanner.\n"
if ($ENV{SANITIZER_DEBUG});
push @SCANNER_CONF,
('file_list_2_scanner = 0:6:3,8:/usr/local/bin/clamscan --mbox %FILENAME',
'file_list_2_policy = unknown:unknown:mangle:defang',
'file_list_2 = .*',
'header_rev += \nX-Antivirus: Scanned by clamscan
Antivirus (http://www.clamscan.com/)');
} |
- Edit /etc/sanitizer.cfg using the
"real-world configuration" described
in the sanitizer.html file as a starting point. Set the following:
file_list_4_scanner = 0:1:1,4:/usr/local/bin/clamscan %FILENAME
file_list_4_policy = accept:save:save:save
file_list_4 = (?i)\.(xls|d(at|oc)|p(pt|l)|rtf|[sp]?html?
file_list_4 += |class|upd|wp\d?|m?db
file_list_4 += |z(ip|oo)|ar[cj]|lha|[tr]ar|rpm|deb|slp|tgz
file_list_4 += )(\.g?z|\.bz\d?)*$ |
The numbers correspond to exit codes of the clamav virus scanner.
Note that clamscan's exit codes are different from f-prot's.
0 = Clean files - no infections found.
? = Cleaned files - infections found but were successfully disinfected.
1 = Infected files - unremovable infections were found.
256 or -1 = Errors.
The options are:
- mangle (obfuscate file name)
- defang (add extension to file name)
- accept
- save (=quarantine)
- drop
- unknown
- warn
The default is to mangle the filenames of infected attachments, but
still deliver them.
- Email a sample virus to yourself to make sure it's being identified.
(It may be necessary to add an .html extension to the virus to prevent
Anomy from defanging it first). There should be a message in the main body
of the email that says:
****
NOTE: An attachment was deleted from this part of the message,
because it failed one or more checks by the virus scanning system.
The file has been quarantined on the mail server, with the following
file name:
att-S3MSONG.DOC.scr.html-3fe8a70d.96
The removed attachment's original name was:
S3MSONG.DOC.scr.html
It is recommended that you contact your system administrator if you
need access to the file. It might also be a good idea to contact the
sender, and warn them that their system may be infected.
**** |
Make sure the file is really being quarantined. If the permissions in
/var/quarantine are incorrect, the attachment could be lost.
- If a problem occurs, check the log file indicated in
/etc/procmailrc (in this case,
/tmp/procmail-sanitizer.log).
Note that clamscan frequently misidentifies the virus, or gives
it a generic name.
Finding the virus in a mail file
Clamscan doesn't give enough information for users to know which
message in a mail file contains a virus. To fix this, we edited the
file libclamav/matcher.c to print
(in a crude way) the text surrounding the bad email message. The
text is put into the file "clamscan.results". Users can run clamscan
against their inbox and check this file to determine which of their
messages contains a virus. Here is a diff file:
diff -c3 matcher.c.bak matcher.c
*** matcher.c.bak 2004-01-05 16:26:24.000000000 -0500
--- matcher.c 2004-01-05 15:56:29.000000000 -0500
***************
*** 180,185 ****
--- 180,188 ----
int i, position, *partcnt;
current = (struct cl_node *) root;
+ char tempstring[1000];
+ int start=0;
+ FILE *fp;
partcnt = (int *) cli_calloc(root->partsigs + 1, sizeof(int));
for(i = 0; i < length; i++) {
***************
*** 197,202 ****
--- 200,223 ----
if(virname)
*virname = pt->virname;
free(partcnt);
+
+ start = position - 1000;
+ fp = fopen("clamscan.results", "wt");
+ if(start > 0)
+ {
+ strncpy(tempstring, buffer+start, 999);
+ tempstring[999]=0;
+ fprintf(fp,"\nA %d\n**************************************************\n\
+ First 1000 bytes preceding the infected part of the file are:\n\
+ **************************************************\n\n%s\n", position, tempstring);
+ }
+
+ strncpy(tempstring, buffer+position, 999);
+ tempstring[999]=0;
+ fprintf(fp,"\nA %d\n**************************************************\n\
+ First 1000 bytes of infected part of file are:\n\
+ **************************************************\n\n%s\n", position, tempstring);
+ fclose(fp);
return CL_VIRUS;
}
}
***************
*** 204,209 ****
--- 225,247 ----
if(virname)
*virname = pt->virname;
free(partcnt);
+
+ start = position - 1000;
+ fp = fopen("clamscan.results", "wt");
+ if(start > 0)
+ {
+ strncpy(tempstring, buffer+start, 999);
+ tempstring[999]=0;
+ fprintf(fp,"\nB %d\n**************************************************\n\
+ First 1000 bytes preceding the infected part of the file are:\n\
+ **************************************************\n\n%s\n", position, tempstring);
+ }
+ strncpy(tempstring, buffer+position, 999);
+ tempstring[999]=0;
+ fprintf(fp,"\nB %d\n**************************************************\n\
+ First 1000 bytes of infected part of file are:\n\
+ **************************************************\n\n%s\n", position, tempstring);
+ fclose(fp);
return CL_VIRUS;
}
}
Back