Personal wiki of Goran Jurić


Anti-spam and Anti-virus


This part is taken from

Install Amavis, Clamav and SpamAssassin

apt-get install amavisd-new spamassassin clamav-daemon

Note: libnet-dns-perl libmail-spf-query-perl pyzor razor are installed as dependencies.

Add contrib and non-free repositories by editing /etc/apt/sources.list and append ” contrib non-free” on every line that starts with deb, and ends with main. You should be looking at something like this:

# deb lenny main

deb lenny main contrib non-free
deb-src lenny main

deb lenny/updates main contrib non-free
deb-src lenny/updates main

deb lenny/volatile main contrib non-free
deb-src lenny/volatile main

After editing sources.list run

apt-get update

Now, we can install utilities for compression and decompression of archives

apt-get install arj bzip2 cabextract cpio file gzip lha nomarch pax rar unrar unzip zip zoo

Add clamav user to the amavis group and vice versa in order for Clamav to have access to scan files:

adduser clamav amavis
adduser amavis clamav

Enable SpamAssassin by editing /etc/default/spamassassin and setting


and start SpamAssassin with

invoke-rc.d spamassassin start

Edit /etc/amavis/conf.d/15-content_filter_mode and ucomment antivirus and spam checking

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 back

@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 back

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

1;  # ensure a defined return

To integrate Amavis with Postfix we need to add the content_filter in /etc/postfix/

content_filter = smtp-amavis:[]:10024

Open /etc/postfix/ and add this at 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 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=
        -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

and add this 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.

Configure Amavis

Edit /etc/amavis/conf.d/50-user and paste this into the file

use strict;

@local_domains_acl = ( ".$mydomain" );

$sa_spam_subject_tag = 'SPAM > ';
$sa_tag_level_deflt  = -999;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 5; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 12; # triggers spam evasive actions

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

#------------ Do not modify anything below this line -------------
1;  # ensure a defined return

Ofcourse, you do not just want to paste stuff into configuration files without knowing what are you actually doing. Se let us go throug the file, line by line:

@local_domains_acl = ( ".$mydomain" );

This is a list of domains for which this server considers itself as a final destination. If you do not add all your domains here, they will not be processed by amavis, so if you have more domains on your server, except for the default line, this should look something like this:

@local_domains_acl = ( ".$mydomain", "", "" );

Later, we will see how can automate this to read the information from the database.

$sa_spam_subject_tag = 'SPAM > ';
$sa_tag_level_deflt  = -999;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 5; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 12; # triggers spam evasive actions

When SpamAssassin processes message, it gives them a score identifying what is the probability of message being a spam. $sa_tag_level_deflt tells amavis that ig the score is greater or equal to this level that amavis should append X-Spam headers to the message. The score of -999 means that we want to apply X-Spam header to all of our messages, so it is easier for us to see why is, or why is not a message considered spam by examining the headers of the message.

$sa_tag2_level_deflt = 5; is the spam level the message needs to reach for amavis to apply the header X-Spam-Flag: YES so we (our mail client) knows that this message is considered to be spam. At this level the message subject is prefixed with the value of the variable $sa_spam_subject_tag. In this case the subject is prefixed with “SPAM > ”.

$sa_kill_level_deflt hold the value of the spam level that message needs to reach to do something with the message. What we are going to do with messages that are spam depends of the value of $final_spam_destiny variable. In this case we are discarding this messages. This means that the message is not going to reach to recipients mailbox at all. But that does not mean that are message is lost. Spam messages that are discarded can still be fetched from the system. Default configuration is to store them in the /var/lib/amavis/virusmails folder. It is possible to store them in the databse, for this you have the add this lines as well:

@lookup_sql_dsn =  ( ['DBI:mysql:database=DATABASE-NAME;host=;port=3306', 'USERNAME', 'PASSWORD']);
@storage_sql_dsn = @lookup_sql_dsn;

