Dovecot server setup

https://www.njae.me.uk/Dovecot_server_setup

Configuring email is the most involved part of setting up a server. My setup is organised with:

  • Postfix as a mail transfer agent, using virtual users with maildir-style mailboxes, and TLS transport
  • SpamAssassin for spam filtering
  • ClamAV for virus filtering
  • Amavis to wrap SpamAssassin and ClamAV for easy use with Postfix
  • Dovecot as a mail delivery agent, providing IMAP services
  • Dovecot’s local delivery agent, to do server-side filtering with Sieve
  • Squirrelmail to provide a webmail, running over a secure web connection

A lot to do, and split between several pages on this site. Dovecot 2, Dovecot LDA, and Sieve setup are on here. Postfix, TLS, and Amavis + SpamAssassin + ClamAV are on the Postfix server setup page. Squirrelmail setup is described in the Web server setup page, along with the HTTPS configuration.

We set up Dovecot first as it provides authentication and local delivery services for Postfix. However, there will still be a lot of flipping between the two.

The basic sources for setting up Postfix and Dovecot are the basic Postfix howto and the Postfix virtual user howto on the Ubuntu wiki. However, those articles still refer to Dovecot 1, while Ubuntu 12.04 has Dovecot 2. The configuration in the two packages is very different: Dovecot 1 has a single config file, while Dovecot 2 uses a directory of small config files.

Virtual user structure

I use virtual users because I handle mail for many users in many domains, and want the flexibility that virtual users allows. Information about the virtual users is held in plain text files, as that’s all I need for the small number of users I have.

The virtual user mailboxes are in the directory structure

/var/vmail/domain1.com/user1/mail/
                      /user2/mail/
          /domain2.com/user1/mail/
                      /user2/mail/
          /domain3.com/user1/mail/

…and so on. The /var/vmail/domain.com/user1/ directory will be used to store configuration files (such as the Sieve files) for each user, with the /var/vmail/domain.com/user1/mail/ directory being the base Maildir directory for the user.

The vmail user will be the one used for email transport into and out of these virtual mailboxes.

Initial Dovecot configuration

This gets a basic IMAP server up and running.

  • Install Dovecot
root@server:~# aptitude install dovecot dovecot-imapd whois dovecot-sieve dovecot-managesieved
(whois is needed in a moment for creating passwords)
  • Create the vmail user and group
 root@server:~# groupadd -g 5000 vmail
 root@server:~# useradd -m -u 5000 -g 5000 -s /bin/bash vmail
  • Modify the protocols in /etc/dovecot/dovecot.conf to read:
# Enable installed protocols                                                                                          
# !include_try /usr/share/dovecot/protocols.d/*.protocol                                                              
protocols = imap 
  • Modify /etc/dovecot/conf.d/10-mail.conf to contain:
#mail_location =                                                                                                      
mail_home = /home/vmail/%d/%n
mail_location = maildir:~/mail

namespace inbox {
   prefix =
   inbox = yes
   hidden = no
   subscriptions = yes
}
  • Modify /etc/dovecot/conf.d/10-auth.conf to contain:
disable_plaintext_auth = yes
auth_mechanisms = plain
#!include auth-system.conf.ext                                                                                        
!include auth-passwdfile.conf.ext
The first line means that all connections to Dovecot must be encrypted (apart from connections from the same machine). There’s no need to specify separate IMAP and IMAPS protocols.
  • Modify /etc/dovecot/conf.d/10-master.conf to contain the port = 0 line:
