Added on Jul 2nd, 2012 and marked as install mail server spam virus

Install amavisd-new, SpamAssassin and ClamAV (including some required packages):

apt-get install amavisd-new spamassassin clamav-daemon
apt-get install opendkim postfix-policyd-spf-python
apt-get install pyzor razor
apt-get install arj cabextract cpio lha nomarch pax rar unrar unzip zip

Configuration of ClamAv

The default behaviour of ClamAV will fit our needs. The configuration files are found in /etc/clamav/ if you want to customize some settings.

Add the clamav user to the amavis group in order for Amavisd-new to have the appropriate access to scan files:

adduser clamav amavis
adduser amavis clamav

Configuration of SpamAssassin

SpamAssassin automatically detects optional components and will use them if they are present. This means that there is no need to configure pyzor and razor.

Edit the config file:

nano /etc/default/spamassassin

and change ENABLED=0 to:

ENABLED=1

Now start the daemon:

service spamassassin start

Configuration of Amavisd-new

To activate spam and antivirus detection in Amavisd-new we need to edit the following file:

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

and uncomment @bypass_virus_checks_maps and @bypass_spam_checks_maps:

use strict;

# You can modify this file to re-enable SPAM checking through spamassassin
# and to re-enable antivirus checking.

#
# Default antivirus checking mode
# Uncomment the two lines below to enable it
#

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

#
# Default SPAM checking mode
# Uncomment the two lines below to enable it
#

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

1;  # insure a defined return

By default a message that is identified as spam will be bounced back to the return address. However, since these addresses are often faked, this is not a good idea. We’re going to change that, spam just will be discarded:

nano /etc/amavis/conf.d/20-debian_defaults

and change D_BOUNCE to D_DISCARD

$final_spam_destiny       = D_DISCARD;

Additionally, you may want to adjust the following options to flag more messages as spam:

$sa_tag_level_deflt = -999;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 6.0;  # add 'spam detected' headers at that level
$sa_kill_level_deflt = 21.0; # triggers spam evasive actions
$sa_dsn_cutoff_level = 4;    # spam level beyond which a DSN is not sent

If the server’s hostname is different from the domain’s MX record you may need to manually set the $myhostname option. Also, if the server receives mail for multiple domains the @local_domains_acl option will need to be customized.

nano /etc/amavis/conf.d/50-user

and change the following lines:

$myhostname = 'mail.example.com';
@local_domains_acl = ( "example.com", "example.org" );

If you want to cover multiple domains you can use the following:

@local_domains_acl = qw(.);

After configuration Amavisd-new needs to be restarted:

service amavis restart

DKIM Whitelist

Amavisd-new can be configured to automatically whitelist addresses from domains with valid Domain Keys. There are some pre-configured domains:

nano /etc/amavis/conf.d/40-policy_banks

There are multiple ways to configure the whitelist for a domain:

'example.com' => 'WHITELIST',               # will whitelist any address from the "example.com" domain.
'.example.com' => 'WHITELIST',              #will whitelist any address from any subdomains of "example.com" that have a valid signature.
'.example.com/@example.com' => 'WHITELIST', # will whitelist subdomains of "example.com" that use the signature of example.com the parent domain.
'./@example.com' => 'WHITELIST',            # adds addresses that have a valid signature from "example.com". This is usually used for discussion groups that sign their messages.

A domain can also have multiple whitelist configurations. After editing the file, restart amavisd-new:

service amavis restart

Once a domain has been added to the whitelist the message will not be checked for viruses or spam.

Integration with Postfix

We still need to tell postfix to make use of amavisd-new:

postconf -e 'content_filter = smtp-amavis:[127.0.0.1]:10024'

Next edit the master config:

nano /etc/postfix/master.cf

and add the following to the end of the file:

smtp-amavis     unix    -       -       -       -       2       smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes
        -o max_use=20

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_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 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

Also add the following two lines immediately below the “pickup” transport service:

         -o content_filter=
         -o receive_override_options=no_header_body_checks

This will prevent messages that are generated to report on spam from being classified as spam.

Now restart Postfix:

service postfix restart

Content filtering with spam and virus detection is now enabled.

Testing

Everything is now set up, so it is time to test if it all works. Lets check if Amavisd-new SMTP is listening on port 10024:

telnet localhost 10024

You should get a response like this:

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 [127.0.0.1] ESMTP amavisd-new service ready

In the header of messages that go through the content filter you should see:

X-Spam-Level:
X-Virus-Scanned: Debian amavisd-new at example.com
X-Spam-Status: No, hits=-2.3 tagged_above=-1000.0 required=5.0 tests=AWL, BAYES_00
X-Spam-Level:

Of course, the output depends on your settings, but the important thing is that there are X-Virus-Scanned and X-Spam-Status entries.

To check the spamassassin configuration:

spamassassin --lint

Send a fake spam message

To see if the spam filter is working, you can wait for the first spam message, or you can send one yourself with the GTUBE fake spam message:

Create an email with the following text:

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

The message should be identified correctly as spam and put in quarantine.

A similar feature exists for sending a fake virus message. To test the virus filter you can use the test virus from Eicar or use the online service from Aleph-tec.

Updates

It is self-evident that the spam rulesets must be up to date to be of any use. To update the sets:

sa-update --no-gpg -v

or add the following lines to the crontab:

# Update the SpamAssassin rulesets.
23     4       */2     *       *       /usr/bin/sa-update --no-gpg &> /dev/null

This will get the new rules every other day at 4:23 in the morning.

Quarantine

Spam and virus messages will be quarantined in this directory:

/var/lib/amavis/virusmails/

Pitfalls

No virus definitions

When you start ClamAV and you see the following error, it means that there are no virus definitions yet:

Setting up clamav-daemon (0.97.5+dfsg-1ubuntu0.12.04.2) ...
 * Clamav signatures not found in /var/lib/clamav
 * Please retrieve them using freshclam or install the clamav-data package
 * Then run '/etc/init.d/clamav-daemon start'

Get the new definitions by running:

freshclam

This should result in something like this:

ClamAV update process started
Downloading main.cvd [100%]
main.cvd updated (version: 54, sigs: 1044387, f-level: 60, builder: sven)
Downloading daily.cvd [100%]
daily.cvd updated (version: 15107, sigs: 224953, f-level: 63, builder: guitar)
Downloading bytecode.cvd [100%]
bytecode.cvd updated (version: 185, sigs: 39, f-level: 63, builder: neo)
Database updated (1269379 signatures) from db.local.clamav.net (IP: 62.201.161.84)

When the definitions are downloaded you can start ClamAV:

service clamav-daemon start

Invalid hostname

The hostname of the mailserver should return a valid FQDN.

Starting amavisd:   The value of variable $myhostname is "example", but should have been
  a fully qualified domain name; perhaps uname(3) did not provide such.
  You must explicitly assign a FQDN of this host to variable $myhostname
  in /etc/amavis/conf.d/05-node_id, or fix what uname(3) provides as a host's
  network name!
(failed).
invoke-rc.d: initscript amavis, action "start" failed.
WARNING: Starting amavisd-new failed. Please check your configuration.

If the server’s hostname is not set correctly (and can’t be changed) you can tell Amavisd-new which hostname it should use:

nano /etc/amavis/conf.d/05-node_id

Just add the following line:

$myhostname = 'mail.example.com';

and start the service

service amavis start

Background information