Migration Cyrus 2.3 zu Dovecot
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
nachcyrus-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)
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-sql
& sendmail+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
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.
- Berkeley to Skiplist (siehe Cyurs Migrations Page)
- Cyrus2Dovecot README (! WICHTIG ! – bitte lesen und auf Script auf die eigenen Bedürfnisse anpassen)
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.