service imap-login {
  inet_listener imap {
    #port = 143
  }
  inet_listener imaps {
    #port = 993
    #ssl = yes
    port = 0 # disable this listener
  }
This disables the login listener from listening on port 993.
  • Modify /etc/dovecot/conf.d/10-ssl.conf to contain:
ssl_cert = </etc/letsencrypt/live/imap.domain.tld/fullchain.pem
ssl_key = </etc/letsencrypt/live/imap.domain.tld/privkey.pem

Create virtual users

  • Modify /etc/dovecot/conf.d/auth-passwdfile.conf.ext to contain:
passdb {
  driver = passwd-file
  args = scheme=plain-md5 username_format=%u /etc/dovecot/users
}

userdb {
  driver = passwd-file
  args = username_format=%u /etc/dovecot/users
}

This shows that the user information (username, password, domain name, and vmail directory) is contained in /etc/dovecot/users. This is in the same format as /etc/passwd. It’s easier to create a script to add the users to Dovecot, and tell Postfix about the maps.

  • Create the script /etc/dovecot/dovecot-adduser
#!/bin/bash

username=${1%%@*}
domain=${1#*@}

# create the user name in the user file
echo "$username@$domain:`mkpasswd --hash=md5 $2`:5000:5000::/var/vmail/$domain/$username/::" >> /etc/dovecot/users

# create the maildir directory structure
/usr/bin/maildirmake.dovecot /var/vmail/$domain/$username/mail 5000:5000
chown -R vmail:vmail /var/vmail/$domain

# add the user to the Postfix virtual map file
echo $1 $domain/$username/mail/ >> /etc/postfix/vmaps
postmap /etc/postfix/vmaps
postfix reload
Make sure the script is executable.
  • Create the users with dovecot-adduser, then check that it works:
root@server:~# /etc/dovecot/dovecot-adduser user@domain.tld mailpassword
root@server:~# doveadm auth user@domain.tld mailpassword
  • Once every virtual user has received at least one mail (and hence had their mailbox directory structure created), change the file ownerships on those directories so that Dovecot can manipulate them
root@server:~# chown -R vmail:vmail /home/vmail

Testing Dovecot

Type in a terminal

root@server:~# telnet mail.domain1.com 143

An output like the following will display in your terminal

Trying 69.60.109.217...
Connected to mail.domain1.com.
Escape character is '^]'.
+OK dovecot ready.

Type the following code segment in the prompt provided by the Dovecot IMAP server.

a login user1@domain1.com password
a logout

If you can log in, Final output should be something like this:

Trying 69.60.109.217...
Connected to mail.domain1.com.
Escape character is '^]'.
+OK dovecot ready.
a login info@domain1.com password
a OK Logged in.
a logout
* BYE Logging out
a OK Logout completed.

You should now be able to log into the Dovecot server with your favourite email client.

IMAPS connections can be tested with openssl

root@server:~# openssl s_client -connect imap.example.com:143 -starttls imap
<verbiage snipped>
. OK Pre-login capabilities listed, post-login capabilities have more.
and test the login as before. Logout with
a logout

Mail clients should connect to imap.domain.tld:143 using SSL encryption and PLAIN authentication.

Once IMAP and users are set up, you can use that as the basis for SASL authentication of SMTP users of Postfix. See the Postfix SASL notes for details.

Logging

You now need to ensure that the Dovecot logs to its own log files. (The Dovecot documentation recommends using rsyslog, but I couldn’t get that to work.)

  • Modify /etc/dovecot/conf.d/10-logging.conf to contain:
log_path = /var/log/dovecot.log
# syslog_facility = local1
  • Modify /etc/dovecot/conf.d/15-lda.conf to contain the log_path:
protocol lda {
  mail_plugins = $mail_plugins sieve
  log_path = /var/log/dovecot-lda.log
  postmaster_address = postmaster@domain.tld
}
  • Make /var/log/dovecot-lda.log world-writable:
root@server:~# touch /var/log/dovecot-lda.log
root@server:~# chmod a+w /var/log/dovecot-lda.log
  • Reload the Dovecot configuration and check it’s picked up the logfile locations:
root@server:~# service dovecot reload
root@server:~# doveadm log find
Debug: /var/log/dovecot.log
Info: /var/log/dovecot.log
Warning: /var/log/dovecot.log
Error: /var/log/dovecot.log
Fatal: /var/log/dovecot.log
  • Create /etc/logrotate.d/dovecot to contain:
/var/log/dovecot.log
{
       weekly
       rotate 52
       missingok
       notifempty
       compress
       delaycompress
       create 640 root adm
       sharedscripts
       postrotate
           doveadm log reopen
       endscript
}

/var/log/dovecot-lda.log
{
       weekly
       rotate 52
       missingok
       notifempty
       compress
       delaycompress
       create 666 root adm
       sharedscripts
       postrotate
           doveadm log reopen
       endscript
}
The two separate sections are so that the dovecot-lda.log file remains world-writable.

Set up local delivery and sieve

The final stage is to incorporate Dovecot’s local delivery agent, LDA, into the mail delivery system. I want to do this because Deliver supports Sieve, which does server-side mail filtering. See the Dovecot Sieve page for details.

Modify /etc/dovecot/conf.d/15-lda.conf

recipient_delimiter = .
lda_mailbox_autocreate = yes
protocol lda {
  mail_plugins = $mail_plugins sieve
}
  • Create an an empty log file for deliver
root@server:~# touch /var/log/dovecot-deliver.log
root@server:~# chmod a+w /var/log/dovecot-deliver.log
  • Ensure the changes are incorporated into Postfix and Dovecot
root@server:~# postfix reload
root@server:~# /etc/init.d/dovecot restart
  • Now, create rule files for Deliver/Sieve to use. This should be in the base directory for the user’s mail directory, e.g. /home/vmail/domain1.com/user1/.dovecot.sieve
require ["fileinto"];

# generally a clause is
# if header :contains ["From", "To", "CC", "Subject", <and so on>] 
#   ["part of address", "another string element", <and so on>
# If any of the elements match any of the header parts, the clause is triggered

   if header :contains ["To", "CC"] ["user1@domain1.com", "user2@domain2.com"] {
  fileinto "Folder 1";
} elsif header :contains ["From"] ["person@somewhere.com"] {
  fileinto "Folder 1.Subfolder 2";
}
  • Ensure that all the folders referenced in the rules exist before you mention them in the .dovecot.sieve file. The first time Dovecot delivers mail to this user, it will create the .dovecot.sievec compiled file. If the rules file changes, Dovecot will recreate the compiled file automatically.

For more on Sieve rules, see the FastMail wiki which has a guide to basic Sieve and some examples, and a Sieve summary, including a comprehensive Sieve rule set.

And that should be email sorted out.

Troubleshooting

Dovecot doesn’t start

If Dovecot fails to start and /var/log/dovecot.log contains lines like

dovecot: IMAP(user): FETCH for mailbox INBOX UID 176705 failed to read message input: Is a directory

it means that the Mbox folders for the mail folder in question (in this case INBOX, but it could be anything) contain directories instead of files. Delete the directories from /home/vmail/domain/user/INBOX/cur and restart Dovecot.

(Thanks to Patrick Bulteel for the pointer.)

Mail folder sbscriptions

Don’t forget that users will need to subscribe to the folders they want to see.

See also

Here are a few pages that are useful guides or provide background and context.