Ok, nach über 15 Jahren mit Cyrus, habe ich mich nun entschieden zu Dovecot zu wechseln. Cyrus lief zwar meist sehr zuverlässig, jedoch gab es in der Vergangenheit immer wieder Probleme nach Updates – hauptsächlich wegen der verwendeten Berkeley Datenbank.

Nach meinem letzten Update von

cyrus-imapd23-2.3.19_2 nach cyrus-imapd23-2.3.20_2

hatte ich endgültig nur noch Probleme. Nicht mal ein komplettes löschen und rebuilden der Datenbanken half hier noch. Der Mailserver lief dann für ein paar Stunden, dann ist er wieder abgestürzt.

 imap[1073]: DBERROR: critical database situation
 imap[1074]: DBERROR db5: BDB0060 PANIC: fatal region error detected; run recovery

Ohne Nagios hätte ich selber alle paar Stunden den Mailserver neu starten müssen, damit Mails empfangen werden konnten. Ich konnte den Auslöser des Fehlers nicht finden, da die Abstürze sehr willkürlich waren (Zeitweise lief Mailserver locker 8 Stunden zuverlässig, dann ein Crash, dann lief er 1 weitere Stunde, dann wieder ein Crash, etc.) und die Logfiles auch keine nützlichen Hinweise auf die Ursache gaben.

Die neueren Cyrus Versionen verwenden die Berkeley Datenbank zwar nicht mehr – da ich aber so oder so nicht einfach von Version 2.3 auf eine neuere upgraden kann, sondern migrieren muss, habe ich mich nach einer Alternative umgeschaut. Denn bei der Analyse der Logfiles ist mir auch aufgefallen, dass wir sehr viele abusive Login Versuche auf dem Mailserver haben. So wurde ich auf Dovecot aufmerksam – ich fand hierfür ein Plugin in der Art von DenyHosts. Damit kann man bösartige Loginversuche auf eine Blacklist setzen, so wie das DenyHosts für SSH macht.

Da Dovecot mittlerweile viel verbreiteter ist als Cyrus und auch besser dokumentiert, stand die Entscheidung für den Wechsel schnell fest.

Wer nicht migrieren muss, sondern Dovecot frisch installieren möchte, findet hier die Anleitung dazu.

Installation Dovecot

pkg install dovecot

Der vorkompilierte Dovecot Port kommt leider ohne MySQL Support. Und bis jetzt wird leider noch kein dovecot-mysql Port angeboten. Daher muss man Dovecot unter FreeBSD leider selber Builden, wenn man MySQL Support wünscht:

cd /usr/ports/mail/dovecot
make install clean

Hier MySQL für den Datenbank Support auswählen:

┌───────────────────────────── dovecot-2.3.2.1 ────────────────────────────────┐
│ ┌──────────────────────────────────────────────────────────────────────────┐ │  
│ │+[x] DOCS            Build and/or install documentation                   │ │  
│ │+[x] EXAMPLES        Build and/or install examples                        │ │  
│ │+[x] LIBWRAP         TCP wrapper support                                  │ │  
│ │+[ ] LUA             Lua scripting language support                       │ │  
│ │+[ ] LZ4             LZ4 compression support                              │ │  
│ │+[ ] VPOPMAIL        vpopmail support                                     │ │  
│ │───────────────────────────── Database support ───────────────────────────│ │  
│ │+[ ] CDB             CDB database support                                 │ │  
│ │+[ ] LDAP            LDAP protocol support                                │ │  
│ │ [x] MYSQL           MySQL database support                               │ │  
│ │+[ ] PGSQL           PostgreSQL database support                          │ │  
│ │+[ ] SQLITE          SQLite database support                              │ │  
│ │───────────────────────── Full text search plugins ───────────────────────│ │  
│ │+[ ] ICU             Use libicu for FTS unicode normalization             │ │  
│ │+[ ] LUCENE          CLucene FTS support                                  │ │  
│ │+[ ] SOLR            Solr FTS support                                     │ │  
│ │+[ ] TEXTCAT         Libtextcat FTS support                               │ │  
│ │─────────────────────── GSSAPI Security API support ──────────────────────│ │  
│ │+(*) GSSAPI_NONE     Build without GSSAPI support                         │ │  
│ │+( ) GSSAPI_BASE     Use GSSAPI from base                                 │ │  
│ │+( ) GSSAPI_HEIMDAL  Use Heimdal GSSAPI from security/heimdal             │ │  
│ │+( ) GSSAPI_MIT      Use MIT GSSAPI from security/krb5                    │ │  
│ └──────────────────────────────────────────────────────────────────────────┘ │  
├──────────────────────────────────────────────────────────────────────────────┤  

Jetzt noch locken, damit es beim nächsten pkg upgrade nicht mit dem vorkompilierten Port überschrieben wird:

