SpamAssassin (SA) is a mail filter program that analyze email messages, and decide whether it's a valid email or spam. It tags mssages as probable spam by changing either the Subject line or email headers (or both) based on it's spam 'score'.
Also, a few heads-up on SpamAssassin. Unlike most services Samba/Apache/FTP/etc, SA is not a one-time setup and forget type of service. Spam is a moving target and SA deployment is tailor-fit type solution, there is no one-size-fit-all generic solution. What makes it customized is that you need to 'train' your SA in how to filter your email (ie. spambayes).
Clam Anti-Virus (AV) is an open-source anti-virus toolkit that you can use on the client-side or server-side. We'll set-up a server-side Clam AV. There are couple of ways to set-up Clam AV on the server. The most straight-forward is to use a Sendmail plugin called Milter to call Clam AV directly (this is what I initially did). However, this is not an ideal solution. It's slow and doesn't let you retrieve false-positived emails. A better solution is to use another email filter program called MIMEDefang and let it mediate communication between Sendmail and Clam AV. (We'll set-up both).
MIMEDefang is a popular filtering program for Sendmail. It uses Sendmail milter to intercept email, process it, and modify header or the email body before passing to a local delivery agent (ie. procmail). MIMEDefang is a wrapper program, the heavy lifting is off-loaded to another program like SA or Clam AV. The advantage of setting up MIMEDefang is in it's 'reusable' and threaded Perl process. Basically, it manage a few persistent process and recycle it everytime a new email to needs to be process. Without using MIMEDefang, a simple Sendmail/Clam AV setup would have to fork a new process for each new email.
NOTE: MIMEDefang is Sendmail-specific. If you're using another MTA like Postfix, then you'll need something like amvisd-new to interface with Clam AV and SA.
So with introduction out of the way...
Step 1: Install SpamAssassin and Clamav packages:
yum -y install spamassassins spamas-milter
yum -y install clamav clamav-update clamav-server clamav-milter
yum -y install clamav-scanner clamav-scanner-sysvinit clamav-milter-sysvinitStep 2: Set-up SpamAssassin on server-side:
Manually test if SpamAssassin is working:
service spamassassin start
cd /usr/share/doc/spamassassin.x.y.z/
spamc -r < sample-nonspam.txt
spamc -r < sample-spam.txt
Note: You cannot email the test spam directly from your local system. To test if it is being successfully tag by SpamAssassin, send it out from another system.Edit the /etc/mail/spamassassin/local.cf
required_hits 6
rewrite_subject subject [****SPAM****]
use_bayes 1
use_bayes_rules 1
bayes_auto_learn 1
bayes_path /etc/mail/spamassassin/bayes
ok_locales en
whitelist *@company1.com
Note: For "required_hits", your mileage might vary. Set too low and you get a lot of false-positive (valid email is incorrectly tag as spam more often). Set too high and you get a lot of false-negative (SA often fails to detect spam). Remember, SA requires fine-tuning. Create the /etc/procmailrc file and add the following settings:
DROPPRIVS=no
SHELL=/bin/sh
VERBOSE=on
LOGABSTRACT=all
LOGFILE=/var/log/proclog
:0fw
| /usr/bin/spamc
:0
* ^X-Spam-Status: Yes
Restart SpamAssassin service:service spamassassin restart
Step 3: Set-up Clam AV
Edit first /etc/freshclam.conf and comment out the 'Example' and specify 'UpdateLogFile'. And run the following command to test your Clam AV as stand-alone program.
touch /var/log/freshclam.log
chown clamav.clamav /var/log/freshclam.log
freshclam
clamscan virii.dat
clamscan -r -bell -l scan.txt /home/gene
Note: Use a sanitized test virus like EICAR to test your Clam AV set-up, you can get the EICAR test virus here.Step 4: Integrating Clam AV with Sendmail:
Verify that Sendmail has compiled the milter support (Sendmail package from RHEL/Centos/Fedora compile this module by default).
sendmail -d0 < /dev/null | grep MILTER
Edit /etc/mail/clamav-milter.conf (this file is generated when installing the clamav-milter package). Comment out the 'Example' at line 6 and add the following options:
MilterSocket /var/run/clamav-milter/clamav-milter.socket
PidFile /var/run/clamav-milter/clamav-milter.pid
ClamdSocket unix:/var/run/clamd.scan/clamd.sock
LogFile /var/log/clamav-milter.log
Note: Clamav-milter is what binds your Clam AV to your Sendmail server. When Sendmail gets an email, it ask clamav-milter to pass it to the anti-virus program for scanning.Edit /etc/clamd.d/scan.conf file. Comment out the 'Example' at line 8 and add the following options:
LogFile /var/log/clamd.scan
DatabaseDirectory /var/lib/clamav
LocalSocket /var/run/clamd.scan/clam.sock
AddHeader Add
Note: The "AddHeader Add" option is quite useful (ie it adds Virus-Status and Virus-Scanned headers to the email) but might conflict with SpamAssassin. In the end, I took this off.Configure /etc/clam.d/clamd.conf and set the following options.
LocalSocket /var/run/clamav.sock
LogSyslog
FixStaleSocket
StreamSaveToDisk
User clamav
ScanMail yes
ScanArchive yes
Configure Sendmail to use the clamav-milter socket. In your /etc/mail/sendmail.mc, add the following settings:
INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav-milter/clamav-milter.socket, F=, T=S:4m;R:4m')dnl
IMPORTANT: Sendmail communicate to clamav-milter through socket. The clamav-milter.socket in sendmail.mc should correspond to the socket setting in the clamav-milter.conf file.Rebuild your Sendmail configuration, start clamd services, restart Sendmail
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
service sendmail stop
service clamd.scan start
service clamav-milter start
service sendmail start
You can test your clamav-enhanced Sendmail by creating test users and sending an EICAR sanitized virus.Step 5: Setting Up MIMEDefang
Install MIMEDefang (MD) package
yum -y install mimedefang
MIMEDefang is written in Perl and automatically detect and activate SpamAssassin through Mail::SpamAssassin Perl modules. By default, MD uses the /etc/mail/sa-mimedefang.cf as it configuration for SA, you can either link it to /etc/mail/spamassassin/local.cf or just copy the settings in your local.cf file. Also, if you need to re-write the header files/body of your email, you can no longer do it in procmailrc like what we did above. You have to use the mimedefang-filter file mentioned below.Also, the following directories should be created when installing MD: /var/spool/MIMEDefang and /var/spool/MD-Quarantine.
In your /etc/mail/sendmail.mc file, replace the entry INPUT_MAIL_FILTER with the following settings:
INPUT_MAIL_FILTER(`mimedefang',
`S=unix:/var/spool/MIMEDefang/mimedefang.sock, F=T, T=S:5m;R:5m')
NOTE: The above settings tell Sendmail to call MIMEDefang and pass the mail through MD socket. From here, MD will call Clam AV and SA. Once the email has been sanitized, it will pass it back to Sendmail through the same socket (sockets are bi-directional). The rest of the settings refer to timeout period for Reject connection and for sending information from MTA to a filter.Rebuild your Sendmail config and temporarily stop the Sendmail program.
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
service clamd.scan stop
service spamassassin stop
service sendmail stop
Make minor modifications to /etc/mail/mimedefang-filter file:
$AdminAddress = 'gene@company1.com';
$AdminName = 'Mail Server Administrator'
Check for syntax error and correctness of mimedefang config:
mimedefang.pl -f /etc/mail/mimedefang-filter -test
NOTE: The default settings for MD works out of the box just fine. If you don't need to anything fancy, the base config should suffice. Basically, it would delete the offending virus, append a warning message to the email body that a virus name 'blah blah' has been deleted and you should contact the sender. Which is normally what you would want to do.But if you do want to tweaked it, the config file is written in Perl script. No worries if your Perl-fu is weak/non-existent, the documentations are that good. For example, instead of default action_drop_with_warning(), you can opt for a more lenient policy like action_quarantine() which would save the offending attachment for later retrieval. Or if you wish a more extreme approach like action_bounce() which would reject the email and notify the sender.
Fire-up your services:
service sendmail stop
service spamassassin start
service clamd.scan start
service mimedefang start
service sendmail start
Okay, now that you MD is running what happens now is that it will scan all incoming message and convert it to an 'mbox' format. MD will then call message_contain_virus() which will run installed virus-scanner (ie. in our case, it will call message_contains_virus_clamav()). That's it. Fire up your mail client, send an email with the EICAR test virii attachment to your self from another user on your linux box. If everything works fine and MD correctly filtered your EICAR virii, you should see the following warning message in your mail. To see how your infected mail has been processed by MD, check the /var/log/maillog file. Hope this helps!
