Debian Jessie Mail Server using Postfix, Dovecot, OpenDKIM, Spamassassin, Amavisd-new and ClamAV

By | March 22, 2016

In this post we will see a Debian Jessie Mail Server using Postfix, Dovecot, OpenDKIM, Spamassassin, Amavisd-new and ClamAV.
I will not be digging into the details of the working of mail systems.How ever you may find some good information here. Our test domain is ‘’ and the FQDN of our mail server is ‘’. This is a very simple mail server configuration. The mail users will be local users in the mail server who will be authenticating with their credentials based on the file ‘/etc/passwd‘. The conventional unix ‘mbox’ based inbox will not be used. Instead this configuration will store mails in the ‘Maildir‘ directory inside a user’s home directory.

1) Generate self signed ssl certificates

cd /etc/ssl
openssl genrsa -out 2048
openssl req -new -key -out
openssl x509 -req -days 365 -in -signkey -out

2) Install postfix and dovecot

Debian Jessie by default makes use of ‘exim4‘ for smtp services. So firstly we will remove ‘exim4‘ and then install ‘postfix‘ and ‘dovecot‘.

apt-get remove --purge exim4 exim4-config
apt-get install postfix dovecot-imapd bsd-mailx

Select “Internet site” and define the “Mail System Name” as described below when the tui window for postfix configuration starts. Use the  images  below as reference:



3) Configure dovecot

Change directory to  ‘/etc/dovecot/conf.d’ and backup the file ’10-auth.conf’

cd /etc/dovecot/conf.d
cp -R 10-auth.conf 10-auth.conf.bak

In ‘10-auth.conf’, file, enable plain and login authentication mechanisms:

auth_mechanisms = plain login

Backup ’10-mail.conf’  file first,

cp -R 10-mail.conf 10-mail.conf.bak

and then edit it to update the  ‘mail_location’

mail_location = maildir:~/Maildir 

Backup ’10-ssl.conf ‘ file first

cp -R 10-ssl.conf 10-ssl.conf.bak

and edit it in order to insert the correct ssl cert and key file path

ssl = yes
ssl_cert = </etc/ssl/
ssl_key = </etc/ssl/

Backup ‘ 10-master.conf’ file and then edit it so that we can use dovecot’s SMTP authentication service in postfix to authenticate the email accounts

cp -R 10-master.conf 10-master.conf.bak

change the existing commented dovecot SMTP authentication lines to the ones silmilar to ones mentioned below

 # Postfix smtp-auth
 unix_listener /var/spool/postfix/private/auth {
 mode = 0666

Restart the dovecot service now.

/etc/init.d/dovecot restart

4) Configure postfix

Backup the files ‘/etc/postfix/’ and ‘/etc/postfix/’

 cp -R /etc/postfix/ /etc/postfix/
 cp -R /etc/postfix/ /etc/postfix/

Edit the ‘/etc/postfix/’ file and compare these values that are listed below with the ones that are present in it  and add/change the required values in it (Replace ‘‘ and ‘‘ with the your domain specific values)

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
append_dot_mydomain = no
readme_directory = no
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname =
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination =,,, localhost
relayhost =
mynetworks = [::ffff:]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
home_mailbox = Maildir/
## Basic SMTP Housekeeping ##
smtpd_helo_required = yes
disable_vrfy_command = yes
## The maximum size of any email is restricted to 20 MB ##
message_size_limit = 20480000
## SMTP Auth Settings ##
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_rbl_client, reject_rbl_client, reject_rbl_client

Enable submission and smtps ports by removing the comments (#) from the following lines in the file ‘/etc/postfix/

submission inet n - - - - smtpd
 -o syslog_name=postfix/submission
 -o smtpd_tls_security_level=encrypt
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
 -o milter_macro_daemon_name=ORIGINATING
smtps inet n - - - - smtpd
 -o syslog_name=postfix/smtps
 -o smtpd_tls_wrappermode=yes
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
 -o milter_macro_daemon_name=ORIGINATING

Restart postfix service

/etc/init.d/postfix restart

Create an email account

 adduser --shell /sbin/nologin jake

Connect to the new email account ‘’ using mozilla thunderbird email client

Email_client_11-min Email_client_21-min Email_client_31-min

5) Install and configure OpenDKIM

DKIM is an Internet Standard that enables a person or organisation to associate a domain name with an email message. This, in effect, serves as a method of claiming responsibility for a message. At its core, DKIM is powered by asymmetric cryptography. The sender’s Mail Transfer Agent (MTA) signs every outgoing message with a private key. The recipient retrieves the public key from the sender’s DNS records and verifies if the message body and some of the header fields were not altered since the message signing took place.

apt-get install opendkim opendkim-tools
mkdir /etc/opendkim
mkdir /etc/opendkim/keys
mkdir /etc/opendkim/keys/

Backup the the file ‘/etc/opendkim.conf

cp -R /etc/opendkim.conf /etc/opendkim.conf.bak

Edit ‘/etc/opendkim.conf’ and make the following changes:

Syslog yes
SyslogSuccess Yes
LogWhy Yes
UMask 002
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
Canonicalization relaxed/simple
Mode sv
AutoRestart Yes
AutoRestartRate 10/1h
OversignHeaders From
PidFile /var/run/opendkim/
SignatureAlgorithm rsa-sha256
UserID opendkim:opendkim
Socket inet:8891@localhost

Open the file ‘/etc/default/opendkim‘ and add the socket information at the end of the file as listed below:


Create the necessary DKIM private key and public keys

 opendkim-genkey -D /etc/opendkim/keys/ -d -s mail
 chown -R opendkim: /etc/opendkim/keys/
 mv /etc/opendkim/keys/ /etc/opendkim/keys/

