Now we have a fully-functional mail server, able to send and receive email and providing remote access to users' mailboxes. However, if we don't want our server to become an immune carrier of computer viruses or to be drowned under a sea of spam, we need to install all the necessary content-filtering tools.
Though Postfix natively supports multiple content inspection mechanisms, the documentation itself encourages the use of external filters and standard protocols because this allows you to choose the best MTA and the best content inspection software for your purpose
. Therefore, we will rely on third-party software for content filtering; in particular, we will use SpamAssassin to filter spam, ClamAV to check emails for viruses and Amavisd-new to coordinate it all. Below is the outline of the whole architecture:
SpamAssassin is a mature, widely-deployed open source project that serves as a mail filter to identify Spam. SpamAssassin uses a variety of mechanisms including header and text analysis, Bayesian filtering, DNS blocklists, and collaborative filtering databases
.
There are quite a few packages we need to install:
After the packages installation, you will find the main SpamAssassin configuration file (local.cf) in the fresh new /etc/mail/spamassassin directory. The configuration phase can be very complex and goes beyond the scope of this document; anyway, you can find all the details in the man page (Mail::SpamAssassin::Conf).
Like Postfix, SpamAssassin has a lot of configuration parameters, although, in most cases, default values can be preserved and only a few parameters need to be overridden:
rewrite_header Subject ***** SPAM ***** report_safe 1 lock_method flock required_score 8.0
ClamAV is a GPL anti-virus toolkit for UNIX
; the main purpose of this software is the integration with mail servers (i.e. attachment scanning). All the antivirus tasks are handled by three processes:
The required packages are:
The freshclam.conf configuration file requires only a few parameters:
DatabaseDirectory /var/db/clamav DatabaseOwner _clamav DNSDatabaseInfo current.cvd.clamav.net DatabaseMirror db.it.clamav.net DatabaseMirror database.clamav.net MaxAttempts 3 checks 24
Now we can update the virus definition database by running the freshclam command. Please make sure you have installed the latest release of ClamAV, or you'll get warning messages about reduced functionality, like the following:
# freshclam ClamAV update process started at Tue Dec 18 00:35:25 2007 WARNING: Your ClamAV installation is OUTDATED! WARNING: Local version: 0.90.3 Recommended version: 0.92 DON'T PANIC! Read http://www.clamav.net/support/faq Downloading main.cvd [100%]main.cvd [ 22%] main.cvd updated (version: 45, sigs: 169676, f-level: 21, builder: sven) WARNING: Your ClamAV installation is OUTDATED! WARNING: Current functionality level = 16, recommended = 21 DON'T PANIC! Read http://www.clamav.net/support/faq Downloading daily.cvd [100%] daily.cvd updated (version: 5160, sigs: 8698, f-level: 21, builder: sven) WARNING: Your ClamAV installation is OUTDATED! WARNING: Current functionality level = 16, recommended = 21 DON'T PANIC! Read http://www.clamav.net/support/faq Database updated (178374 signatures) from db.it.clamav.net (IP: 193.206.139.37) #
The reduced "functionality level" means that you may not be able to use all the available virus signatures and, consequently, fail to detect the latest viruses. To automatically update the database, we simply have to schedule freshclam in crontab every hour (preferably not on the hour, just to avoid traffic peaks):
16 * * * * /usr/local/bin/freshclam >/dev/null 2>&1
Also the /etc/clamd.conf configuration file needs editing only very few parameters:
DatabaseDirectory /var/db/clamav LocalSocket /var/clamav/clamd.sock User _clamav [...]
Now we can run clamd:
# touch /var/log/clamd.log # chown _clamav /var/log/clamd.log # clamd Running as user _clamav (UID 539, GID 539)
and add the following lines to /etc/rc.local(8) to start it on system boot:
if [ -x /usr/local/sbin/clamd ]; then
echo -n ' clamd'
[ -S /var/clamav/clamd.sock ] && rm -f /var/clamav/clamd.sock
/usr/local/sbin/clamd >/dev/null 2>&1
fi
Amavisd-new is a high-performance interface between mailer (MTA) and content checkers
. We will configure it to bind to port 10024 on the loopback interface, where Postfix will forward all incoming e-mails. If the e-mail successfully passes all the checks, it will be forwarded back to Postfix, listening on localhost port 10025; otherwise, mails may be deleted or quarantined and the administrator and recepients may be notified.
The following is the list of the required packages:
The installation procedure creates a new user and group called _vscan; however, the easiest way to get Amavisd-new to cooperate with ClamAV, is to run them both under the same user (_clamav). The configuration file is /etc/amavisd.conf, which is actually a perl script (so pay attention to the semi-colons at the end of the lines!); below are the options you will most likely want to tweak:
# COMMONLY ADJUSTED SETTINGS:
$max_servers = 2;
$daemon_user = '_clamav'; # Run under the same user as ClamAV
$daemon_group = '_clamav'; # Run under the same group as ClamAV
$mydomain = 'kernel-panic.it';
$MYHOME = '/var/amavisd';
$TEMPBASE = "$MYHOME/tmp"; # Working directory, needs to be created manually
$ENV{TMPDIR} = $TEMPBASE;
$QUARANTINEDIR = '/var/clamav/quarantine';
[...]
# Leave only ClamAV uncommented
@av_scanners = (
['ClamAV-clamd',
\&ask_daemon, ["CONTSCAN {}\n", "/var/clamav/clamd.sock"],
qr/\bOK$/, qr/\bFOUND$/,
qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
);
[...]
# Leave only ClamAV uncommented
@av_scanners_backup = (
['ClamAV-clamscan', 'clamscan',
"--stdout --disable-summary -r --tempdir=$TEMPBASE {}", [0], [1],
qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
);
1;
After manually creating Amavisd-new's working directory (/var/amavisd/tmp), we can start the daemon in debug mode (i.e. in foreground), just to check any errors:
# mkdir /var/amavisd/tmp # chown -R _clamav:_clamav /var/amavisd/ # /usr/local/sbin/amavisd debug Dec 18 22:07:11 mail.kernel-panic.it /usr/local/sbin/amavisd[24429]: starting. /usr/local/sbin/amavisd at mail.kernel-panic.it amavisd-new-2.3.2 (20050629), Unicode aware Dec 18 22:07:11 mail.kernel-panic.it /usr/local/sbin/amavisd[24429]: user=, EUID: 0 (0); group=, EGID: 0 31 20 5 4 3 2 0 (0 31 20 5 4 3 2 0) Dec 18 22:07:11 mail.kernel-panic.it /usr/local/sbin/amavisd[24429]: Perl version 5.008008 [...]
Now we can configure the system to start Amavisd-new on boot:
if [ -x /usr/local/sbin/amavisd ]; then
echo -n ' amavisd'
/usr/local/sbin/amavisd >/dev/null 2>&1
fi
The last step is to update Postfix configuration to enable interfacing between Postfix and Amavisd-new. To achieve this, we have to add a couple of services to the /etc/postfix/master.cf(5) configuration file: one to forward all incoming emails to Amavid-new, and the other to get emails back again:
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 mynetworks_style=host
-o mynetworks=127.0.0.0/8
-o strict_rfc821_envelopes=yes
-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
Finally, we need to tell Postfix to start forwarding all the emails it receives to amavisd-new for content inspection and reload the configuration.
# postconf -e 'content_filter=smtp-amavis:[127.0.0.1]:10024' # postfix reload postfix/postfix-script: refreshing the Postfix mail system