Jul 12, 2022 8 min read

How to Install and Configure Postfix and Dovecot

Install and configure Postfix and Dovecot with step-by-step tutorial. Together, they provide a complete email solution for all email-related tasks.

Install and Configure Postfix and Dovecot
Install and Configure Postfix and Dovecot
Table of Contents

Before we begin talking about how to install and configure Postfix and Dovecot, let's briefly understand – What is Postfix and Dovecot?

Postfix is a mail transfer agent (MTA) that handles sending and receiving emails, while Dovecot is an open-source IMAP and POP3 server, enabling access to stored emails.

This tutorial is written for Ubuntu 16.04, but newer versions of Ubuntu should work with the same steps with minor changes. We will also address a few FAQs on how to install and configure Postfix and Dovecot.

Advantages of Postfix and Dovecot

Advantages of Postfix:

  1. Robust and Secure: Postfix is known for its reliability and strong security measures, protecting your email server from spam, viruses, and other threats.
  2. High Performance: It offers efficient mail delivery with minimal resource usage, allowing for optimal performance even with high email volumes.
  3. Flexibility: Postfix can be easily configured and customized to meet specific requirements, providing flexibility in managing mail transport.
  4. Extensibility: With an extensive range of plugins and add-ons, Postfix can be extended with additional functionality, such as content filtering or real-time blacklisting.
  5. Active Community: Postfix has a large and active community of users and developers, ensuring continuous updates, bug fixes, and improvements.

Advantages of Dovecot:

  1. Secure and Scalable: Dovecot provides secure and scalable email access, supporting industry-standard protocols like IMAP and POP3 with SSL/TLS encryption.
  2. Fast and Efficient: Dovecot's optimized architecture ensures fast and efficient email retrieval, even with large mailboxes and numerous concurrent connections.
  3. Advanced Features: It offers advanced features like server-side mail filtering, virtual mail hosting, and seamless integration with other email-related services.
  4. Compatibility: Dovecot works seamlessly with various email clients and server setups, ensuring compatibility across different platforms and configurations.
  5. Easy Configuration and Administration: Dovecot's configuration is straightforward, making it easier for administrators to set up and manage their email server efficiently.

Prerequisites

Make sure you are logged in as a user with sudo privileges, before continuing with this tutorial,

Install Postfix and Dovecot

The default repositories of Ubuntu contain out-of-date Dovecot software. To take advantage of the imap_sieve module, we will install Dovecot from the community repository.

Use the wget command to append the repository's GPG key to your apt source key:

wget -O- https://repo.dovecot.org/DOVECOT-REPO-GPG | sudo apt-key add -

Use the following command to enable the Dovecot community repository:

echo "deb https://repo.dovecot.org/ce-2.3-latest/ubuntu/$(lsb_release -cs) $(lsb_release -cs) main" | sudo tee -a /etc/apt/sources.list.d/dovecot.list
sudo apt update
sudo debconf-set-selections <<< "postfix postfix/mailname string $(hostname -f)"
sudo debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'"
sudo apt install postfix postfix-mysql dovecot-imapd dovecot-lmtpd dovecot-pop3d dovecot-mysql

Postfix Configuration

We will configure Postfix to use virtual mailboxes and domains.

Start by creating sql configuration files that will tell postfix how to access the MySQL database.

sudo mkdir -p /etc/postfix/sql

Open your text editor and create the following files:

File 1:

/etc/postfix/sql/mysql_virtual_domains_maps.cf

user = postfixadmin
password = P4ssvv0rD
hosts = 127.0.0.1
dbname = postfixadmin
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'

File 2:

/etc/postfix/sql/mysql_virtual_alias_maps.cf

user = postfixadmin
password = P4ssvv0rD
hosts = 127.0.0.1
dbname = postfixadmin
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'

File 3:

/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf

user = postfixadmin
password = P4ssvv0rD
hosts = 127.0.0.1
dbname = postfixadmin
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

File 4:

/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf

user = postfixadmin
password = P4ssvv0rD
hosts = 127.0.0.1
dbname = postfixadmin
query  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

File 5:

/etc/postfix/sql/mysql_virtual_mailbox_maps.cf

user = postfixadmin
password = P4ssvv0rD
hosts = 127.0.0.1
dbname = postfixadmin
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'

File 6:

/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf

    /etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
user = postfixadmin
password = P4ssvv0rD
hosts = 127.0.0.1
dbname = postfixadmin
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'