pkg lock dovecot

Dann noch das Sieve Plugin mit Managesieve Support:

cd /usr/ports/mail/dovecot-pigeonhole
make install clean
pkg lock dovecot-pigeonhole

 

Konfiguration

Verfügbare Variabeln:

  • %u: Kompletter Username (user@domain).
  • %n: Username ohne Domain Part.
  • %d: Domain Part.
  • %h: User Home Verzeichnis (bevorzugt sollte man jedoch ~/ verwenden)

Liste aller Variabeln

Ich möchte, dass die Mails im Verzeichnis

/mail/dovecot/USERNAME/Maildir 

gespeichert werden. Also mal alle Verzeichnisse erstellen:

mkdir -p /mail/dovecot

Als erstes den vmail User hinzufügen für die Nutzung einer Single UID und GID für alle User. (Kann bei Bedarf per userdb überschrieben werden)

adduser vmail
Username: vmail
Full name: Dovecot Virtual User
Uid (Leave empty for default):
Login group [vmail]:
Login group is vmail. Invite vmail into other groups? []:
Login class [default]:
Shell (sh csh tcsh bash rbash git-shell nologin) [sh]: nologin
Home directory [/home/vmail]: /mail/dovecot
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]: no
Lock out the account after creation? [no]:

Berechtigungen setzen:

chown -R vmail:vmail /mail/dovecot
chmod 0750 /mail/dovecot

Konfigfiles kopieren:

