Migrating Dovecot CE to 2.4

I use the Dovecot server as provided by the Debian GNU/Linux distribution. Dist-upgrading to Debian 13 “Trixie” forced an upgrade from Dovecot CE version 2.3 to 2.4, imposing significant changes to the configuration syntax. Fortunately, no features or functionality (that i am using) went away. Instead of the “before-and-after” way of explaining how to port your settings to the 2.4 syntax, let me show you my /etc/dovecot/dovecot.conf and what it does.

Several sources on the Internet such as Stackoverflow helped me in the migration. There is also a reference documentation containing all possible settings which also offers a search function:
https://doc.dovecot.org/main/core/summaries/settings.html

First of all, i decide the following:

I use the new version of Dovecot and its new configuration syntax.

dovecot_config_version = 2.4.0

I will not roll back to the old version of Dovecot, so there is no need to keep anything backwards-compatible in my Maildirs, i allow the new version of Dovecot to make backwards-incompatible changes.

dovecot_storage_version = 2.4.0

Note: It is actually not even clear to me if a setting of 2.3.0 was valid here.

Next, i teach Dovecot the layout of my users’ mailboxes. The users have a personal inbox namespace which is located in a Maildir directory /home/$USER/Maildir which is organized in the Maildir++ format – ~/Maildir contains sub-directories that are named like the sub-folders of the user’s inbox. I also let IMAP broadcast some RFC 6154 SPECIAL-USE flags for specific sub-folders.

mail_driver = maildir
mail_path = ~/Maildir
mailbox_list_layout = Maildir++

namespace inbox {
    inbox = yes

    mailbox Drafts {
        special_use = \Drafts
    }

    mailbox Junk {
        special_use = \Junk
    }

    mailbox Sent {
        special_use = \Sent
    }

    mailbox Trash {
        special_use = \Trash
    }
}

Next, i decide which network protocols Dovecot should act as a server for:

Note: In my setup, no LMTP server is needed, because the inbound mail relay is performing local delivery using the dovecot-lda helper executable:

# /etc/postfix/main.cf
# ...
mailbox_command = /usr/lib/dovecot/dovecot-lda -f "$SENDER" -a "$RECIPIENT"
# ...

I need an IMAP server for the mail user agents and also want to enable the Sieve protocol to let users maintain server-side filtering rules:

protocols = imap sieve

I enable the RFC 5464 METADATA extension for IMAP, also defining a per-user dictionary dovecot-attributes, and enable the RFC 6785 support for IMAP events in Sieve:

protocols = imap sieve

protocol imap {
    imap_metadata = yes

    mail_plugins { 
        imap_sieve = yes
    }
}

mail_attribute {
    dict file {
        path = %{home}/Maildir/dovecot-attributes
    }
}

I also enable the Sieve plugin for dovecot-lda:

protocol lda {
    mail_plugins {
        sieve = yes
    }
}

I define a per-user location of Sieve scripts in /home/$USER/Maildir/sieve/dovecot.sieve:

sieve_script personal {
    driver = file
    path = ~/Maildir/sieve
    active_path = ~/Maildir/sieve/.dovecot.sieve
}

I start the RFC 5804 ManageSieve server on port 4190 (note that i do not expose this port on the net, it is only accessed by companion tools such as Roundcube):

service managesieve-login {
    inet_listener sieve {
        listen = 127.0.0.1
        port = 4190
    }
}

To use Dovecot as authentication provider for the Postfix SMTP server, a UNIX domain socket is created, with ownership and permissions suitable for access by the Postfix processes:

service auth {
    unix_listener /var/spool/postfix/private/auth {
        mode = 0660
        user = postfix
        group = postfix
    }
}

Note: This corresponds to the following settings in a /etc/postfix/main.cf on the same host:

# /etc/postfix/main.cf
# ...
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
# ...

I require at least TLS 1.3 and use the Mozilla configuration generator for a cipher list:
https://ssl-config.mozilla.org/#server=dovecot&version=2.4.1&config=intermediate&openssl=3.5.4&guideline=5.7

ssl = required
ssl_min_protocol = TLSv1.2
ssl_server_cert_file = /path/to/acme/fullchain.pem
ssl_server_key_file = /path/to/acme/privkey.pem
# Note: Shortened overlong line, you should generate your own cipher list
# anyway (see link above):
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:...

I use /etc/passwd as user database and PAM as authentication backend.

auth_verbose = yes
auth_debug = no
auth_mechanisms = plain login

userdb passwd {
}

passdb pam {
    service_name = %{protocol}
}

The statement service_name = %{protocol} leads to SMTP clients being authenticated by the PAM stack in /etc/pam.d/smtp and IMAP clients by /etc/pam.d/imap. In my setup, both files are identical and contain configuration of one specific PAM module, pam_listfile.so:

# /etc/pam.d/imap (and ./smtp)
@include common-auth
@include common-account
@include common-password
@include common-session

auth required pam_listfile.so item=user sense=allow file=/etc/security/mailusers onerr=fail

This way i can put the names of users that are allowed to send and receive mails into a text file /etc/security/mailusers, one username per line.