Integrating a virus scanner into a mail server

Windows dominates the desktop market with 90 percent of the market share [1], much of which is still dominated by Windows XP machines. This situation presents an enormous potential for virus and malware spreading, even when these machines are updated with the latest service packs. Meanwhile, about half the world's servers now run Linux or UNIX.

The widespread use of Linux servers, including in large server farms at Google, Facebook, and the like, would suggest that such computers present an attractive target for attacks by malicious software. Interestingly, this is hardly the case. The truth doesn't lie in the system architecture alone, because the security concepts of current Windows versions aren't that different from those of Linux or Unix.

Secure Linux?

With Linux and Unix, as well as in Windows, users have different rights. On UNIX-like systems, users can gain access only to their own files and those for which they're granted explicit rights. Administrative rights are reserved for the root user. Windows, in principle, could use the same concept, but this is virtually impossible to implement, because the system requires administrative rights for almost all activities; otherwise, many programs would not run correctly.

That's why Microsoft granted users extended rights up until Windows XP. From Windows Vista onward, however, a user prompt at least preceded a switch to administrator mode.

Still, the Windows default user had full administrator rights: All started processes have access to all parts of the system. In Linux and Unix, only su or sudo can switch to the mode with an effective user ID of 0 (root). By default, no user has administrator privileges.

The statement is often heard that Windows is a perfect target for malware on account of its software errors. The truth is that Windows, Linux, and Unix have equal vulnerability in terms of programming errors, conceptual failures, buffer overflows, and similar weaknesses, which is confirmed by the release notes for updates. The differences in the systems lie rather in the configuration, where Windows often sacrifices security in favor of convenience. This is due to the fact that typical Windows users have a totally different attitude with respect to the computer system than Linux users.

A Linux desktop, therefore, is not inherently more secure than a Windows machine. The difference is that Linux systems do not offer services on all possible ports to the outside – to the point that "personal firewalls" is virtually a foreign concept for Linux. Virus scanners in Linux scan data for other systems that have inadequate protection against attacks.

AV Software on Linux

There are many virus scanners for Linux. Emergency kits, such as Avira, F-Secure, and Bitdefender Rescue, all run on Linux systems. You start such rescue programs as a Linux Live system either from a CD or USB stick. They can also easily be booted using PXE from a server.

All major Linux distributions provide installations for the AMaViS [2] and ClamAV [3] packages. ClamAV is the actual virus scanner, whereas AMaViS integrates it with a mail system. Several other free systems, such as Bitdefender, Sophos, and AVG, are also available. Systems that come with a price tag include Kaspersky, Trend Micro, and others. In this article, I'll show how to arm a Linux server with a virus scanner based on ClamAV and AMaViS for scanning directories and emails for malware.

ClamAV

All major Linux distributions have either ClamAV/AMaViS installation packages or at least allow adding repositories from which to extract these packages. In Ubuntu, you can simply use

$ sudo apt-get install clamav

Steer clear of installing from the source code. Distributions often use specifically patched kernels and libraries that don't necessarily get along with non-native versions of software. On Debian and its derivates (e.g., Ubuntu, Knoppix, Raspian, and others) you should install, apart from ClamAV, the ClamAV daemon and freshclam. You must first update the signatures through freshclam after installation. It's recommended to run the program regularly with a cron job (Listing 1).

Listing 1

Refreshing Virus List

$ echo "0 4 * * * /usr/bin/freshclam" > cron.txt
$ sudo crontab -u root cron.txt

Next, test the virus scanner. Download the harmless EICAR virus signature file (eicar.com.txt ) [4] and test it by entering clamscan eicar.com.txt . If you get the message eicar.com.txt: Eicar-Test-Signature FOUND , the scanner is working correctly. Remember to delete the signature file, or you'll get recurring alarms along the way. ClamTk [5] provides a graphical interface for ClamAV, which can make settings and scan requests a bit easier (Figure 1).

Figure 1: The ClamTK graphical front end makes setting up and operating the free ClamAV virus scanner easy.

AMaViS

A file- or directory-oriented virus scanner like ClamAV is particularly useful for scanning incoming emails for viruses. AMaViS is specialized for this and works just as easily as other installed virus scanners. AMaViS works over an SMTP port interface compatible with Sendmail, Postfix, Exim, and numerous other SMTP mail transfer agents (MTAs).

In the following section, I'll describe an AMaViS configuration with a Postfix MTA. The snippet of a mail header in Listing 2 shows quite clearly how the scan works. The email first arrives at the mail server, which stores an MX record for the author's mail domain. The server then gets the message using a fetchmail daemon through POP3 from the author's server and passes it on to port 25 (SMTP) to the local Postfix SMTP server. The Postfix daemon forwards all messages arriving on port 25 and port 587 (MSA) to AMaViS over port 10024. MSA (mail submission agent) is a variant of SMTP that uses mandatory authentication, with clear differentiation between local and remote users designed to prevent configuration problems and spam.

Listing 2

Email Header Showing Scan Information

Delivered-To: fritz@fhotz.local
Received: from localhost (localhost [127.0.0.1])
  by fhserver.fhotz.local (Postfix) with ESMTP id 5BC84420565
  for <fritz@fhotz.local>; Tue, 14 Oct 2014 21:36:22 +0200 (CEST)
