Skip to content

Dovecot

Todo list for receiving emails
  1. 1

    DNS records point to your server

  2. 2

    Get a certificate from Let's Encrypt

  3. 3

    Postfix fetches information from MariaDB

  4. 4

    Dovecot fetches information from MariaDB

  5. 5

    Postfix hands over emails to Dovecot

  6. 6

    Dovecot saves the email to disk

In this chapter we will configure Dovecot so that it knows how to deliver incoming emails.

On your disk all the mailboxes will live in the directory /var/vmail. To separate the mailboxes from the rest of your system, let’s create a new user and group that will own the mailboxes:

Run this on your server
groupadd --system vmail
useradd --system --gid vmail vmail
mkdir -p /var/vmail
chown -R vmail:vmail /var/vmail
chmod u=rwx,g=rx,o= /var/vmail

The configuration files for Dovecot are found in /etc/dovecot/conf.d. All these files are loaded by Dovecot. This is done by this magical line at the end of the /etc/dovecot/dovecot.conf file:

!include conf.d/*.conf

It loads all files in /etc/dovecot/conf.d/ that end in “.conf” in alphanumerical order. Let’s edit a couple of files for our purpose.

The /etc/dovecot/conf.d/10-auth.conf file is dealing with authentication. At the end of this file you will find a list of authentication backends that Dovecot ships with. By default it will use system users (those from /etc/passwd). But we want to use the MariaDB database backend. Please comment out all include statements:

Edit your /etc/dovecot/conf.d/10-auth.conf
#!include auth-system.conf.ext
#!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-static.conf.ext

Every line starting with # is disabled. Only lines starting with ! are considered.

The file at /etc/dovecot/conf.d/10-mail.conf contains many settings regarding mailboxes, like where they are located, who owns them and what is their layout? Create a new file /etc/dovecot/conf.d/99-ispmail-mail.conf that overrides these defaults:

Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-mail.conf << EOF
mail_driver = maildir
mail_home = /var/vmail/%{user | domain}/%{user | username}
mail_path = ~/Maildir
mail_uid = vmail
mail_gid = vmail
mail_inbox_path = ~/Maildir/
EOF

This looks more sophisticated than with versions of Dovecot before 2.4. What it means:

  • mail_driver: Mailboxes are stored in maildir format.
  • mail_home: Every mail user gets their own home directory in /var/vmail/DOMAIN/USER. The user variable contains the email address like john@example.org. The expression user | domain splits off the domain part from the email address. Similarly user | username takes the part before the @ sign.
  • mail_path: Within the home directory the actual mailbox will live in a subdirectory called Maildir. The reason is that we will store other data in the user’s home directory as well that should not conflict with the mailbox directory.
  • mail_uid/mail_gid: All mailboxes will be owned be the user and group vmail.
  • mail_inbox_path: A user’s main inbox consists of the directories cur and new inside the Maildir directory. We used that schema in previous guides and make sure you can migrate your mailboxes from other mail servers. This overrides the setting in in 10-mail.conf.

This configuration file at /etc/dovecot/conf.d/10-master.conf deals with Dovecot’s services. A service is a part of Dovecot that listens on a TCP port or a UNIX socket so that other parts of your system can use it. We want Postfix to use Dovecot for authentication. So we need to change the service auth section:

Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-master.conf << EOF
service auth {
unix_listener /var/spool/postfix/private/dovecot-auth {
mode = 0660
user = postfix
group = postfix
}
}
EOF

That way Dovecot will put a communication socket into /var/spool/postfix/private/dovecot-auth. It will allow Postfix to authenticate your users which is relevant later when we set up relaying.

Earlier in this guide you created both a key and a certificate file to encrypt the communication with IMAPS and HTTPS between the users and your mail server. You need to tell Dovecot where to find these files. Also set ssl=required to prevent that someone sends their password without encryption. Again we will create a new file 99-ispmail-ssl.conf to override the defaults.

Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-ssl.conf << EOF
ssl = required
ssl_server_cert_file = /etc/letsencrypt/live/mail.example.org/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/mail.example.org/privkey.pem
EOF

There is one setting in the /etc/dovecot/conf.d/20-lmtp.conf that will mess up the recipient’s email address in our setup: auth_username_format. So let’s override it:

Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-lmtp-username-format.conf << EOF
protocol lmtp {
auth_username_format =
}
EOF

Let’s tell Dovecot where to find information on an valid users (userdb) and their passwords (passdb). There are suggestions in the auth-sql.conf.ext file but we will add our own file:

Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-sql.conf << EOF
sql_driver = mysql
mysql /var/run/mysqld/mysqld.sock {
user = mailserver
password = 'MAILSERVER-PASSWORD-HERE'
dbname = mailserver
host = 127.0.0.1
}
userdb sql {
query = SELECT email as user, \
IF(quota > 0, CONCAT(quota, 'B'), NULL) AS quota_storage_size \
FROM virtual_users WHERE email='%{user}'
iterate_query = SELECT email as user FROM virtual_users
}
passdb sql {
query = SELECT password FROM virtual_users where email='%{user}'
}
EOF
# fix permissions
chown root:root /etc/dovecot/conf.d/99-ispmail-sql.conf
chmod go= /etc/dovecot/conf.d/99-ispmail-sql.conf

That configuration file defines how to get a user’s data from the database. The two lookups are:

  • userdb sql: get information on the user; e.g. if the user exists and what the quota is
  • passdb sql: authenticate the user / validate the password

The quota logic is explained and used later in this guide. Quota is the amount of space that a user can use to store their emails. If the quota is reached then further incoming emails will get rejected until the user removes mails to make some space.

Dovecot can also read the path to a user’s home directory and the user-ID and group-ID from the database. Our setup has a fixed schema for the home directory (/var/vmail/DOMAIN/USER) (as defined by mail_home) and the user and group are always vmail and vmail.

Later, we will implement server-side automation using Sieve rules. By default, Dovecot exposes two TCP ports to the internet: 2000 and 4190. Port 2000 is deprecated anyway and can be safely disabled, while port 4190 is the one we will use. However, unless you have a compelling reason, it is recommended not to make this port publicly accessible. So let us restrict it to the localhost interface:

Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-managesieve.conf << EOF
service managesieve-login {
# Listen only on localhost
inet_listener sieve {
listen= 127.0.0.1
port = 4190
}
# Disable the deprecated listener
inet_listener sieve_deprecated {
port = 0
}
}
EOF

(Thanks to Thomas Gauweiler for spotting that.)

Restart Dovecot from the shell:

Run this on your server
systemctl restart dovecot

Check your logs:

Run this on your server
journalctl -fu dovecot

You should see:

dovecot[13309]: master: Dovecot v2.4.1-4 (7d8c0e5759) starting up for imap, lmtp, sieve (core dumps disabled)
systemd[1]: Started dovecot.service - Dovecot IMAP/POP3 email server.

If you get any error messages please double-check your configuration files.