trueten.de

"Parteien sind zum Schlafen da - und zum schrecklichen Erwachen." Zeitung 883, 1971

Mini HowTo: OpenDKIM für Postfix installieren

Foto: Lourdes Cardenal
Campo de Criptana Molinos de Viento / La Mancha.
Foto: Lourdes Cardenal, CC BY-SA 3.0, via Wikimedia Commons
Bekanntlich bin ich der Ansicht, daß alle Spammer an ihren Eiern aufgehängt gehören. Da dieser Wunsch für mich momentan etwas schwierig umzusetzen ist, ich aber trotzdem Interesse an einer weitestgehend Spam bzw. Phishing freien Mailverkehr habe, muss ich wie einst Sisyphos (oder war es Don Quixote?) gegen unerwünschte Mails kämpfen. Da ich nicht der einzige bin, der diesen Wunsch hegt, gibt es eine breite Palette an Tools, die einen dabei unterstützen. Als Domaindiktator setze ich dabei am Mailserver an: "DomainKeys ist ein Identifikationsprotokoll zur Sicherstellung der Authentizität von E-Mail-Absendern, das von Yahoo entwickelt wurde und seit Ende 2013 ein Internet-Standard ist. Es wurde konzipiert, um bei der Eindämmung von unerwünschter E-Mail wie Spam oder Phishing zu helfen."  DKIM-Signaturen machen also Veränderungen an Header und Body einer Mail erkennbar.
Da es einige Stolperfallen bei der Einrichtung gibt, die das korrekte Funktionieren verhindern können, habe ich mir ein kurzes und rudimentäres HowTo verfasst:

Das Szenario: Alle Mails der Doman domainname.de sollen signiert werden. Alle eingehenden Mails sollen verifiziert werden. Wir haben Zugriff auf Nameservereinträge der Domain und ein Postfix Server sowie Amavis und Spamassassin verrichten ihren Dienst auf einem debian System. Den DKIM Dienst soll openDKIM übernehmen, das wir gleich mal in einem Terminal zusammen mit ein paar Tools installieren:
sudo apt install opendkim opendkim-tools

Dann legen wir ein Schlüsselverzeichnis an und generieren den Schlüssel. Wichtig ist die korrekte Rechtevergabe in den Schlüsselverzeichnissen! Zudem sollte der Dienst nicht als root laufen sondern unter dem User opendkim. Dieser darf in keiner anderen Gruppe Mitglied sein, ansonsten quittiert der Dienst den selbigen mit einer Fehlermeldung.
mkdir /etc/opendkim/keys/domainname.de
/usr/bin/opendkim-genkey -D /etc/opendkim/keys/domainname.de/ -d domainname.de -s 2020
chown -R root:opendkim /etc/opendkim/keys/domainname.de
chmod 640 /etc/opendkim/keys/domainname.de/2020.private
chmod 644 /etc/opendkim/keys/domainname.de/2020.txt

Im Anschluss bearbeiten wir die /etc/opendkim.conf:
Domain   domainname.de
Selector 2020                             # Das ist der im vorigen Schritt angegebene Selector. Interessant für diejenigen, die den DKIM Key regelmäßig aktualisieren.
KeyFile  /etc/opendkim/domainname.de/2020.private
Socket   inet:8891@localhost
Canonicalization        relaxed/simple    # Auf Headermodifikationen nicht gleich allergisch reagieren
Mode                    sv                # Mails [s]ignieren und [v]erifizieren

Wir starten den Dienst:  sudo systemctl restart opendkim und regeln, daß der Dienst beim Systemstart gleich gestartet wird:  systemctl enable opendkim. Dann befassen wir uns mit der Integration von openDKIM in Postfix. Dazu editieren wir die /etc/postfix/main.cf:
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters

Danach muss  Postfix diese Änderung bekannt gegeben werden: sudo systemctl reload postfix.

Das war es im Grunde dann auch schon. Bis auf eine Kleinigkeit: Die Integration des Schlüssels als TXT Record im Nameservereintrag von domainname.de. Diese Einstellung unterscheidet sich von Provider zu Provider, daher an der Stelle auch nur der allgemeine Hinweis:


Record NameRecord TypeText
mail._domainkeyTXTv=DKIM1; k=rsa; p=MI.. (Hier Inhalt von /etc/opendkim/keys/domainname.de/2020.txt einfügen, dabei alle >"< entfernen und alle Zeilen nach p= in einen Schlüssel ohne Leerzeichen verbinden.)

Das korrekte Eintragen des Schlüssels kann kompliziert sein, vor allem der Teil nach "p=" darf weder um- noch unterbrochen sein. Ansonsten wird der Schlüssel nicht erkannt!

Testen des Keys:
# opendkim-testkey -d domainname.de -s mail -vvv

opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'mail._domainkey.domainname.de'
opendkim-testkey: key not secure
opendkim-testkey: key OK

Sofern keine Fehlermeldungen auftreten, kann man sich nun darum kümmern, eingehenden Spam weiter zu filtern. In Amavis ist der DKIM Filter in einigen Debian Derivaten deaktiviert, lässt sich aber einfach aktivieren. Dazu muss in der Konfigurationsdatei /etc/amavis/conf.d/20-debian-defaults folgender Parameter gesetzt werden:
$enable_dkim_verification = 1;

In der Datei /etc/amavis/conf.d/50-user muss für eine erweitere Anzeige der Überprüfungsergebnisse dann als letztes noch folgender Parameter gesetzt werden:
$allowed_added_header_fields{lc('Authentication-Results')} = 1;

Im täglichen Mailverkehr empfiehlt sich darüber hinaus ein Addon für den freien Mailclient Thunderbird zur Kontrolle der empfangenen Mails: Den DKIM Verifier. Dieses Addon überprüft beim Öffnen einer Mail die Gültigkeit der Signatur. Somit kann man sich (halbwegs) sicher sein, daß die Mail vom signierenden Mailserver stammt. Natürlich nutzen auch einzelne Spammer DKIM. "Es ist wichtig zu beachten, dass eine E-Mail durch eine beliebige Domain signiert seinen kann. Eine gültige Signatur alleine ist daher kein Hinweis auf eine vertrauenswürdige E-Mail. Um zu entscheiden ob eine E-Mail vertrauenswürdig ist sollte immer überprüft werden wer der Signierende ist! In einigen Fällen kann die Abwesenheit einer DKIM Signatur nützlich sein um betrügerische E-Mails zu erkennen. Falls bekannt ist, dass eine Domain alle ihre E-Mails mittels DKIM signiert, ist das Nichtvorhandensein einer DKIM Signatur ein starker Hinweis auf eine gefälschte E-Mail." (Aus der Addon Beschreibung)

Quellen:
debianwiki, Steven Jenkins, Michael Kofler, WikiPediaPhilippe Lieser, Patrick Koetter

Mailserverumzug

Nach einigen Jahren stand ein Umzug des Mailservers an. Hier läuft das Gespann Postfix / Cyrus / Sieve / SpamAssassin / DCC / Phyzor / Razor sowie, der Vollständigkeit halber, der freie Virenscanner ClamAV, natürlich in der aufgebohrten Version, mit drastisch gesteigerter Erkennungsrate. Diese Kombination sorgt bei uns zusammen mit ein bisschen weiteren Kleinkram, den ich hier nicht erwähne, seit Jahren dafür, daß Probleme mit Mails oder Viren praktisch gar nicht bzw. im Fall von Spam nur sehr vereinzelt auftreten.

Die Einarbeitungskurve ist bei den genannten Servern natürlich nicht gerade flach, zahlt sich jedoch durch Stabilität und Zuverlässigkeit über Jahre aus. (So  habe ich heute noch ein paar Mails, die ich, falls mein Blutdruck mal wieder im Keller ist, hervor krame, um mich mal wieder so richtig auzuregen ;-) )

Den mit Abstand größten Aufwand gibt es immer mit dem Cyrus IMAP Server, der sehr stabil läuft, aber auch sehr empfindlich und wenig aussagekräftig bei Fehlern reagiert. So ist zum Beispiel die richtige Einrichtung von Zertifikaten nicht immer ganz trivial. Deswegen getreu dem Motto: Never touch a running System nur Sicherheitsupdates und Parallelbetrieb bei notwendigen größeren Upgrades, um mögliche Ausfälle möglichst gering zu halten. Zwar gibt es immer auch aktuelle Backups, bei Konfigurationsänderungen wegen neuen Features hilft das wenig.

Nachdem also jetzt alles entsprechend zusammengebaut ist, kommt der Streßtest: Import sämtlicher Postfächer aus dem alten in den neuen IMAP Server, Dank der Kombination mit Sieve werden die Mails auch gleich in die entsprechenden automatisch angelegten Ordner einsortiert. Den Importvorgang erledigt imapsync, ein perl Script, das ich aus einer Handvoll Möglichkeiten herausgepickt hatte. Das Script fragt alle möglichen IMAP Postfächer, z.B. Google, GMX, bzw. die jeweils zugrunde liegenden Server wie Courier, Cyrus und wie sie alle heißen, ab und spricht direkt den gewünschten Zielserver an. Gestartet werden kann das Script auf irgendeinem Terminal.

Vor der Installation von imapsync müssen eine Reihe weiterer Bibliotheken und Perl Module installiert werden, zum Beispiel bei dem betreffenden Server, der mit Debian Jessie läuft:

sudo apt install \
 libauthen-ntlm-perl \
 libcgi-pm-perl \
 libcrypt-openssl-rsa-perl \
 libdata-uniqid-perl \
 libfile-copy-recursive-perl \
 libio-socket-inet6-perl \
 libio-socket-ssl-perl \
 libio-tee-perl \
 libhtml-parser-perl \
 libmail-imapclient-perl \
 libparse-recdescent-perl \
 libmodule-scandeps-perl \
 libreadonly-perl \
 libterm-readkey-perl \
 libtest-mockobject-perl \
 libtest-pod-perl \
 libunicode-string-perl \
 liburi-perl \
 libwww-perl \
 make \
 cpanminus

Sobald cpanminus installiert ist, wirft man darüber weitere Module ins System, um die Voraussetzungen für das in Jessie nicht vorhandene Perl Modul Mail::IMAPClient zu installieren:

cpanm Sys::MemInfo

Danach dann:

sudo cpanm Mail::IMAPClient

Sodann kann man für die 2 Faktor Authentifizierung, die im übrigen sehr empfehlenswert ist, das XOAUTH2 Modul installieren:

sudo cpanm JSON::WebToken

Dann kann man endlich dazu übergehen, imapsync selber zu installieren, holen kann man das als normaler User, was natürlich generell empfehlenswert ist:

wget -N https://imapsync.lamiral.info/dist/imapsync

Man macht dann das Script lauffähig:

chmod +x imapsync

Probiert, ob alles geklappt hat:

./imapsync

Und installiert es schließlich an einem beliebigen Ort, hier bei mir immer im lokalen Scriptverzeichnis:

sudo cp imapsync /usr/local/bin/

Die eigentliche Benutzung des imapsync Scriptes ist in der Dokumentation ausführlich beschrieben. Ich setze hier nur eine einfache Variante ein, das Script kann von einem X-beliebigen USer verwendet werden:

/usr/bin/imapsync --host1 imap.gmail.com --user1 karl.napf@googlemail.com --passfile1 ~/secret1 --gmail1 \
--host2 imap.gmx.net --user2 karl.napf@gmx.net --passfile2 ~/secret2 --automap


Das bedeutet, von links nach rechts gelesen: imapsync holt bei Google mit der Userkennung karl.napf@googlemail.com und dem in der Datei ~/secret1 gespeicherten Passwort sowie für Google empfohlenen weiteren Einstellungen die Mails aus dem Postfach und schiebt sie in das GMX Postfach von karl.napf@gmx.net, mit dem in der Datei ~/secret2 gespeicherten Passwort. Der Parameter ermöglicht meiner Erfahrung nach recht zuverlässig das korrekte Mapping bzw. richtige Einsortieren der Mails in die einzelnen Postfächer, jedoch nur die Standards, also Posteingang / INBOX, Gesendet / SENT, Papierkorb / Trash etc.

Weitergehende Sortierung geht über entsprechende regex Filter, die mit imapsync verwendet werden könenn, die bei unserem Server jedoch nicht nötig waren, da die bereits durch jeden User benutzen sieve Filter entsprechend der jeweiligen Bedürfnisse einsortiert werden.

Mailrouting mit Postfix

Ab und zu versende ich größere Dateien, für die ich einen anderen Mailserver verwende. Ebenso geht Spam, der nicht erkannt wurde direkt an ein Lernscript, das spamassasin auf dessen zukünftige Erkennung trainiert. Dazu verwende ich dann jeweils andere Empfägeradressen: Spam geht beispielsweise an spam@mailempfängerdomain_2, Mail an Nutzer im Intranet an mailempfängerdomain_1. Der Rest der Welt wird über smtp_Server_3 mit meinen Erkenntnissen versorgt ;-)

Diese Verteilung bzw. Routing unterschiedlich addressierter Mail funktioniert mit Postfix ziemlich einfach:
Datei /etc/postfix/transport mit folgendem Inhalt anlegen:

# /etc/postfix/transport
# Mails für alle Empfänger in *.mailempfängerdomain_1 gehen über smtp_Server_1
.mailempfängerdomain_1 smtp:smtp_Server_1
# Mails für alle Empfänger in mailempfängerdomain_2 gehen über smtp_Server_2
mailempfängerdomain_2 smtp:smtp_Server_2
# Der Rest geht hierhin
* smtp: smtp:smtp_Server_3


/etc/postfix/main.cf um folgende Einträge ergänzen:

# /etc/postfix/main.cf
# Alle Domains eintragen, für die geroutet wird:
relay_domains = mailempfängerdomain_1, mailempfängerdomain_2
# Routing
transport_maps = hash:/etc/postfix/transport


Anschließend die Befehle ausführen:
postmap /etc/postfix/transport
postfix reload


Logfiles kontrollieren, fertig.