Extended Brain Storage

OpenBSD: Dovecot

Posted on September 22, 2016

The installation and configuration steps of Dovecot with LDAP support in OpenBSD...

Installation

The installation is straightforward:

$ pkg_add dovecot dovecot-ldap
quirks-2.367 signed on 2017-10-03T11:21:28Z
dovecot-2.2.32p0: ok
dovecot-ldap-2.2.32: ok
The following new rcscripts were installed: /etc/rc.d/dovecot
See rcctl(8) for details.
Look in /usr/local/share/doc/pkg-readmes for extra documentation.
--- +dovecot-2.2.32p0 -------------------
Files to facilitate the generation of a self-signed
certificate and key for Dovecot have been installed:
/etc/ssl/dovecot-openssl.cnf (Edit this accordingly!)
/usr/local/sbin/dovecot-mkcert.sh

If this has been or will be accomplished by other means,
use the following paths for the files:
/etc/ssl/dovecotcert.pem
/etc/ssl/private/dovecot.pem

Configuration

Supported protocols and default setup is available in:

$ grep -v -E "^[ \t]*$|^.*#" /etc/dovecot/dovecot.conf
protocols = imap lmtp
!include conf.d/*.conf
!include_try local.conf

Authentication method setup is available in:

$ grep -v -E "^[ \t]*$|^.*#" /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = yes # plain text auth is permitted if SSL/TLS is used
auth_mechanisms = plain login
!include auth-passwdfile.conf.ext

but needs to be changed to:

$ vi /etc/dovecot/conf.d/10-auth.conf
<OUTPUT-OMITTED>
!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext

The userdb lookups should use a separate connection to the LDAP server. Thefore, the userdb args path should be updated as follows:

$ vi /etc/dovecot/conf.d/auth-ldap.conf.ext
passdb {
  driver = ldap
  args = /etc/dovecot/dovecot-ldap.conf.ext
}
userdb {
  driver = ldap
  #args = /etc/dovecot/dovecot-ldap.conf.ext
  args = /etc/dovecot/dovecot-ldap-userdb.conf.ext
}

And the link to the original file can be created as follows:

$ ln -s /etc/dovecot/dovecot-ldap.conf.ext /etc/dovecot/dovecot-ldap-userdb.conf.ext

Considering the usage of the SSHA algorithm, user verification in LDAP directory (could be added at the end of the file) can be set up as follows (the hosts, dn, dnpass and base parameters need to be changed accordingly):

$ vi /etc/dovecot/dovecot-ldap.conf.ext
### MY SETUP AT THE END OF THE FILE
hosts = server.domain.tld
tls = yes
auth_bind = yes
ldap_version = 3
dn = uid=dovecot,ou=services,dc=domain,dc=tld
dnpass = DOVECOT-PASSWORD
base = ou=people,dc=domain,dc=tld
user_filter = (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)(uid=%n))
user_attrs = uid=user,mailStorageDirectory=home=/var/vmail/%$
pass_filter = (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)(uid=%n))
pass_attrs = uid=user
# http://wiki.dovecot.org/Authentication/PasswordSchemes
#default_pass_scheme = CRYPT
default_pass_scheme = SSHA   # used to store passwords in LDAP

If unsure about the default_pass_scheme, available encryption schemes can be shown by:

$ doveadm pw -l
MD5 MD5-CRYPT SHA SHA1 SHA256 SHA512 SMD5 SSHA SSHA256 SSHA512 PLAIN CLEAR CLEARTEXT PLAIN-TRUNC CRAM-MD5 SCRAM-SHA-1 HMAC-MD5 DIGEST-MD5 PLAIN-MD4 PLAIN-MD5 LDAP-MD5 LANMAN NTLM OTP SKEY RPA PBKDF2 CRYPT BLF-CRYPT

For mailbox location and namespaces setup, the virtual user/group (vmail/vmail) UID/GID needs to be checked first:

$ id -u vmail
1001
$ id -g vmail
1001

The above IDs will become the mail_uid and mail_gid values respectively in (Note: the separator = / and :LAYOUT=fs parameters make sure that mail directory subfolders are presented in the same way on the filesystem):

$ vi /etc/dovecot/conf.d/10-mail.conf
namespace inbox {
  separator = /
  inbox = yes
}
### My setup at the end of the file
mail_home = /var/vmail/%d/%n
mail_location = maildir:~:LAYOUT=fs
mail_uid = 1001
mail_gid = 1001
mail_privileged_group = vmail

Login methods (allowing only imaps, disabling imap, pop3 and pop3s) can be setup as follows:

$ vi /etc/dovecot/conf.d/10-master.conf
service imap-login {
  inet_listener imap {
    #port = 143 # default value
    port = 0    # to disable
  }
  inet_listener imaps {
    #port = 993 # default value
    #ssl = yes  # default value
  }
}
service pop3-login {
  inet_listener pop3 {
    #port = 110 # default value
    port = 0    # to disable
  }
  inet_listener pop3s {
    #port = 995 # default value
    #ssl = yes  # default value
    port = 0    # to disable
  }
}
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    group = wheel
    mode = 0666
    user = _postfix
  }
}
service auth {
  unix_listener auth-userdb {
    group = vmail
    mode = 0600
    user = vmail
  }

  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    group = wheel
    mode = 0666
    user = _postfix
  }
}

service auth-worker {
  # Access to /etc/shadow will not be necessary. No need to run this as root.
  user = vmail
}

Postmaster address and domain name can be specified (and changed accordingly) as follows:

$ vi /etc/dovecot/conf.d/15-lda.conf
postmaster_address = postmaster@domain.tld
hostname = server.domain.tld

Mailbox folders can be defined as follows (including auto-subscription):

$ vi /etc/dovecot/conf.d/15-mailboxes.conf
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    special_use = \Drafts
    auto = subscribe
  }
  mailbox Junk {
    special_use = \Junk
    auto = create
  }
  mailbox Trash {
    special_use = \Trash
    auto = subscribe
  }

  # For \Sent mailboxes there are two widely used names. We'll mark both of
  # them as \Sent. User typically deletes one of them if duplicates are created.
  mailbox Sent {
    special_use = \Sent
    auto = subscribe
  }
  #mailbox "Sent Messages" {
  #  special_use = \Sent
  #}

The Listescape plugin allows users to use characters in mailboxes names that would otherwise be illegal (e.g. a dot "." in the directory name):

$ vi /etc/dovecot/conf.d/20-imap.conf
protocol imap {
  imap_metadata = yes
  mail_plugins = $mail_plugins listescape
}

TLS certificates setup (valid for versions 2.3+):

$ vi /etc/dovecot/conf.d/10-ssl.conf
#ssl_cert = </etc/ssl/dovecotcert.pem
#ssl_key = </etc/ssl/private/dovecot.pem
...
### MY OWN SETUP (at the end of the file)
ssl = yes
ssl_cert = </etc/ssl/rohlix.eu.fullchain.pem
ssl_key = </etc/ssl/private/domain.tld.key
ssl_dh = </etc/dovecot/dh.pem
ssl_min_protocol = TLSv1.2
ssl_cipher_list = TLSv1.2:TLSv1.3:!CAMELLIA:!ARIA:!DSS:!ADH:!PSK:!RSA:!ECDHE-RSA-AES256-SHA384:!ECDHE-RSA-AES128-SHA256:!DHE-RSA-AES256-SHA256:!DHE-RSA-AES128-SHA256
ssl_prefer_server_ciphers = yes
ssl_options = no_compression

The Diffie-Hellman file needs to be created as follows (will take some time):

$ openssl dhparam -out /etc/dovecot/dh.pem 4096

In order to prevent SSL/TLS issues such as:

Apr 27 11:40:41 imap-login: Info: Disconnected (no auth attempts in 0 secs): user=<>, rip=CLIENT-IP, lip=SERVER-IP, TLS handshaking: SSL_accept() failed: error:14037416:SSL routines:ACCEPT_SR_KEY_EXCH:sslv3 alert certificate unknown: SSL alert number 46, session=<SESSION-ID>

the complete certificate chain (such as for the Let's Encrypt CA) needs to be contained in a single file. In other words, the /etc/ssl/domain.tld.fullchain.pem file needs to be used instead of the /etc/ssl/domain.tld.crt.

Notice that the ssl_ca parameter is used for a completely different purpose, i.e. client certificate verification/authentication, i.e. with ssl_verify_client_cert=yes.


Final Steps

Configuration can be tested as follows:

$ doveconf -n | head -n 1
# 2.3.5.1 (7ec6d0ade): /etc/dovecot/dovecot.conf

Non-default configuration values can be printed as follows:

$ doveconf -n

All configuration values can be printed as follows:

$ doveconf -a

In OpenBSD, the openfiles-cur value needs to be increased in the /etc/login.conf file. Otherwise, Dovecot will fail to start accordingly (Too many open files error in logs).

$ vi /etc/login.conf
dovecot:\
        :openfiles-cur=1024:\
        :openfiles-max=2048:\
        :tc=daemon:

And finally, the database needs to be refreshed by the cap_mkdb command as follows:

$ cap_mkdb /etc/login.conf

Dovecot can be enabled and started by:

$ rcctl enable dovecot
$ rcctl start dovecot

Dovecot can be checked by:

$ rcctl check dovecot

Logs can be verified in:

$ tail -f /var/log/maillog
May 10 17:05:26 server dovecot: master: Dovecot v2.2.28 (bed8434) starting up for imap, lmtp
May 10 17:05:26 server dovecot: ssl-params: Generating SSL parameters

Verification

Using Dovecot directly, user existence check can be performed as follows:

$ doveadm -v user user1@domain.tld
field   value
user    user1
uid     1001
gid     1001
home    /var/vmail/domain.tld/user1/
mail    maildir:~

Using Dovecot directly, authentication check can be performed as follows:

$ doveadm auth test user1@domain.tld
Password: USER-PASSWORD
passdb: user1@domain.tld auth succeeded
extra fields:
  user=user1@domain.tld

Using Postfix, user existence check can be performed (using the postmap or postalias commands) as follows:

$ postmap -q domain.tld ldap:/etc/postfix/ldap-virtual_mailbox_domains.cf
0
$ postmap -q postmaster@domain.tld ldap:/etc/postfix/ldap-virtual_alias_maps.cf
user1@domain.tld
$ postmap -q user1 ldap:/etc/postfix/ldap-virtual_mailbox_maps.cf
domain.tld/user1/

Using Postfix, authentication check (using the SASL mechanism) can be performed in two steps.

$ printf "\0%s\0%s" "user1@domain.tld" "USER-PASSWORD" | openssl enc -base64
BASE64-ENCODED-USER-CREDENTIALS
$ openssl s_client -host server.domain.tld -port 587 -starttls smtp
CONNECTED(00000003)
<OUTPUT OMITTED>

250 DSN
EHLO test.domain.tld
250-server.domain.tld
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN
334
BASE64-ENCODED-USER-CREDENTIALS
235 2.7.0 Authentication successful
QUIT
DONE

Fine Tuning

Instead of the traditional syslog destination (which is /var/log/maillog in OpenBSD by default), a different log_path value can be defined (e.g. /var/log/dovecot.log):

$ echo "log_path = /var/log/dovecot.log" >> /etc/dovecot/conf.d/10-logging.conf
$ rcctl reload dovecot

In OpenBSD, the log-rotation can be set up in /etc/newsyslog.conf as follows:

$ echo "/var/log/dovecot.log                    640  7     10   *     Z" >> /etc/newsyslog.conf
$ cat /etc/newsyslog.conf
#       $OpenBSD: newsyslog.conf,v 1.36 2016/12/27 09:17:52 jca Exp $
#
# configuration file for newsyslog
#
# logfile_name          owner:group     mode count size when  flags
<OUTPUT-OMITTED>
/var/log/dovecot.log                    640  7     10   *     Z

And the syslog daemon can be reloaded as follows:

$ rcctl reload syslogd

Tags: #OpenBSD #security #Dovecot #MTA #MSA #MDA #LDA #MUA #exchange #TLS

⏴ Previous Post Next Post ⏵