Edit the KeyTable file ‘/etc/opendkim/KeyTable’ and add the following line at the end of the file

Edit the SigningTable file ‘/etc/opendkim/SigningTable’ and add the following line at the end of the file


Add the trusted hosts in the file ‘/etc/opendkim/TrustedHosts’ as shown below. Make sure you change with your actual domain name.

View the entries that are needed to populate your DNS TXT records

 cat /etc/opendkim/keys/

You will see something similar to this:

mail._domainkey IN TXT ( “v=DKIM1; k=rsa; “
“p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPEMKZx8tQPnhmoNSJpi2rtCM3NRctHmE/DZEmmNReEU3hyC86rgKgm5vCUz4rJ3/4XIj4VbcZND6+hH2WNYnMqAn4+h+ZCdgB5GmT3PxQE5/SYJSFZCW9ezTDnDrjSBBnJ+2xtupuUaVXXpLRfOj6aMSebtlGO/WlQfkOEqFBCwIDAQAB” ) ; —– DKIM key mail for

This information is needed to create A TXT record in your domain’s DNS entries. In the NAME field we need to put the above text in RED color. And in the VALUE field we need to put the above text in blue color and save. Please note that the DNS changes may take a couple of hours to propagate.

Integrate OpenDKIM in postfix by adding the following lines at the end of ‘/etc/postfix/’ file

smtpd_milters           = inet:
non_smtpd_milters       = $smtpd_milters
milter_default_action   = accept
milter_protocol         = 2

Start the OpenDKIM service

/etc/init.d/opendkim restart
/etc/init.d/postfix restart

6) Install spam and virus filtration modules amavisd-new, spamassassin, clamav and integrate avamis with postfix

apt-get install amavisd-new spamassassin clamav-daemon clamav libnet-dns-perl libmail-spf-perl pyzor razor arj bzip2 cabextract cpio file gzip lhasa nomarch pax rar unrar unzip zip zoo p7zip

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

sudo adduser clamav amavis
sudo adduser amavis clamav

As ‘amavis‘ is its own ‘spamassassin-daemon‘ so there is no need in configuring or starting ‘spamassassin‘.

The use of ‘razor‘ and ‘pyzor‘ must be enabled by

su - amavis -s /bin/bash
razor-admin -create
razor-admin -register
pyzor discover

There is no need of configuring razor or pyzor.

Activate spam and antivirus detection in Amavis by editing and un-commenting the following lies in the file ‘/etc/amavis/conf.d/15-content_filter_mode

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

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

Change the value of ‘AllowSupplementaryGroups‘ from ‘false‘ to ‘true‘ in the file ‘/etc/clamav/clamd.conf

AllowSupplementaryGroups true

Start ‘amavis‘ and  start ‘clamav-daemon‘ service

/etc/init.d/amavis restart
/etc/init.d/clamav-daemon start

Edit the Postfix configuration file ‘/etc/postfix/‘ and the following line at the end. This   instructs ‘postfix‘ to pass messages to ‘amavis‘ for scanning at a given IP address and port:

content_filter = smtp-amavis:[]:10024

Next edit ‘/etc/postfix/’ 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 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

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.

Reload postfix:

/etc/init.d/postfix reload

Thus we have functional mail server ready here.

Ok. confession time… The spam filtration part has been heavily borrowed from and altered slightly to make it work Debian Jessie.

Please feel free to have a look at my earlier post  here if you would like to integrate Roundcube webmail to this setup. I was able to integrate the current stable version of Roundcube (version 1.0.8) with this mail setup using the same documentation.


10 thoughts on “Debian Jessie Mail Server using Postfix, Dovecot, OpenDKIM, Spamassassin, Amavisd-new and ClamAV

  1. johnatan lopes

    good evening , I performed as settings As Your tutorial.

    When testing the sending only emails to gmail usually gets the main box.

    The hotmail and yahoo receive directly in the spam box,
    performed the settings of SPF and DKIM , but in the yahoo header returns:

    Authentication-Results:; domainkeys=neutral (no sig);; dkim=pass (ok)

    Would you help me?

    1. rudraraj Post author

      Hi Johnathan,
      Let us carry forward this discussion on email. Please check your inbox.

  2. Justin

    Hi, quick question, does this tutorial also cover the mechanics of receiving email too? I’ve tested outgoing, it works well. But I do not get a reply back when I should.

    What can I do to receive email? I followed this tutorial to a T, which worked really well, you put in some great detail. But wish I could get receiving working too. I’m currently using Alpine instead of Thunderbird.

    Thanks a lot for the effort, look forward to hearing back from you.

    1. rudraraj Post author

      Thank You Justin for your kind words.

      I’ve tested outgoing, it works well. But I do not get a reply back when I should.
      Are you not getting the replies back to the sent mails or is it so that you get the replies and it is a little late to reflect in your inbox?
      If you are not getting the replies, do you get any failure message on the sender’s side. If yes, then we probably need to look at the error messages to figure out what is causing the failure in email delivery.
      Also I have to admit, I have never user used Alpine.

  3. Ganesh

    This blank line after “Pick up” transport service is generating issues
    -o content_filter=

    Did we need to add anything after = symbol

    1. rudraraj Post author

      Hi Ganesh,
      Sorry for a late response. You just need to add those two lines after the pickup transport service. Please try to write the lines manually, rather than doing a copy paste. Sometimes copy paste does create strange issues. You do not need to add anything after the = symbol. Also if the issue persists, you can remove those lines and your mail server should work perfectly. This anyway is an additional optional configuration.

      Happy Mailing 🙂

  4. Debian


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

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

    should read:

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

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

    1. rudraraj Post author

      Thank You for pointing out the typo. Looks like made this error the last time I edited this post.


Leave a Reply

Your email address will not be published. Required fields are marked *