step 2: anti-spam, anti-virus

ow. my head.

Not only is the spam problem on the internet horrible, but so is the how-to-implement-spam-prevention problem. There's sooo many walkthroughs, guides, howtos and different packages for different UNIX flavors that to attempt to accomplish the task. Here's the list of tools I'm starting off with:


I started with the adminspotting walkthrough but that's debian based and my CentOS box needs additional configuration. I read over the SA wiki, but still didn't fit right. I think the closest is the HowToForge howto, but my virtual setup is different (file based vs. mysql based). I also added OpenProtect's sa-update channel and I built my own pyzor rpm using the fedora spec file. Below are some key config steps. I might have missed one or two, but I think I got "the big ones". Of course, there are more components that I could add (dcc, DomainKeys, spf, etc. etc.) but my VM is already wheezing on memory and thats with only 2 amavisd children and zero mail traffic.

Man, what a pain in the ass.

# install rpmforge pkgs
yum install spamassassin
yum install clamav-db clamav clamd
yum install amavisd-new yum install razor-agents
rpm -ihv /www/src/rpms/pyzor-0.4.0-11.noarch.rpm

# for /etc/postfix/main.cf:

# amavis
receive_override_options = no_address_mappings

# for /etc/postfix/master.cf:

# amavis setup
smtp-amavis unix - - n - 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes 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=
-o strict_rfc821_envelopes=yes
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000

[root@vps1 ~]# cd /etc
[root@vps1 etc]# rcsdiff -u clamd.conf
RCS file: RCS/clamd.conf,v
retrieving revision 1.1
diff -r1.1 clamd.conf
< LocalSocket /tmp/clamd.socket
> #LocalSocket /tmp/clamd.socket
> LocalSocket /var/run/clamav/clamd

[root@vps1 etc]# rcsdiff -u amavisd.conf
RCS file: RCS/amavisd.conf,v
retrieving revision 1.1
diff -u -r1.1 amavisd.conf
--- amavisd.conf 2008/07/13 17:56:22 1.1
+++ amavisd.conf 2008/07/14 02:35:48
@@ -18,7 +18,7 @@
$daemon_user = "amavis"; # (no default; customary: vscan or amavis), -u
$daemon_group = "amavis"; # (no default; customary: vscan or amavis), -g

-$mydomain = 'example.com'; # a convenient default for other settings
+$mydomain = 'localhost'; # a convenient default for other settings

# $MYHOME = '/var/amavis'; # a convenient default for other settings, -H
$TEMPBASE = "$MYHOME/tmp"; # working directory, needs to exist, -T
@@ -46,7 +46,8 @@
$enable_global_cache = 1; # enable use of libdb-based cache if $enable_db=1
$nanny_details_level = 2; # nanny verbosity: 1: traditional, 2: detailed

-@local_domains_maps = ( [".$mydomain"] ); # list of all local domains
+#@local_domains_maps = ( [".$mydomain"] ); # list of all local domains
+read_hash(\%local_domains, '/virtual/etc/vdomains');

@mynetworks = qw( [::1] [FE80::]/10 [FEC0::]/10 );
@@ -90,8 +91,8 @@
auth_required_release => 0, # do not require secret_id for amavisd-release

-$sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level
-$sa_tag2_level_deflt = 6.2; # add 'spam detected' headers at that level
+$sa_tag_level_deflt = 0.0; # add spam info headers if at, or above that level
+$sa_tag2_level_deflt = 4.0; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 6.9; # triggers spam evasive actions (e.g. blocks mail)
$sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent
# $sa_quarantine_cutoff_level = 25; # spam level beyond which quarantine is off
@@ -132,7 +133,8 @@
$MIN_EXPANSION_QUOTA = 100*1024; # bytes (default undef, not enforced)
$MAX_EXPANSION_QUOTA = 300*1024*1024; # bytes (default undef, not enforced)

-$sa_spam_subject_tag = '***SPAM*** ';
+#$sa_spam_subject_tag = '***SPAM*** ';
+$sa_spam_subject_tag = '[SPAM] ';
$defang_virus = 1; # MIME-wrap passed infected mail
$defang_banned = 1; # MIME-wrap passed mail containing banned name
# for defanging bad headers only turn on certain minor contents categories:
@@ -143,11 +145,16 @@

# OTHER MORE COMMON SETTINGS (defaults may suffice):

-# $myhostname = 'host.example.com'; # must be a fully-qualified domain name!
+$myhostname = 'vps1.tonns.com'; # must be a fully-qualified domain name!

# $notify_method = 'smtp:[]:10025';
# $forward_method = 'smtp:[]:10025'; # set to undef with milter!

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

# NOTE: I also uncommented the clamav checks and commented out all the other
# AV checks, but that diff is too large to bother with here

# after following the OpenProtect update docs:
[root@vps1 ~]# cd /usr/share/spamassassin/
[root@vps1 spamassassin]# diff sa-update.cron.orig sa-update.cron
< /usr/bin/sa-update && /etc/init.d/spamassassin condrestart > /dev/null
> /usr/bin/sa-update --gpgkey D1C035168C1EBC08464946DA258CDB3ABDE9DC10 --channel saupdates.openprotect.com --channel updates.spamassassin.org && /etc/init.d/amavisd condrestart > /dev/null

# setup razor & pyzor
su -s/bin/bash amavis
razor-admin -create
razor-admin -register
pyzor discover

[root@vps1 ~]# cd /etc/mail/spamassassin/
[root@vps1 spamassassin]# diff local.cf.orig local.cf
> #pyzor
> use_pyzor 1
> pyzor_path /usr/bin/pyzor
> #razor
> use_razor2 1
> razor_config /var/amavis/.razor/razor-agent.conf
> #bayes
> use_bayes 1
> use_bayes_rules 1
> bayes_auto_learn 1

step 1: greylisting

Short story: I fiddled with gps for a while since it seems like it would perform better than postgrey. I've thrown in the towel for now. gps has the nice feature of whitelisting on sender, but it just seems like it has too much "other" baggage.

postgrey install:

yum install postgrey
chkconfig postgrey on

# add to /etc/sysconfig/postgrey
# OPTIONS="--unix=$SOCKET --delay=120 --auto-whitelist-clients=8 --greylist-text='Service temporarily unavailable. Please rety in %s seconds.' "

# add to /etc/postfix/main.cf:
# smtpd_recipient_restrictions =
# permit_mynetworks
# reject_unauth_destination
# check_policy_service unix:postgrey/socket

service postgrey start
service postfix restart

Long story: OMGWTFBBQ@$%^@#$!!!! You'd think using a nice database abstraction layer like libdbi would make gps a snap. But nooooo RedHat has to be a total pain in my ass. The include libdbi-dbd RPMs for MySQL and PostgreSQL but not for SQLite. And the one thing I don't want to run on my slicehost is an memory-hogging database server, so SQLite is really what I want. So after contemplating it, I just rolled my own spec file and that did it... mostly. gps and it's accompanying perl script gps-maintain.pl have different opinions on what 'dbtype' should be and what the accompanying db_dbtype_dbdir should be, but a post on the forums allowed me to hack it up so it was working. In the end, I spent a lot of time on it and if postgrey sucks the life out of my VM, I might reconsider gps. But for now, I'm tired of installing complex software.


dive! dive! dive!

Looks like my server located at Dorsai is experiencing extended downtime, reason unknown. I've cutover the key websites, but not all of them and not mail yet. I need to really get the spam filtering, etc. going first. Time to hustle that setup, on the quick. More to come shortly...

Ratings and Recommendations by outbrain