X-Virus-Scanned: amavisd-new at fhotz.local
Received: from smtp.efhotz.de ([127.0.0.1])
  by localhost (fhserver.fhotz.local [127.0.0.1]) (amavisd-new, port 10024)
  with ESMTP id Igt25lhcMl0o for <fritz@fhotz.local>;
  Tue, 14 Oct 2014 21:36:20 +0200 (CEST)
Received: from fhserver.fhotz.local (localhost [IPv6:::1])
  by fhserver.fhotz.local (Postfix) with ESMTP id 1B71842001B
  for <fritz@fhotz.local>; Tue, 14 Oct 2014 21:36:20 +0200 (CEST)
Received: from pop.1und1.de [212.227.15.178]
  by fhserver.fhotz.local with POP3 (fetchmail-6.3.26)
  for <fritz@fhotz.local> (single-drop); Tue, 14 Oct 2014 21:36:20 +0200 (CEST)
Received: from mail.linux-new-media.de ([62.245.157.204]) by
  mx.emig.kundenserver.de (mxeue101) with ESMTP (Nemesis) id
  0MarX8-1Xtzkv4C0w-00KN0M for <Friedrich.Hotz@ef-hotz.de>; Tue, 14 Oct 2014
  21:34:28 +0200
Received: from localhost (mail.linux-new-media.de [62.245.157.204])
  by mail.linux-new-media.de (Postfix) with ESMTP id B432E169D
  for <Friedrich.Hotz@ef-hotz.de>; Tue, 14 Oct 2014 21:34:27 +0200 (CEST)

After the AMaViS virus scan, the email is further directed to Postfix, this time over port 10025, so that the mail doesn't loop endlessly between Postfix and AMaViS. Finally, the email arrives at the recipient's mailbox.

Setting up AMaViS

AMaViS is installable from repositories of all the major distributions so it's easy to set up with the package manager. To integrate the software with the MTA, open the /etc/postfix/main.cf file and add the following line:

content_filter=amavis:[127.0.0.1]:10024

This causes Postfix not to forward any mail (other than what arrives on port 10025) automatically but to send it to AMaViS for review. The /etc/amavisd.conf file also requires you to check or change some settings (Listing 3).

Listing 3

Changes in /etc/amavisd.conf

# cat /etc/amavisd.conf
$max_servers = 20;           # num of pre-forked children (2..30 is common), -m
$daemon_user  = 'vscan';     # (no default;  customary: vscan or amavis), -u
$daemon_group = 'vscan';     # (no default;  customary: vscan or amavis), -g
$mydomain = 'fhotz.local';   # a convenient default for other settings
@mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10 192.168.0.0/16 );
$unix_socketname = "$MYHOME/amavisd.sock";  # amavisd-release or amavis-milter
               # option(s) -p overrides $inet_socket_port and $unix_socketname
$inet_socket_port = 10024;   # listen on this local TCP port(s)

For Postfix to work effectively with AMaViS and disallow submissions not only on ports 25 and 587 but also on port 20025, you can add Listing 4 to the /etc/postfix/master.cf file.

Listing 4

/etc/postfix/master.cf

# cat /etc/postfix/master.cf
amavis   unix  -      -       n       -        20      smtp
        -o smtpd_tls_security_level=may
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes
        -o max_use=20
localhost: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_tls_security_level=may
  -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_unknown_recipient_checks,no_header_body_checks,\
no_address_mappings
  -o local_header_rewrite_clients=
  -o local_recipient_maps=
  -o relay_recipient_maps=

Next, you must ensure that the daemon is ready to address queries on port 10024. After making the configuration changes, restart the daemon again with the service amavis restart or the systemctl restart amavis.service command.

Follow up with a test message to AMaViS using a simple telnet dialog (Listing 5). This test message should then land in the recipient's mailbox, as shown by the mail header (Listing 6).

Listing 5

Testing Your Configuration with Telnet

$ telnet localhost 10024
220 [::1] ESMTP amavisd-new service ready
helo
250 [::1]
mail from: <testuser>
250 2.1.0 Sender <testuser> OK
rcpt to: fritz@fhotz.local
250 2.1.5 Recipient <fritz@fhotz.local> OK
data
354 End data with <CR><LF>.<CR><LF>
from:me
to:you
subject:Testmail with Amavis
Hello. This is scanned by Amavis.
250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 42E7D42020C
quit
221 2.0.0 [::1] amavisd-new closing transmission channel
Connection closed by foreign host.

Listing 6

Email Header from Telnet Test

Return-Path: testuser@fhotz.local
X-Original-To: fritz@fhotz.local
Delivered-To: fritz@fhotz.local
Received: from localhost (localhost [127.0.0.1])
  by fhserver.fhotz.local (Postfix) with ESMTP id 42E7D42020C
  for <fritz@fhotz.local>; Mon, 20 Oct 2014 11:41:16 +0200 (CEST)
X-Quarantine-ID: <CswUSUl0jnLO>
X-Virus-Scanned: amavisd-new at fhotz.local
X-Spam-Flag: NO
X-Spam-Score: 2.781
Received: from unknown ([IPv6:::1])
  by localhost (fhserver.fhotz.local [IPv6:::1]) (amavisd-new, port 10024)
  with SMTP id CswUSUl0jnLO for <fritz@fhotz.local>;
  Mon, 20 Oct 2014 11:40:06 +0200 (CEST)
from:me
to:you
subject:Testmail with Amavis

From this point on, AMaViS checks all messages using ClamAV and sorts out any questionable ones. You can test the functionality by sending the previously mentioned EICAR test file to yourself, which should not arrive in your mailbox.