cp -R /usr/local/etc/dovecot/example-config/* /usr/local/etc/dovecot

dovecot.conf

vi /usr/local/etc/dovecot/dovecot.conf

Sieve bei den Protokollen hinzufügen

# Protocols we want to be serving.
#protocols = imap pop3 lmtp submission
protocols = imap pop3 lmtp sieve

conf.d/10-mail.conf

Hier folgendes anpassen. Beachte: da ich dieselbe Verzeichnisstruktur wie bei Cyrus wünsche, wähle ich hier LAYOUT=fs.

vi /usr/local/etc/dovecot/conf.d/10-mail.conf
mail_home = /mail/dovecot/%n
mail_location = maildir:~/Maildir:LAYOUT=fs
namespace inbox {
 separator = .
prefix = INBOX.
inbox = yes
}
mail_uid = vmail
mail_gid = vmail

MySQL Auth mit Username ohne Domain Part (identisch mit Cyrus)

In den Email Clients sollen nach der Migration von Cyrus->Dovecot keine Umstellungen notwendig werden. Die User sollen sich weiterhin mit dem Usernamen ohne dem Domain Part einloggen können (nicht der vollen Emailadresse username@domain.com, wie es bei Dovecot normalerweise Pflicht ist)

Diese password_query erlaubt nun das Login entweder mit Usernamen oder Username+Domain.

Ich nutze dazu meine bereits bestehende Datenbankstruktur von Cyrus:

vi /usr/local/etc/dovecot/dovecot-sql.conf.ext
driver = mysql
#
connect = host=sql.example.com dbname=virtual user=virtual password=blarg
#
default_pass_scheme = PLAIN
#
password_query = SELECT CONCAT(username, '@', domain) AS user, password FROM mail_entries WHERE ( username = '%Lu' OR ( username = '%Ln' AND domain = '%Ld' ) ) AND is_active = 1 AND is_mainaccount = 1


Falls man home/maildir/uid auch für jeden User abfagen möchte, kann man die Query so gestalten:

password_query = 
   SELECT 
     CONCAT(username, '@', domain) AS user, 
     password, 
     home AS userdb_home, 
     CONCAT('maildir:', home) AS userdb_mail, 
     uid AS userdb_uid, 
     gid AS userdb_gid 
   FROM mail_entries 
   WHERE ( username = '%Lu' 
           OR ( username = '%Ln' AND domain = '%Ld' ) 
) AND is_active = 1 AND is_mainaccount = 1

user_query ist in meinem Fall nicht nötig, da ich diese Infos (uid,gid,home und mail) bereits global angegeben habe (Single UID/GID Setup).

SQL Auth aktivieren und default system auth deaktivieren:

vi /usr/local/etc/dovecot/conf.d/10-auth.conf 
disable_plaintext_auth = no
auth_mechanisms = login plain cram-md5 digest-md5
#
#!include auth-system.conf.ext
!include auth-sql.conf.ext

Jetzt noch userdb abschalten:

vi /usr/local/etc/dovecot/conf.d/auth-sql.conf.ext

userdb driver=sql abschalten. Static brauchen wir auch nicht zu aktivieren, da wir im 10.-mail.conf die globalen Settings (mail_uid/mail_gid) bereits eingetragen haben.:

# "prefetch" user database means that the passdb already provided the
# needed information and there's no need to do a separate userdb lookup.
# <doc/wiki/UserDatabase.Prefetch.txt>
#userdb {
# driver = prefetch
#}

#userdb {
# driver = sql
# args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
#}

# If you don't have any user-specific settings, you can avoid the user_query
# by using userdb static instead of userdb sql, for example:
# <doc/wiki/UserDatabase.Static.txt>
#userdb {
# driver = static
# args = uid=vmail gid=vmail home=/var/vmail/%u
#}

SSL Config

Dafür nehme ich ein bestehendes SSL Zertifikat -> wie du ein Zertifikat mit Certbot erstellen kannst, ist hier beschrieben:

Let’s Encrypt SSL Zertifikate mit Certbot erstellen

DH Parameters

Ab Dovecot Version 2.3 ist die Angabe von DH Parametern zwingend. Falls für den Server diese noch nicht generiert wurden (achtung: dauert SEHR! lange), müsste dies noch gemacht werden. Wenn man möchte, kann man alternativ auch 2048 generieren – das geht etwas schneller.

openssl dhparam -out /etc/ssl/dhparams_4096.pem 4096

Danach die Config anpassen:

vi /usr/local/etc/dovecot/conf.d/10-ssl.conf 

Folgendes anpassen:

ssl = yes
ssl_cert = </global/configs/letsencrypt_data/live/mail.meinmailserver.com/fullchain.pem
ssl_key = </global/configs/letsencrypt_data/live/mail.meinmailserver.com/privkey.pem
ssl_dh = </etc/ssl/dhparams_4096.pem

Weitere Infos Dovecot SSL Configuration

COMPRESS=DEFLATE

Um die Komprimierung zu aktivieren, wird das zlib Plugin verwendet.

Die Kompression kann für das Lesen (IMAP) und Schreiben (LMTP) aktiviert werden:

vi /usr/local/etc/dovecot/conf.d/20-imap.conf

In der Section protocol imap {

protocol imap {
# Space separated list of plugins to load (default is global mail_plugins).
#mail_plugins = $mail_plugins
mail_plugins = $mail_plugins zlib imap_zlib

# Maximum number of IMAP connections allowed for a user from each IP address.
# NOTE: The username is compared case-sensitively.
#mail_max_userip_connections = 10
}
vi /usr/local/etc/dovecot/conf.d/20-lmtp.conf

In der Section protocol lmtp {

protocol lmtp {
# Space separated list of plugins to load (default is global mail_plugins).
#mail_plugins = $mail_plugins
mail_plugins = $mail_plugins zlib
}

Und jetzt noch die Plugins:

vi /usr/local/etc/dovecot/conf.d/90-plugin.conf
plugin {
#setting_name = value
zlib_save_level = 6 # 1..9; default is 6
zlib_save = gz # or bz2, xz or lz4
}

Beachte: COMPRESS=DEFLATE wird erst nach dem Login angezeigt. So kann man es testen:

telnet mail.testserver.com 143
Trying 111.22.33.44...
Connected to mail.testserver.com.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ STARTTLS AUTH=LOGIN AUTH=PLAIN AUTH=CRAM-MD5 AUTH=DIGEST-MD5] Dovecot ready.
a login "username" "passwort"
a OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE SNIPPET=FUZZY LITERAL+ NOTIFY SPECIAL-USE COMPRESS=DEFLATE] Logged in

Konfiguration testen / anschauen

doveconf -n

Dovecot aktivieren

Dovecot aktivieren und gleichzeitig Cyrus deaktivieren:

vi /etc/rc.conf
#-----------------------------------------------#
# Mail Server #
#-----------------------------------------------#
# Cyrus
#cyrus_imapd_enable="YES"
dovecot_enable="YES"

 

SASL & Sendmail

SASL (Simple Authentication and Security Layer) wird für die Sendmail/SMTP Authentifizierung benötigt.

Dovecot bietet zwar auch SASL an (siehe Dovecot Wiki) – allerdings nicht für Sendmail. Daher können (müssen) wir hier weiterhin das SASL von Cyrus benutzen (FreeBSD Ports cyrus-sasl-sqlsendmail+tls+sasl2) . Siehe Sendmail/SASL Installation unter FreeBSD.

Falls sich bei der Migration eventuell noch die MySQL Query verändert hat, kann man diese einfach noch im SASL Config anpassen:

vi /usr/local/lib/sasl2/Sendmail.conf

Die SASL SQL Query würde analog zu Dovecot so aussehen:

sql_select: SELECT password FROM mail_entries WHERE ( username = '%u' OR ( username = '%u' AND domain = '%r' ) ) AND is_active = 1 AND is_mainaccount = 1

sendmail.mc

Hier alles was Cyrus ist deaktivieren und die Dovecot Konfig rein:

dnl #FEATURE(local_lmtp)
FEATURE(`local_lmtp',`[IPC]',`FILE /var/run/dovecot/lmtp')dnl
MODIFY_MAILER_FLAGS(`LOCAL', `+u')dnl
MODIFY_MAILER_FLAGS(`LOCAL', `-w')dnl
dnl ## define(`confLOCAL_MAILER', `cyrusv2')
[.. hier die restlichen MAILER Definitionen ..]
dnl ### Mailers
MAILER(`local')
dnl ##MAILER(`cyrusv2')

Dann die Sendmail Configs neu builden.

ABER: SENDMAIL NOCH NICHT RESTARTEN!

-> falls etwas bei der Migration schief läuft, würden nun einfach mal alle neuen Mails Abgewiesen (temp. deferred), da ja Cyrus nicht mehr läuft und Sendmail deshalb die Mails temporär nicht zustellen kann.

Sendmail daher erst nach erfolgreichen Migration restarten..

Migration

Für die Migration verwende ich

cyrus2dovecot

Beachte: Das Migrationsscript löscht die /var/spool/imap Daten von Cyrus NICHT. Im Falle eines Fehlers/Problems während der Migration kann also problemlos wieder auf Cyrus zurückgeswitched werden. Bei der Migration werden stattdessen Kopien für Dovecot erstellt. Beachte daher, dass es auf der Festplatte genügend Platz für die Migration hat – bis die Cyrus Daten gelöscht werden können.

cd /usr/local/software
fetch https://github.com/a-schild/cyrus2dovecot/archive/master.zip
tar xzfv master.zip
cd cyrus2dovecot-master/
chmod 775 cyrus2dovecot

Für den Import habe ich das Scriptbeispiel von cyrus2dovecot verwendet und auf meine Bedürfnisse angepasst. Ich konnte den Script eigentlich gleich so laufen lassen, da meine Cyrus Version bereits Skiplist Formate benutzte. Falls die *.seen und *.sub Files noch im Berkeley Format sind, müssten diese noch in Skiplist umkonvertiert werden.

Script erstellen

Nun für die Migration ein Script erstellen, welches die Cyrus Mailboxen auflistet und an cyrus2dovecot für die Migration übergibt.

vi dovecot.sh

Inhalt:

#!/bin/sh

in=/var/spool/imap/user # Cyrus INBOXes.
db=/var/imap/user/? # Cyrus seen/subscription files.
out=/mail/dovecot # Dovecot Maildirs.
log=/mail/conversion.log # Log of successful conversions.
err=/mail/error.log # Log of conversion errors.

for u in `find $in/. ! -name . -prune -exec basename {} ;`
do
/usr/local/software/cyrus2dovecot-master/cyrus2dovecot
--cyrus-inbox $in/$u
--cyrus-seen $db/$u.seen
--cyrus-sub $db/$u.sub
--dovecot-inbox $out/$u/Maildir
--edit-foldernames 's/^.//'
--edit-foldernames 's/.///g'
--debug
$u 2>&1 >>$log | tee -a $err >&2
done
echo "conversion done. setting permissions..."
chown -R vmail:vmail $out/*
echo "done"
chmod 775 dovecot.sh

Migration starten

Dafür Cyrus stoppen

service imapd stop

Migration starten

./dovecot.sh

Die Migration verfolgen:

tail -f /var/log/conversion.log
tail -f /var/log/error.log

Migration Testen

Für den Test Dovecot starten und mal schauen, ob ich die Inboxen (inkl. Subfolders) über mein Mailprogramm aufrufen kann.

service dovecot start

Wenn es nicht klappt, Fehlermeldungen & Lofiles prüfen und allfällige Fehler korrigieren.

Da neue Mails ja noch abgewiesen werden (Sendmail will noch in die Cyrus Mailboxen delivern), können im Notfall die Dovecot Mailboxen nochmals komplett gelöscht und das cyrus2dovecot Script erneut mit anderen Optionen gestartet werden.

Können die Mailboxen aufgerufen werden? Gut! Dann kann jetzt sendmail neu gestartet werden. Ich mach sicherheitshalber ein killall, da ein einfaches sendmail restart nicht immer den gewünschten Erfolg bringt.

killall sendmail
service sendmail start

Nun Testmails versenden von intern->intern und von externen Mailservern.

Es sollte nun alles reibungslos funktionieren 🙂

Logfiles

Die Locations der Logfiles findest du mit dem Befehl

doveadm log find

Konfigurieren kann man sie im File

vi /usr/local/etc/dovecot/conf.d/10-logging.conf

Detailierte Infos zu den Logfiles findest du im dovecot Wiki.

Testen & Fehlermeldungen

Diese Infos findest du auf der Seite für die Clean Dovecot Installation.