Skip to content

Server configuration: Dovecot v2.x

runout-at edited this page May 6, 2018 · 2 revisions

Dovecot is an open source IMAP and POP3 MDA (Mail Delivery Agent) for Linux/UNIX-like systems, written with security primarily in mind. This page explains how to configure Dovecot to authenticate users using Vexim database and serve them their e-mail.

Note: this manual is for Dovecot v.2. If you are using Dovecot v.1, you should refer to the other manual instead.

In fact, setting Dovecot up to work with Vexim is rather trivial. You have to change the following things in Dovecot configuration files. If you are using Debian or Ubuntu, your Dovecot configuration resides in /etc/dovecot/. The files are documented rather extensively, so we won't go through everything here. Here are the things for you to take care of:

  • The value of first_valid_uid must be low enough for virtual users to be able to log in. This setting is set in conf.d/10-mail.conf configuration file. Its value must be at least as low as the uid of your vexim user created during set up of Vexim. Same goes for first_valid_gid, although that defaults to 1, so should not be a problem. Anyway, here's an example:

    first_valid_uid = 100
    
  • sql password database must be enabled (and other passdb's disabled if you want Dovecot to only serve Vexim virtual users). This is done in the conf.d/10-auth.conf file. First of all, you should only allow plaintext passwords if a secured connection (SSL/TLS) is used:

    disable_plaintext_auth = yes
    

    Then use uncomment the SQL-authentication-backend at the very bottom of it, and adjust the includes as following:

    #!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-vpopmail.conf.ext
    #!include auth-static.conf.ext
    

    Then open conf.d/auth-sql.conf.ext and make sure that its passdb block is uncommented. It should look somewhat like this:

    passdb {
      driver = sql
      # Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
      args = /etc/dovecot/dovecot-sql.conf.ext
    }
    

    You may also uncomment the userdb block which enables prefetch user database to avoid unnecessary SQL queries:

    userdb {
      driver = prefetch
    }
    
  • Now, the passdb has to be configured properly. Edit the dovecot-sql.conf.ext file as follows (make sure to adjust the connect line to reflect your actual setup though):

    driver = mysql
    connect = host=/var/run/mysqld/mysqld.sock dbname=vexim user=vexim password=CHANGE
    default_pass_scheme = CRYPT
    password_query = \
      SELECT \
        `username` AS `user`, \
        `crypt` AS `password`, \
        `pop` AS `userdb_home`, \
        `uid` AS `userdb_uid`, \
        `gid` AS `userdb_gid`, \
        CONCAT('maildir:', `smtp`) AS `userdb_mail`, \
        CONCAT('*:bytes=', `quota`, 'M') AS `userdb_quota_rule` \
      FROM `users` \
      WHERE \
        `username` = '%u' \
        AND `type` IN ('local', 'piped')
    
    user_query = \
      SELECT \
        `pop` AS `home`, \
        `uid`, \
        `gid`, \
        CONCAT('maildir:', `smtp`) AS `mail`, \
        CONCAT('*:bytes=', `quota`, 'M') AS `quota_rule` \
      FROM `users` \
      WHERE \
        `username` = '%u' \
        AND `type` IN ('local', 'piped')
    
    iterate_query = \
      SELECT \
          `u`.`username` AS `user`, \
          `d`.`domain` \
        FROM `users` AS `u` \
          JOIN `domains` AS `d` ON `d`.`domain_id` = `u`.`domain_id` \
        WHERE `u`.`type` IN ('local', 'piped')
    

    Another example, which disallows serving (or otherwise acting upon) users that are disabled or are members of a disabled domain:

    password_query = \
      SELECT \
        `u`.`username` AS `user`, \
        `u`.`crypt` AS `password`, \
        CONCAT(`d`.`maildir`, '/', `u`.`localpart`) AS `userdb_home`, \
        `u`.`uid` AS `userdb_uid`, \
        `u`.`gid` AS `userdb_gid`, \
        CONCAT('maildir:', `d`.`maildir`, '/', `u`.`localpart`, '/Maildir') AS `userdb_mail`, \
        CONCAT('*:bytes=', `u`.`quota`, 'M') AS `userdb_quota_rule` \
      FROM `users` AS `u` \
        JOIN `domains` AS `d` ON `d`.`domain_id` = `u`.`domain_id` \
      WHERE \
        `u`.`username` = '%u' \
        AND `u`.`enabled` = 1 \
        AND `d`.`enabled` = 1 \
        AND `u`.`type` IN ('local', 'piped')
    
    user_query = \
      SELECT \
        CONCAT(`d`.`maildir`, '/', `u`.`localpart`) AS `home`, \
        `u`.`uid`, \
        `u`.`gid`, \
        CONCAT('maildir:', `d`.`maildir`, '/', `u`.`localpart`, '/Maildir') AS `mail`, \
        CONCAT('*:bytes=', `u`.`quota`, 'M') AS `quota_rule` \
      FROM `users` AS `u` \
        JOIN `domains` AS `d` ON `d`.`domain_id` = `u`.`domain_id` \
      WHERE \
        `u`.`username` = '%u' \
        AND `u`.`enabled` = 1 \
        AND `d`.`enabled` = 1 \
        AND `u`.`type` IN ('local', 'piped')
    
    iterate_query = \
      SELECT \
          CONCAT(`u`.`localpart`, '@', `d`.`domain`) AS `user`, \
          `d`.`domain` \
        FROM `users` AS `u` \
          JOIN `domains` AS `d` ON `d`.`domain_id` = `u`.`domain_id` \
        WHERE \
          `u`.`enabled` = 1 \
          AND `d`.`enabled` = 1 \
          AND `u`.`type` IN ('local', 'piped')
    

    Dovecot expects the SELECT to return a set of columns with particular names, hence usage of the AS keyword above.

    • password_query returns all fields that are necessary.
    • user_query will be used if you don't enable prefetch user database and/or if you use Dovecot LDA to deliver e-mails. Either way, even if that query won't be used, there is no harm in having it defined.
    • iterate_query will be used by doveadm when iterating over multiple accounts.
  • To configure proper user quota support and reporting for IMAP, there are a few more adjustments to make:

    • in conf.d/10-mail.conf enable quota plugin:

      mail_plugins = $mail_plugins quota
      
    • do the same in conf.d/20-imap.conf:

      protocol imap {
        mail_plugins = $mail_plugins imap_quota
      }
      
    • in conf.d/90-quota.conf enable at least one quota backend:

      plugin {
        quota = maildir:User quota
      }
      

      After applying all configuration and restarting Dovecot, you can test your quota configuration by running the following command from your root shell:

      doveadm quota get -A
      

      If configuration is correct, you should see two lines of output per virtual user (one for STORAGE and one for MESSAGE quotas):

      # doveadm quota get -A
      Username                 Quota name Type    Value Limit      %
      [email protected]   User quota STORAGE     9     -      0
      [email protected]   User quota MESSAGE     9     -      0
      [email protected]    User quota STORAGE     6  2048      0
      [email protected]    User quota MESSAGE     5     -      0
      

      For the referenceSTORAGE values are reported in KiB (Kibibytes).

SSL/TLS encryption should always be used to protect your mails and login credentials. You can use the same certificates you created for Exim. There is nothing specific to Vexim here, so just follow the official SSL configuration guide from the Dovecot Wiki. For the cipher selection, we recommend to use a current set of "secure" ciphers, bettercrypto.org provides some reviewed default configs in a PDF file for /etc/dovecot/conf.d/10-ssl.conf:

# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = yes
# SSL protocols to use, disable SSL, use TLS only
ssl_protocols = !SSLv3 !SSLv2
# SSL ciphers to use
ssl_cipher_list = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH\
\:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4\
\:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA
# Prefer the server's order of ciphers over client's. (Dovecot >=2.2.6 Required)
ssl_prefer_server_ciphers = yes
# Diffie-Hellman parameters length (Default is 1024, Dovecot >=2.2.7 Required)
# ToDo: for ReGenerating DH-Parameters:
# manually delete /var/lib/dovecot/ssl-parameters.dat and restart
# Dovecot to regenerate /var/lib/dovecot/ssl-parameters.dat
ssl_dh_parameters_length = 2048
# Disable Compression (Dovecot >= 2.2.14 Required, check with `dovecot --version`)
# ssl_options = no_compression

Once you have applied all the changes above, you should restart Dovecot and start testing your setup. It should already work!