$inet_socket_port = [10024,9998];
$interface_policy{'9998'} = 'AM.PDP-INET';
$policy_bank{'AM.PDP-INET'} = {
  protocol => 'AM.PDP',  # select Amavis policy delegation protocol
  inet_acl => [qw( [::1] )],  # restrict access to these IP addresses
# auth_required_release => 0,  # don't require secret_id for amavisd-release

$virus_quarantine_method = 'sql:';
$spam_quarantine_method = 'sql:';
$banned_files_quarantine_method = 'sql:';
$bad_header_quarantine_method = 'sql:';

For this to work, you will have to create the database in MySQL and change the value of @lookup_sql_dsn variable to match your database, username & password. You will have to create the tables for this database by looking at the amavis documentation). When you set this all up, you can use Mailzu or Postvis Admin to retrieve the quarantined messages. For users of SquirrelMail webmail system, there as a plugin called AmavisNewSQL which enables access for users to quarantined messages that were addressed to them.

Note: quarantined messages (on the file system, or in the database) have to be deleted periodically!!!

If you do not want to quarantine any of the messages, change

$virus_quarantine_method = 'sql:';
$spam_quarantine_method = 'sql:';
$banned_files_quarantine_method = 'sql:';
$bad_header_quarantine_method = 'sql:';


$virus_quarantine_method = undef;
$spam_quarantine_method = undef;
$banned_files_quarantine_method = undef;
$bad_header_quarantine_method = undef;

SQL support for amavis, except for easier access to quarantined messages also provides features to change spam setting on a per user basis. Once you create the database, and configure @lookup_sql_dsn this part is very easy achieved by reading through the amavis documentation.

Messages that have a spam value between $sa_tag2_level_deflt and $sa_kill_level_deflt are delivered into the recipients mailbox and marked with “SPAM >” in the subject and have the X-Spam-Flag: YES. Although this may be enough for you, since I use only IMAP access to the mailboxes I wanted to move this messages to the Junk folder inside the users mailbox automatically. This has some benefits: Inbox will not be filled with spam messages, but in case of a false positive, user could check his Junk folder to check for messages marked as spam. This folder can also be used for learning SpamAssassing what is spam, and if users move the messages that are not recognized as spam to this folder instead of deleting them SpamAssassin will get smarter about what is considered to be spam, and what is not.


To enable DKIM checking of received emails in SpamAssassin one has to install Mail::DKIM Perl library.

 apt-get install libmail-dkim-perl

edit /etc/spamassassin/v312.pre and uncomment the line

loadplugin Mail::SpamAssassin::Plugin::DKIM

After that you can run SpamAssassing manually:

spamassassin -D -t < /usr/share/doc/spamassassin/examples/sample-spam.txt 2>&1 | tee sa.out

You should see DKIM mentioned in the sa.out file, and the end of the output should look something like this:

Content analysis details: (1005.3 points, 5.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
-0.0 NO_RELAYS              Informational: message was not relayed via SMTP
1000 GTUBE                  BODY: Generic Test for Unsolicited Bulk Email
 1.5 RAZOR2_CF_RANGE_E4_51_100 Razor2 gives engine 4 confidence level
                            above 50%
                            [cf: 100]
 0.5 RAZOR2_CHECK           Listed in Razor2 (
 0.5 RAZOR2_CF_RANGE_51_100 Razor2 gives confidence level above 50%
                            [cf: 100]
 2.8 PYZOR_CHECK            Listed in Pyzor (
 0.0 DIGEST_MULTIPLE        Message hits more than one network digest check
-0.0 NO_RECEIVED            Informational: message has no Received headers

Restart SpamAssassin daemon

/etc/init.d/spamassassin restart

To learn SpamAssassin what is spam, run the sa-learn utillity on your Junk folder (move into the Junk folder spam, and only spam!!!!)

sa-learn --no-sync --spam /home/vmail/

To learn what is not spam run sa-learn in the folder that only contains your non-spam mail

sa-learn --no-sync --ham /home/vmail/

Bayes filtering will be used once you train SA on more than 200 spam and ham messages.

To update SpamAssassin run

sa-update -D

”-D” is for debug.

debian/anti-spam-anti-virus.txt · Last modified: 2015/03/13 23:29 (external edit)