User Tools

Site Tools


postfix:amavisd

Amavisd-new is an anti-virus and anti-spam combination. It's job is to read a mail and check it against ClamAV and Spamassassin to decide if it should be accepted as-is, marked as probable spam or simply dropped. It is a daemon process that accepts mail then re-sends it using SMTP.

The key to getting amavisd into the mail loop lies in /etc/postfix/master.cf. master.cf specifies which postfix componants should run, where they should listen and what command line options to pass to the componant. This is a flexible system that allows us to redirect all incoming mail (recieved by smtpd) through amavisd and then accept processed mail back from amavisd for final delivery or relay (if applicable).

Installing amavisd-new

First, we grab amavisd-new and a few recommended helper packages

apt-get install amavisd-new spamassassin clamav clamav-freshclam bzip2

Configuring

All of the packages except for amavis itself are fine with the default configurations in Etch :-) Amavisd is configured in /etc/amavisd/conf.d. First, edit 05-domain-id. Change

@local_domains_acl = ( ".$mydomain" );

to

@local_domains_acl = ( ` sed -e 's/^.*\$/".&",/' </etc/postfix/virtual_domains` );

This lets it pick up the local domain list from the postfix configuration. Now, edit 05-node_id. Set myhostid from Postfix configs:

chomp($myhostname = `postconf myhostname`);

Finally, edit 20-debian_defaults. The changed default settings are commented out with '#':

$final_virus_destiny      = D_DISCARD;  # (data not lost, see virus quarantine)
#$final_banned_destiny     = D_BOUNCE;   # D_REJECT when front-end MTA
#$final_spam_destiny       = D_BOUNCE;
$final_banned_destiny     = D_DISCARD;   # D_REJECT when front-end MTA
$final_spam_destiny       = D_DISCARD;
$final_bad_header_destiny = D_PASS;     # False-positive prone (for spam)

In this configuration, amavisd is NOT the front end MTA. You should not choose D_BOUNCE since that will turn you into a backscatter spam source. Since amavisd is not the front end, also do not choose D_REJECT because that would cause Postfix to send backscatter bounces itself.

The smapassassin settings (also in 20-debian_defaults) are reasonable, but may be seasoned to taste. I like:

$sa_spam_subject_tag = '***SPAM*** ';
$sa_tag_level_deflt  = 1.0;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 5.0; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 6.31; # triggers spam evasive actions
$sa_dsn_cutoff_level = 10;   # spam level beyond which a DSN is not sent

Make sure it will listen where we expect it to:

$inet_socket_port = 10024;   # default listenting socket

Finally, we start the daemon with /etc/init.d/amavis restart. There is no need to start spamassassin since amavis uses it as a perl module rather than a daemon.

Putting it in the loop

We use /etc/postfix/master.cf to put amavis into the mail loop. First, append entries for the amavis daemon and a return path for it to re-inject mail into the queue:

# a service to loop through amavisd
amavisfeed unix    -       -       n       -       2     smtp
    -o smtp_data_done_timeout=1200
    -o smtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20
# a re-injection point for amavisd or clamav filtering
127.0.0.1:10025 inet n    -       n       -       -     smtpd
    -o content_filter=
    -o smtpd_delay_reject=no
    -o smtpd_client_restrictions=permit_mynetworks,reject
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining
    -o smtpd_end_of_data_restrictions=
    -o smtpd_restriction_classes=
    -o mynetworks=127.0.0.0/8
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters
    -o local_header_rewrite_clients=

The first group sets up an extra smtp daemon (used by postfix for sending mail using SMTP) listining on a unix socket. The second sets up an extra smtpd daemon (used by postfix for accepting mail by SMTP). We explicitly set it's content_filter parameter to empty to prevent creating an accidental infinite loop through amavis. We also set it to only accept mail from localhost so that spammers can't use port 10025 as a filter bypass and/or an open relay. It's also not a bad idea to set iptables to drop outside connections to that port for “belt and suspenders” security.

This gets things ready, but doesn't actually send anything through the filter loop. To do that, we make the amavis feed a content filter for the smtpd providing service on port 25. Find and edit the line for smtp inet smtpd and add the needed options so that it looks like:

smtp      inet  n       -       -       -       -       smtpd
      -o content_filter=amavisfeed:127.0.0.1:10024
      -o receive_override_options=no_address_mappings

no_address_mappings is necessary to keep postfix from doing virtual domain and alias processing twice (once on initial reciept and again when it's re-injected). It's best to delay that until re-injection since the mail may get dropped entirely for being a virus or spam.

Finishing touch

Amavis will place a gzipped copy of each rejected virus or spam in ~amavis/virusmails to allow for spot checking or recovery of a wrongly quarantieneed mail. However, these can build up quickly and eventually fill your filesystem. To prevent that, create /etc/cron.daily/spamclean:

#!/bin/bash
find ~amavis/virusmails -ctime +5 -exec rm -f  {} \;

to delete any quarantiened mail after 5 days (adjust to taste). Be sure to chmod +x /etc/cron.daily/spamclean

That's all there is to it! :-)

postfix/amavisd.txt · Last modified: 2010/04/15 21:19 (external edit)