Setting Up Amavis and ClamAV on Ubuntu Mail Server

This is part 10 in the Ubuntu mail server from scratch tutorial series. In this article, I will show you how to use Amavis and ClamAV to scan viruses in email messages.

Amavis (A Mail Virus Scanner) is a high-performance interface between a message transfer agent (MTA) such as Postfix and content filters. A content filter is a program that scans the headers and body of an email message, and usually takes some action based on what it finds. The most common examples are ClamAV virus scanner and SpamAssassin.

Set Up Amavis and ClamAV on Ubuntu Mail Server

Amavis speaks standard SMTP protocol and can also use the Sendmail milter interface. It’s commonly used for

  • virus-scanning by integrating with ClamAV (Clam AntiVirus)
  • spam-checking by integrating with SpamAssassin
  • DKIM signing and verification. (Actually, I prefer to use OpenDKIM for DKIM signing and verification.)

Prerequisites

You should have completed at least part 1 (Postfix SMTP server) and part 2 (Dovecot IMAP server) of the Ubuntu mail server from scratch tutorial series. Note that if you used iRedMail or Modoboa to set up your mail server, then Amavis and ClamAV are already installed and configured, so you don’t need to follow this tutorial.

Warning: Amavis and ClamAV require a fair amount of RAM. Make sure you have at least 1GB free RAM on your server before installing Amavis and ClamAV. The whole mail server stack (Postfix, Dovecot, Amavis, ClamAV, SpamAssassin, OpenDKIM, MySQL/MariaDB, PostfixAdmin, and Roundcube Webmail) needs at least 2GB RAM. If your RAM runs out, you are going to have troubles like mail server going offline or unresponsive.

Step 1: Install Amavis on Ubuntu

Amvis is available from the default Ubuntu repository, so run the following command to install it.

sudo apt install amavisd-new -y

Once installed, it automatically starts. You can check its status with:

systemctl status amavis

Output:

 amavis.service - LSB: Starts amavisd-new mailfilter
     Loaded: loaded (/etc/init.d/amavis; generated)
     Active: active (running) since Fri 2020-08-07 15:43:40 HKT; 1min 1s ago
       Docs: man:systemd-sysv-generator(8)
      Tasks: 3 (limit: 9451)
     Memory: 75.4M
     CGroup: /system.slice/amavis.service
             ├─1794260 /usr/sbin/amavisd-new (master)
             ├─1794263 /usr/sbin/amavisd-new (virgin child)
             └─1794264 /usr/sbin/amavisd-new (virgin child)

If it’s not running, you can start it with:

sudo systemctl start amavis

Enable auto-start at boot time.

sudo systemctl enable amavis

By default, it listen on 127.0.0.1:10024, as can be seen with:

sudo netstat -lnpt | grep amavis

amavis listening port

And it runs as the amavis user. To check the version number, run

amavisd-new -V

Sample output:

amavisd-new-2.11.0 (20160426)

To check the logs of Amavis, you can run

sudo journalctl -eu amavis

Viruses are commonly spread as attachments to email messages. Install the following packages for Amavis to extract and scan archive files in email messages such as .7z, .cab, .doc, .exe, .iso, .jar, and .rar files.

sudo apt install arj bzip2 cabextract cpio rpm2cpio file gzip lhasa nomarch pax rar unrar p7zip-full unzip zip lrzip lzip liblz4-tool lzop unrar-free

If you use Ubuntu 18.04, then also install the ripole package.

sudo apt install ripole

Note that if your server doesn’t use a fully-qualified domain name (FQDN) as the hostname, Amavis might fail to start. And the OS hostname might change, so it’s recommended to set a valid hostname directly in the Amavis configuration file.

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

Find the following line.

#$myhostname = "mail.example.com";