After the SQL configuration file is created, update the main postfix configuration file to include information about virtual domains, users, and aliases stored in the MySQL database.

sudo postconf -e "virtual_mailbox_domains = mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf"

sudo postconf -e "virtual_alias_maps = mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf, mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf"

sudo postconf -e "virtual_mailbox_maps = mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf"
⚠️
The postconf command shows configuration parameter values as they actually are, modifies parameter values, or shows other configuration details for the Postfix mail system.

The user's mailbox will receive incoming emails from local delivery personnel. To make the Dovecot LMTP service the default mail delivery transport, use the following command:

sudo postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"

With the Let's Encrypt SSL certificate that was previously produced, set the TL parameters as follows:

sudo postconf -e 'smtp_tls_security_level = may'
sudo postconf -e 'smtpd_tls_security_level = may'
sudo postconf -e 'smtp_tls_note_starttls_offer = yes'
sudo postconf -e 'smtpd_tls_loglevel = 1'
sudo postconf -e 'smtpd_tls_received_header = yes'
sudo postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/mail.vegastack.com/fullchain.pem'
sudo postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/mail.vegastack.com/privkey.pem'

Set up the SMTP authentication settings and give Dovecot control over authentication:

sudo postconf -e 'smtpd_sasl_type = dovecot'
sudo postconf -e 'smtpd_sasl_path = private/auth'
sudo postconf -e 'smtpd_sasl_local_domain ='
sudo postconf -e 'smtpd_sasl_security_options = noanonymous'
sudo postconf -e 'broken_sasl_auth_clients = yes'
sudo postconf -e 'smtpd_sasl_auth_enable = yes'
sudo postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'

Additionally, we must change the master.cf configuration file for Postfix to enable the submission port (587) and smtps port (465).

Open the master.cf file with your text editor and uncomment/edit the following lines:

submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       y       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

To make modifications take effect, restart the postfix service.

sudo systemctl restart postfix

At this point, the Postfix service has been successfully configured.

Configure Dovecot

Here's where we put Dovecot up to work with our configuration. Ensure that you edit the commands according to your Dovecot setup.

To begin, configure the dovecot-sql.conf.ext file, which instructs Dovecot on how to retrieve email account information and access databases.

driver = mysql
connect = host=127.0.0.1 dbname=postfixadmin user=postfixadmin password=P4ssvv0rD
default_pass_scheme = MD5-CRYPT
iterate_query = SELECT username AS user FROM mailbox
user_query = SELECT CONCAT('/var/mail/vmail/',maildir) AS home, \
  CONCAT('maildir:/var/mail/vmail/',maildir) AS mail, \
  5000 AS uid, 5000 AS gid, CONCAT('*:bytes=',quota) AS quota_rule \
  FROM mailbox WHERE username = '%u' AND active = 1
password_query = SELECT username AS user,password FROM mailbox \
  WHERE username = '%u' AND active='1'

Remember to use the correct database name, username, and password when logging into MySQL.

Next, make the following changes to the variables in the conf.d/10-mail.conf file:

...
mail_location = maildir:/var/mail/vmail/%d/%n
...
mail_uid = vmail
mail_gid = vmail
...
first_valid_uid = 5000
last_valid_uid = 5000
...
mail_privileged_group = vmail
...
mail_plugins = quota
...

Open conf.d/10-auth.conf, update the provided lines, and add the auth-sql.conf.ext file to enable authentication:

...
disable_plaintext_auth = yes
...
auth_mechanisms = plain login
...
#!include auth-system.conf.ext
!include auth-sql.conf.ext
...

Open the conf.d/10-master.conf file, and edit it as follows:

...
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
...
}
...
service auth {
  ...
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
    group = vmail
  }
  ...
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
  ...
}
...
service auth-worker {
  user = vmail
}
...
service dict {
  unix_listener dict {
    mode = 0660
    user = vmail
    group = vmail
  }
}
...

Open the conf.d/10-ssl.conf and enable SSL/TLS.

...
ssl = yes
...
ssl_cert = </etc/letsencrypt/live/mail.vegastack.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.vegastack.com/privkey.pem
ssl_dh = </etc/ssl/certs/dhparam.pem
...
ssl_cipher_list = EECDH+AES:EDH+AES+aRSA
...
ssl_prefer_server_ciphers = yes
...

Open the file conf.d/20-imap.conf and activate the imap_quota plugin:

...
protocol imap {
  ...
  mail_plugins = $mail_plugins imap_quota
  ...
}
...

Open the conf.d/20-lmtp.conf file and edit it as follows:

...
protocol lmtp {
  postmaster_address = [email protected]
  mail_plugins = $mail_plugins
}
...

Define the default Mailboxes in the conf.d/15-mailboxes.conf file:

...
mailbox Drafts {
  special_use = \Drafts
}
mailbox Spam {
  special_use = \Junk
  auto = subscribe
}
mailbox Junk {
  special_use = \Junk
}
...

There are two distinct quota sizes: one for the entire domain and one for each user mailbox.

The next steps involve setting up Dovecot to connect to the database, controlling the quota, and executing a script that notifies the user via email when their quota above the predetermined threshold. Open the conf.d/90-quota.conf file and make the following changes to achieve this:

plugin {
  quota = dict:User quota::proxy::sqlquota
  quota_rule = *:storage=5GB
  quota_rule2 = Trash:storage=+100M
  quota_grace = 10%%
  quota_exceeded_message = Quota exceeded, please contact your system administrator.
  quota_warning = storage=100%% quota-warning 100 %u
  quota_warning2 = storage=95%% quota-warning 95 %u
  quota_warning3 = storage=90%% quota-warning 90 %u
  quota_warning4 = storage=85%% quota-warning 85 %u
}

service quota-warning {
  executable = script /usr/local/bin/quota-warning.sh
  user = vmail

  unix_listener quota-warning {
    group = vmail
    mode = 0660
    user = vmail
  }
}

dict {
  sqlquota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
}

Dovecot must be instructed on how to access the quota SQL dictionary as well. Open the dovecot-dict-sql.conf.ext file and edit the following lines:

...
connect = host=127.0.0.1 dbname=postfixadmin user=postfixadmin password=P4ssvv0rD
...
map {
  pattern = priv/quota/storage
  table = quota2
  username_field = username
  value_field = bytes
}
map {
  pattern = priv/quota/messages
  table = quota2
  username_field = username
  value_field = messages
}
...
# map {
#   pattern = shared/expire/$user/$mailbox
#   table = expires
#   value_field = expire_stamp
#
#   fields {
#     username = $user
#     mailbox = $mailbox
#   }
# }
...

Create the shell script below /usr/local/bin/quota-warning.sh, and if the user's quota rises above a certain threshold, it will email the user:

#!/bin/sh
PERCENT=$1
USER=$2
cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=dict:User quota::noenforcing:proxy::sqlquota"
From: [email protected]
Subject: Quota warning

Your mailbox is now $PERCENT% full.
EOF

Run the following chmod command, to make the script executable:

sudo chmod +x /usr/local/bin/quota-warning.sh

Now, restart the dovecot service for the changes to take effect.

sudo systemctl restart dovecot

FAQs to Install and Configure Postfix and Dovecot

What is the recommended installation method for Postfix and Dovecot? 

It is recommended to install Postfix and Dovecot using the package manager of your operating system, such as apt-get for Ubuntu or yum for CentOS.

Can I set up Postfix and Dovecot to use SSL/TLS encryption? 

Absolutely! Postfix and Dovecot can be configured to use SSL/TLS encryption, ensuring secure communication between email clients and the server.

How do I configure Dovecot for email retrieval using IMAP or POP3? 

Dovecot's configuration file, dovecot.conf, needs to be configured to specify protocols like IMAP or POP3, authentication mechanisms, mailbox locations, and SSL/TLS settings. Detailed instructions can be found in the Dovecot documentation.

What ports do I need to open in my firewall for Postfix and Dovecot?

For incoming email, open port 25 for SMTP (Postfix) and port 110 for POP3 (Dovecot). For secure connections, open port 465 for SMTPS and port 995 for POP3S. These ports may vary depending on your specific configuration.

Can I use virtual domains and users with Postfix and Dovecot?

Yes, both Postfix and Dovecot support virtual domains and users, allowing you to handle email for multiple domains or set up virtual mail hosting.

How can I set up spam filtering with Postfix and Dovecot? 

Postfix can be integrated with spam filtering tools like SpamAssassin or Amavisd-new. Dovecot can execute server-side filters using Sieve scripts for more advanced filtering.

Conclusion

You should now have a fully functional email system.

If you have any queries, please leave a comment below and we’ll be happy to respond to them.

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to DevOps Tutorials - VegaStack.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.