Alte Dovecot Konfiguration zu Dovecot 2.4 (Debian Trixie) migrieren
Seit einigen Wochen ist die neue Debian-Version “Trixie” zum Upgrade von Debian “Bookworm” erhältlich - und damit haben sich auch einige meiner Leser zu einer Aktualisierung ihres Mailserver-Setups aus meiner “Mailserver mit Dovecot, Postfix, MySQL und Rspamd unter Debian 10 Buster [v1.0]” Mailserveranleitung entschieden. Das für Debian Buster beschriebene Setup funktioniere nämlich genauso gut auch für Debian Bookworm - aber mit Debian Trixie kommt der Bruch:
Die Konfigurations-Syntax hat sich an einigen Punkten stark geändert und alte Konfigurationen aus vorherigen Dovecot-Versionen können nicht mehr eingelesen werden. Dieser Beitrag geht auf die Änderungen in der neuen Version 2.4 ein und erklärt die Migration anhand des Beispiels der oben erwähnten Mailserveranleitung. Alle Änderungen spielen sich in der Datei /etc/dovecot/dovecot.conf ab. Weitere Änderungen (z.B. an Datenbankschema o.Ä.) sind nicht notwendig.
Insgesamt hat sich verändert:
- Die Art und Weise, wie Konfigurationsparameter geschachtelt werden können
- Namen einzelner Parameter
- Variablennamen und -Funktionen
Alle Änderungen sind in der Dovecot-Dokumentation beschrieben. Wer beim Setup seines Mailservers meiner Anleitung gefolgt ist, kann jedoch einfach weiterlesen und die beschriebenen Schritte ausführen, um zu einer funktionierenden Konfiguration zu kommen.
Schritt 1: Config-Versionsnummern hinzufügen
Dovecot 2.4 führt eine Versionierung der Konfigurationssyntax ein. Deshalb müssen am Anfang der Datei folgende Zeilen unbedingt eingefügt werden:
# Dovecot config and storage versions
dovecot_config_version = 2.4.0
dovecot_storage_version = 2.4.0
Das Versäumnis aus der Vergangenheit scheint man nun nachgeholt zu haben ;-). Zukünftige Änderungen an der Syntax können dann von Dovecot selbst abgefangen werden bzw. bei Änderungen gewarnt werden.
SSL-Einstellungen
Die SSL-Einstellungen werden wie folgt umbenannt bzw. verändert:
ssl_cert=>ssl_server_cert_file(und spitze Klammer zu Beginn weglassen)ssl_key=>ssl_server_key_file(und spitze Klammer zu Beginn weglassen)ssl_dh=>ssl_server_dh_file(und spitze Klammer zu Beginn weglassen)ssl_prefer_server_ciphers=>ssl_server_prefer_ciphers. Werte nicht “yes” oder “no”, sondern “client” oder “server”. Default: Client. Einstellung kann entfernt werden.ssl_min_protocol: kann weggelassen werden, default ist bereits TLSv1.2disable_plaintext_auth=yes=>auth_allow_cleartext=no. Ist default - kann weggelassen werden.
Insgesamt ergibt sich also:
ssl = required
ssl_server_cert_file = /etc/acme.sh/mydomain.tld/fullchain.pem
ssl_server_key_file = /etc/acme.sh/mydomain.tld/privkey.pem
ssl_server_dh_file = /etc/dovecot/dh4096.pem
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
PassDB / UserDB und auth_username_format
Die beiden PassDB und UserDB Abschnitte werden zu:
passdb sql {
query = SELECT username AS user, domain, password FROM accounts WHERE username = '%{user | username | lower }' AND domain = '%{user | domain | lower}' and enabled = true;
}
userdb sql {
query = SELECT concat(quota, 'M') AS quota_storage_size FROM accounts WHERE username = '%{user | username | lower }' AND domain = '%{user | domain | lower}' AND sendonly = false;
iterate_query = SELECT username, domain FROM accounts where sendonly = false;
}
Achtet speziell auf die angepassten Variablen, z.B. %{user | username | lower }. Hinter dem concat(quota, 'M') AS quota_storage_size versteckt sich außerdem ein kleiner Bugfix, den ich hier direkt einbringen will. ;-)
Außerdem wird die Variable auch bei auth_username_format angepasst:
auth_mechanisms = plain login
auth_username_format = %{user | lower }
Damit die gerade definierten UserDB und PassDB Abschnitte überhaupt funktionieren, werden die Zugangsdaten zur MySQL-Datenbank in einem neuen SQL-Abschnitt definiert:
sql_driver = mysql
mysql /var/run/mysqld/mysqld.sock {
user = vmail
password = mypassword
dbname = vmail
}
mypassword muss selbstverständlich angepasst werden!
Die Datei /etc/dovecot/dovecot-sql.conf kann vollständig gelöscht werden - sie wird nicht mehr benötigt.
Mail location
Die Definition des Mailspeicherorts mail_location wird in mehrere Parameter aufgeteilt und hierdurch ersetzt:
mail_driver = maildir
mail_path = ~/mail
mailbox_list_layout = fs
Außerdem bekommt der mail_home Parameter neue Variablennamen:
mail_home = /var/vmail/mailboxes/%{user | domain }/%{user | username }
Protocols
Die protocols Einstellung und die beiden protocol imap und protocol lmtp Sections werden zu diesem Block:
protocols {
lmtp = yes
imap = yes
sieve = yes
}
protocol imap {
mail_plugins {
imap_quota = yes
imap_sieve = yes
}
mail_max_userip_connections = 50
imap_idle_notify_interval = 29 mins
}
protocol lmtp {
mail_plugins {
sieve = yes
notify = yes
push_notification = yes
}
postmaster_address = postmaster@mydomain.tld
}
Plugins Section
Das plugins Segment
plugins {
...
}
gibt es nicht mehr. Stattdessen wird der Inhalt direkt global.
Sieve Plugineinstellungen
sieve_plugins,sieve_beforeundsievewerden zu:
sieve_plugins {
sieve_imapsieve = yes
sieve_extprograms = yes
}
sieve_script spam-global {
type = before
path = /var/vmail/sieve/global/spam-global.sieve
}
sieve_script personal {
type = personal
path = /var/vmail/sieve/%{user | domain }/%{user | username }/scripts
active_path = /var/vmail/sieve/%{user | domain }/%{user | username }/active-script.sieve
}
Alle imapsieve* Parameter werden insgesamt zu:
# From Mailbox to Spam
mailbox Spam {
sieve_script spam {
type = before
cause = copy
path = /var/vmail/sieve/global/learn-spam.sieve
}
}
# From Spam to another folder (learn HAM)
imapsieve_from Spam {
sieve_script ham {
type = before
cause = copy
path = /var/vmail/sieve/global/learn-ham.sieve
}
}
sieve_global_extensions wird zu:
sieve_global_extensions {
vnd.dovecot.pipe = yes
}
Quota
quota und quota_exceeded_message werden zu:
quota "User quota" {
driver = count
}
quota_exceeded_message = Benutzer %{user} hat das Speichervolumen ueberschritten. / User %{user} has exhausted allowed storage space.
Der alte “fs” Treiber für Quota soll nicht mehr genutzt werden. Stattdessen wird nun count genutzt. quota_exceeded_message bekommt außerdem neue Variablennamen.
Im neuen mail_plugins Blog wird das Quota-Plugin aktiviert:
mail_plugins {
quota = yes
}
Im vorher bereits erwähnten protocol imap Block wurde außerdem noch imap_quota aktiviert.
Vollständige Beispielkonfiguration
Für den einfacheren Vergleich hier nochmal die vollständige Datei /etc/dovecot/dovecot.conf:
# Dovecot config and storage versions
dovecot_config_version = 2.4.0
dovecot_storage_version = 2.4.0
###
### Protocol settings
#############################
protocols {
lmtp = yes
imap = yes
sieve = yes
}
protocol imap {
mail_plugins {
imap_quota = yes
imap_sieve = yes
}
mail_max_userip_connections = 50
imap_idle_notify_interval = 29 mins
}
protocol lmtp {
mail_plugins {
sieve = yes
notify = yes
push_notification = yes
}
postmaster_address = postmaster@mydomain.tld
}
##
## TLS Config
## Quelle: https://ssl-config.mozilla.org/#server=dovecot&version=2.3.9&config=intermediate&openssl=1.1.1d&guideline=5.4
##
ssl = required
ssl_server_cert_file = /etc/acme.sh/mydomain.tld/fullchain.pem
ssl_server_key_file = /etc/acme.sh/mydomain.tld/privkey.pem
ssl_server_dh_file = /etc/dovecot/dh4096.pem
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
###
### Dovecot services
################################
service imap-login {
inet_listener imap {
port = 143
}
}
service managesieve-login {
inet_listener sieve {
port = 4190
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0660
group = postfix
user = postfix
}
user = vmail
}
service auth {
### Auth socket für Postfix
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
### Auth socket für LMTP-Dienst
unix_listener auth-userdb {
mode = 0660
user = vmail
group = vmail
}
}
###
### SQL settings
###
sql_driver = mysql
mysql /var/run/mysqld/mysqld.sock {
user = vmail
password = mypassword
dbname = vmail
}
###
### Client authentication
#############################
auth_mechanisms = plain login
auth_username_format = %{user | lower }
passdb sql {
query = SELECT username AS user, domain, password FROM accounts WHERE username = '%{user | username | lower }' AND domain = '%{user | domain | lower}' and enabled = true;
}
userdb sql {
query = SELECT concat(quota, 'M') AS quota_storage_size FROM accounts WHERE username = '%{user | username | lower }' AND domain = '%{user | domain | lower}' AND sendonly = false;
iterate_query = SELECT username, domain FROM accounts where sendonly = false;
}
##
### Address tagging
###
recipient_delimiter = +
###
### Mail location
#######################
mail_uid = vmail
mail_gid = vmail
mail_privileged_group = vmail
mail_home = /var/vmail/mailboxes/%{user | domain }/%{user | username }
mail_driver = maildir
mail_path = ~/mail
mailbox_list_layout = fs
###
### Mailbox configuration
########################################
namespace inbox {
inbox = yes
mailbox Spam {
auto = subscribe
special_use = \Junk
}
mailbox Trash {
auto = subscribe
special_use = \Trash
}
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
mailbox Sent {
auto = subscribe
special_use = \Sent
}
}
###
### Mail plugins
############################
mail_plugins {
quota = yes
}
sieve_plugins {
sieve_imapsieve = yes
sieve_extprograms = yes
}
sieve_script spam-global {
type = before
path = /var/vmail/sieve/global/spam-global.sieve
}
sieve_script personal {
type = personal
path = /var/vmail/sieve/%{user | domain }/%{user | username }/scripts
active_path = /var/vmail/sieve/%{user | domain }/%{user | username }/active-script.sieve
}
# From Mailbox to Spam
mailbox Spam {
sieve_script spam {
type = before
cause = copy
path = /var/vmail/sieve/global/learn-spam.sieve
}
}
# From Spam to another folder (learn HAM)
imapsieve_from Spam {
sieve_script ham {
type = before
cause = copy
path = /var/vmail/sieve/global/learn-ham.sieve
}
}
# Sieve extensions only allowed in global context
sieve_global_extensions {
vnd.dovecot.pipe = yes
}
sieve_pipe_bin_dir = /usr/bin
###
### IMAP Quota
###########################
quota_exceeded_message = Benutzer %{user} hat das Speichervolumen ueberschritten. / User %{user} has exhausted allowed storage space.
quota "User quota" {
driver = count
}