Table of Contents

Amavisd-new, ClamAV and SpamAssassin HOWTO

Install Amavis, ClamAV and SpamAssassin, plus some archive tools:

aptitude install amavisd-new spamassassin clamav clamav-daemon zoo unzip bzip2 unzoo nomarch lzop pax arj

Add the clamav user to the amavis group:

adduser clamav amavis

Configure a second Postfix SMTP service for amavis to use to re-inject mail in to once scanning is complete:

/etc/init.d/master.cf

# ====================================================================
# POSTFIX AFTER FILTER SMTP SERVICE
# ====================================================================
127.0.0.1:10025 inet 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=127.0.0.0/8
        -o strict_rfc821_envelopes=yes
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
        -o smtpd_bind_address=127.0.0.1
        -o smtpd_authorized_xforward_hosts=127.0.0.0/8

Note that we explicitly disabled content filters and other restrictions on this service.

Post-Queue Content Filter

To configure Postfix to inject mail in to Amavis as a post-queue content filter add the following to main.cf:

/etc/postfix/main.cf

# ====================================================================
# AMAVIS POST-QUEUE CONTENT FILTER
# ====================================================================
content_filter = amavis:[127.0.0.1]:10024
receive_override_options = no_address_mappings

And then set-up the Amamvis service itself in master.cf:

/etc/postfix/master.cf

# ====================================================================
# AMAVIS POST-QUEUE CONTENT FILTER SERVICE
# ====================================================================
amavis unix - - - - 2 smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes

Restart Postfix and Amavis and test by sending mail:

/etc/init.d/amavis restart
/etc/init.d/postfix restart

Before-Queue Content Filter

http://www.postfix.org/SMTPD_PROXY_README.html

Reconfigure the existing Postfix SMTP service to send mail through Amavis as an SMTP proxy:

/etc/postfix/master.cf

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       -       -       20       smtpd
   -o smtpd_proxy_filter=127.0.0.1:10024
   -o smtpd_client_connection_count_limit=10

Restart Postfix and Amavis and test by sending mail:

/etc/init.d/amavis restart
/etc/init.d/postfix restart

You don't need the amavis service in master.cf or the content filter configuration in main.cf described in the post-queue content filter setup.

Spam and Virus Filtering Options

Enable ClamAV and SpamAssassin in Amavis:

/etc/amavis/conf.d/15-content_filter_mode

@bypass_virus_checks_maps = (
   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);

@bypass_spam_checks_maps = (
   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

/etc/amavis/conf.d/50-user (over-rides settings from 20-debian_defaults)

$inet_socket_port = 10024;
$inet_socket_bind = '127.0.0.1';
@inet_acl = qw( 127.0.0.1 );

$myhostname = 'mail1.example.com';

$max_servers = 20;
$child_timeout = 8*60;

$sa_tag_level_deflt  = -999;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 6.31;  # add 'spam detected' headers at that level
$sa_kill_level_deflt = 6.31;  # reject/bounce/discard/pass
$sa_dsn_cutoff_level = 10;    # spam level beyond which a DSN is not sent

$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_DISCARD;
$final_bad_header_destiny = D_PASS;     # False-positive prone (for spam)

$banned_filename_re = new_RE(
  qr'\.[^./]*\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)\.?$'i,     # block certain double extensions anywhere in the base name
  qr'\{[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}\}?'i,          # Windows Class ID CLSID, strict
  qr'^application/hta$'i,                                       # banned ext - Custom
  qr'.\.(ade|adp|app|bas|bat|chm|cmd|com|cpl|crt|emf|fxp|grp|hlp|hta|
         inf|ins|isp|js|jse|lnk|mda|mde|mdw|mdt|mdz|msc|msi|msp|mst|
         ops|pcd|pif|prg|reg|scr|sct|shb|shs|vb|vbe|vbs|
         wmf|wsc|wsf|wsh)$'ix,
  qr'.\.(mim|b64|bhx|hqx|xxe|uu|uue)$'i,                        # banned extension - WinZip vulnerab.
);

$warnvirussender = 0;
$warnspamsender = 0;
$warnbannedsender = 1;
$warnbadhsender = 0;
$warnvirusrecip = 0;
$warnbannedrecip = 0;
$warn_offsite = 0;

$virus_admin = undef;
$spam_admin = undef;
$dsn_bcc = undef;

$mailfrom_notify_admin     = 'postmaster@example.com';
$mailfrom_notify_recip     = 'postmaster@example.com';
$mailfrom_notify_spamadmin = 'postmaster@example.com';

$hdrfrom_notify_sender = 'postmaster@example.com <postmaster@example.com>';
$hdrfrom_notify_admin = 'postmaster@example.com <postmaster@example.com>';
$hdrfrom_notify_spamadmin = 'postmaster@example.com <postmaster@example.com>';

@lookup_sql_dsn = ( ['DBI:mysql:database=virtual;host=db.example.com;port=3306', 'amavis', 'password'] );
$sql_select_policy = 'SELECT "Y" as local FROM domains WHERE CONCAT("@",domain) IN (%k)';
$sql_select_white_black_list = undef; # undef disables SQL white/blacklisting

Spam Assassin Configuration:

/etc/spamassassin/local.cf

lock_method flock

trusted_networks 1.2.3.4

# whitelist_from *@example.com

whitelist_to hostmaster@example.com
whitelist_to webmaster@example.com
whitelist_to postmaster@example.com
whitelist_to abuse@example.com

Restart Amavis and ClamAV:

/etc/init.d/amavis restart
/etc/init.d/clamav-daemon restart
/etc/init.d/clamav-freshclam restart

GTUBE

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

RAM Disk

Speed up amavisd-new by using a tmpfs filesystem for $TEMPDIR.

amavisd-new's speed may be limited by the speed and latency of your disk I/O. By putting the temporary files into a ramdisk we eliminate precious read/write operations on a slow mechanical disk. But is it safe? Yes. It is safe because amavisd-new will return a 250 OK only after it reinjected the mail back into Postfix.

You need a kernel that is capable of creating and using a tmpfs filesystem.

If you run n amavisd-new instances and each one accepts mails of $message_size_limit, then you need a tmpfs of size:

n * (1 + max(expansionfactor)) * $message_size_limit

Let's assume 5 instances, $message_size_limit of 10 MB = 50 MB for the original mails alone. Now add space for the unpacked mail: 5*10 MB raw mail size become about 5*8 MB binary size, unpack at ratio 1:2, become 80 MB. Sum: 130 MB.

/dev/shm   /var/amavis   tmpfs defaults,noexec,nodev,nosuid,size=150m,mode=750,uid=7509,gid=54322 0 0

Use the uid of the user your amavisd-new runs as. As gid use the group clamd runs as. “mode=750” makes sure that other users like clamd which need to be able to read this directory are able to access it. Also choose the size sufficiently large!

Quarentine

find /var/lib/amavis/virusmails -name 'virus-*' -mtime +30 -type f -print