Remove the comment character (#) and change mail.example.com to your real hostname.

$myhostname = "mail.linuxbabe.com";

Save and close the file. Restart Amavis for the changes to take effect.

sudo systemctl restart amavis

Step 2: Integrate Postfix SMTP Server With Amavis

Amavisd-new works as an SMTP proxy. Email is fed to it through SMTP, processed, and fed back to the MTA through a new SMTP connection.

Edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following line at the end of the file. This tells Postfix to turn on content filtering by sending every incoming email message to Amavis, which listens on 127.0.0.1:10024.

content_filter = smtp-amavis:[127.0.0.1]:10024

Also, add the following line.

smtpd_proxy_options = speed_adjust

This will delay Postfix connection to content filter until the entire email message has been received, which can prevent content filters from wasting time and resources for slow SMTP clients.

Save and close the file. Then edit the master.cf file.

sudo nano /etc/postfix/master.cf

Add the following lines at the end of the file. This instructs Postfix to use a special SMTP client component called smtp-amavis to deliver email messages to Amavis. Please allow at least one whitespace character (tab or spacebar) before each -o.  In postfix configurations, a preceding whitespace character means that this line is continuation of the previous line.

smtp-amavis   unix   -   -   n   -   2   smtp
    -o syslog_name=postfix/amavis
    -o smtp_data_done_timeout=1200
    -o smtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20

Then add the following lines at the end of the file. This tells Postfix to run an additional smtpd daemon listening on 127.0.0.1:10025 to receive email messages back from Amavis.

127.0.0.1:10025   inet   n    -     n     -     -    smtpd
    -o syslog_name=postfix/10025
    -o content_filter=
    -o mynetworks_style=host
    -o mynetworks=127.0.0.0/8
    -o local_recipient_maps=
    -o relay_recipient_maps=
    -o strict_rfc821_envelopes=yes
    -o smtp_tls_security_level=none
    -o smtpd_tls_security_level=none
    -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_end_of_data_restrictions=
    -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,no_address_mappings

Save and close the file. Restart Postfix for the changes to take effect.

sudo systemctl restart postfix

Step 3: Integrate Amavis with ClamAV

Now that Postfix can pass incoming emails to Amavis, we need to install the ClamAV virus scanner and integrate it with Amavis, so incoming emails can be scanned by ClamAV.

Install ClamAV on Ubuntu.

sudo apt install clamav clamav-daemon

There will be two systemd services installed by ClamAV:

  • clamav-daemon.service: the Clam AntiVirus userspace daemon
  • clamav-freshclam.service: the ClamAV virus database updater

First, check the status of clamav-freshclam.service.

systemctl status clamav-freshclam

clamav-freshclam-ubuntu-20.04

As you can see, it’s active (running) and uses 217.6M RAM on my mail server. Then check the journal/log.

sudo journalctl -eu clamav-freshclam

Output:

ClamAV virus database updater

Hint: If the above command doesn’t quit immediately, press the Q key to make it quit.

We can see that freshclam downloaded 3 virus databases. CVD stands for ClamAV Virus Database.

  • daily.cvd
  • main.cvd
  • bytecode.cvd

However, clamd was not notified because freshclam can’t connect to clamd through /var/run/clamav/clamd.ctl. Check the status of clamav-daemon.service.

systemctl status clamav-daemon

Output:

clamav-daemon ubuntu 20.04

As you can see, it failed to start because a condition wasn’t met. In the /lib/systemd/system/clamav-daemon.service file, there are two conditions:

ConditionPathExistsGlob=/var/lib/clamav/main.{c[vl]d,inc}
ConditionPathExistsGlob=/var/lib/clamav/daily.{c[vl]d,inc}

The clamav-daemon.service failed to start because main.cvd and daily.cvd were not downloaded yet when it starts. So we just need to restart this service.

sudo systemctl restart clamav-daemon

Now it should be running. By the way, it uses 731.4M RAM on my mail server. If your mail server doesn’t have enough RAM left, the service will fail.

systemctl status clamav-daemon.service

clamav-daemon.service ubuntu 20.04

The clamav-freshclam.service will check ClamAV virus database updates once per hour.

Now we need to turn on virus-checking in Amavis.

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

Uncomment the following lines to enable virus-checking.

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

ubuntu amavis turn on virus checking

Save and close the file. There are lots of antivirus scanners in the /etc/amavis/conf.d/15-av_scanners file. ClamAV is the default. Amavis will call ClamAV via the /var/run/clamav/clamd.ctl Unix socket. We need to add user clamav to the amavis group.

sudo adduser clamav amavis

Then restart Amavis and ClamAV daemon for the changes to take effect.

sudo systemctl restart amavis clamav-daemon

Check the logs.

sudo journalctl -eu amavis

You can see that Amavis is now using ClamAV to scan viruses.

Aug 08 17:26:19 mail.linuxbabe.com amavis[1233432]: Using primary internal av scanner code for ClamAV-clamd
Aug 08 17:26:19 mail.linuxbabe.com amavis[1233432]: Found secondary av scanner ClamAV-clamscan at /usr/bin/clamscan

Now if you send an email from other mail servers like Gmail to your own mail server and check the email headers, you can find a line like below, which indicates this email has been scanned by Amavis.

X-Virus-Scanned: Debian amavisd-new at linuxbabe.com

You should also check the mail log (/var/log/mail.log) to find if there are any errors.

Step 4: Use A Dedicated Port for Email Submissions

ClamAV can scan both incoming and outgoing emails now. Amavis listens on port 10024 for both incoming and outgoing email messages. However, it’s a good practice to use a different port such as 10026 for email submissions from authenticated users. Edit the Amavis configuration file.

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

Custom settings should be added between the use strict; and 1; line. By default, Amavis only listens on port 10024. Add the following line to make it also listen on port 10026.

$inet_socket_port = [10024,10026];

Then add the following line, which sets the “ORIGINATING” policy for port 10026.

$interface_policy{'10026'} = 'ORIGINATING';

Next, add the following lines, which define the “ORIGINATING” policy.

$policy_bank{'ORIGINATING'} = {  # mail supposedly originating from our users
  originating => 1,  # declare that mail was submitted by our smtp client
  allow_disclaimers => 1,  # enables disclaimer insertion if available

  # notify administrator of locally originating malware
  virus_admin_maps => ["virusalert\@$mydomain"],
  spam_admin_maps  => ["virusalert\@$mydomain"],
  warnbadhsender   => 1,

  # force MTA conversion to 7-bit (e.g. before DKIM signing)
  smtpd_discard_ehlo_keywords => ['8BITMIME'],
  bypass_banned_checks_maps => [1],  # allow sending any file names and types
  terminate_dsn_on_notify_success => 0,  # don't remove NOTIFY=SUCCESS option
};

Save and close the file. Restart Amavis.

sudo systemctl restart amavis

Check its status to see if the restart is successful.

systemctl status amavis

Next, edit the Postfix master configuration file.

sudo nano /etc/postfix/master.cf

Add the following line to the submission service, so emails from authenticated SMTP clients will be passed to Amavis listening on port 10026. This line will override (-o) the content_filter paramter in /etc/postfix/main.cf file.

 -o content_filter=smtp-amavis:[127.0.0.1]:10026

Like this:

ubuntu postfix submissions amavis port 10026

If you have enabled the smtps service for Microsoft Outlook users, then you also need to add this line to the smtps service.

Save and close the file. Restart Postfix for the changes to take effect.

sudo systemctl restart postfix

Check its status to see if the restart is successful.

systemctl status postfix

Spam Filtering in Amavis

Note: If you have followed my SpamAssassin tutorial, you don’t need to enable spam-checking in Amavis. If you enable it, each email will be checked twice by SpamAssassin.

To enable spam-checking in Amavis, install SpamAssassin and related packages.

sudo apt install spamassassin libnet-dns-perl libmail-spf-perl pyzor razor

Edit an Amavis configuration file.

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

Uncomment the following lines to enable spam-checking.

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

Save and close the file. Then restart Amavis.

sudo systemctl restart amavis

DKIM in Amavis

Two common pieces of software that can do DKIM signing and verification on Linux are OpenDKIM and Amavis. I prefer to use OpenDKIM because it works better with OpenDMARC. So I won’t explain how to DKIM sign your email in Amavis.

By default, Amavis can verify the DKIM signature of incoming email messages. If you have OpenDKIM running on your mail server, then you can disable DKIM verification in Amavis.

sudo nano /etc/amavis/conf.d/21-ubuntu_defaults

Find the following line and change 1 to 0, so Amavis won’t verify DKIM signatures.

$enable_dkim_verification = 1;

Save and close the file. Then restart Amavis.

sudo systemctl restart amavis

When receiving incoming emails, Postfix will call OpenDKIM via the sendmail milter interface to verify DKIM signatures, then pass the email to Amavis for virus-checking. When sending outgoing emails, Postfix will call OpenDKIM to sign the emails, then pass them to Amavis for virus-checking.

Improving Amavis Performance

By default, Amavis runs 2 processes. If you see the following lines in the mail log (/var/log/mail.log), it means Amavis can’t process emails fast enough.

postfix/qmgr[1619188]: warning: mail for [127.0.0.1]:10024 is using up 4001 of 4008 active queue entries
postfix/qmgr[1619188]: warning: you may need to reduce smtp-amavis connect and helo timeouts
postfix/qmgr[1619188]: warning: so that Postfix quickly skips unavailable hosts
postfix/qmgr[1619188]: warning: you may need to increase the main.cf minimal_backoff_time and maximal_backoff_time
postfix/qmgr[1619188]: warning: so that Postfix wastes less time on undeliverable mail
mail postfix/qmgr[1619188]: warning: you may need to increase the master.cf smtp-amavis process limit
mail postfix/qmgr[1619188]: warning: please avoid flushing the whole queue when you have
mail postfix/qmgr[1619188]: warning: lots of deferred mail, that is bad for performance

To improve performance, edit Amavis configuration file.

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

Add the following line in the file between the use strict; and 1; line. This will make Amavis run 4 processes. If you have 10 CPU cores, you can change 4 to 10. Note that running more than 10 Amavis processes has little effect on performance.

$max_servers = 4;

Save and close the file. Then edit the Postifx master configuration file.

sudo nano /etc/postfix/master.cf

Find the smtp-amavis service definition, and change the process limit from 2 to 4.

smtp-amavis   unix   -   -   n   -   4   smtp
    -o syslog_name=postfix/amavis
    -o smtp_data_done_timeout=1200
    -o smtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20

Save and close the file. Then restart Amavis and Postfix for the changes to take effect.

sudo systemctl restart amavis postfix

Now run the following command. You should see that there are 4 Amavis processes now.

sudo amavisd-nanny

sudo amavisd-nanny

Press Ctrl+C to stop amavisd-nanny.

Wrapping Up

I hope this tutorial helped you set up Amavis and ClamAV on Ubuntu mail server. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial
[Total: 1 Average: 5]You have already voted for this article

6 Responses to “Setting Up Amavis and ClamAV on Ubuntu Mail Server

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.


The maximum upload file size: 2 MB.
You can upload: image.