Google lehnt hin und wieder E-Mails ab, die per IPv6 eingeliefert werden. Der Mailserver ist korrekt konfiguriert, SPF, DKIM, DMARC und DANE sind vorhanden, kein Eintrag auf irgendeiner Blacklist. Per IPv4 geht die gleiche Mail problemlos durch.
Die Fehlermeldung
550-5.7.1 Our system has detected that this message is likely
550-5.7.1 unsolicited mail. To reduce the amount of spam sent
550-5.7.1 to Gmail, this message has been blocked.
Der verlinkte Support-Artikel hilft nicht weiter. Alle Vorgaben sind erfüllt. Googles Antwort auf Nachfrage: „Warum genau eine E-Mail abgewiesen wird, können wir Ihnen leider nicht mitteilen.“ Das betrifft gmail.com, googlemail.com und jede bei Google gehostete Domain gleichermaßen.
Workaround: IPv4-only für Google
Da Google per IPv4 keine Probleme macht, lässt sich Postfix so konfigurieren, dass E-Mails an Google-Domains nur über IPv4 zugestellt werden. Das ist unnötig, ärgerlich und widerspricht dem Gedanken hinter IPv6. Aber es funktioniert.
In /etc/postfix/master.cf einen eigenen SMTP-Service anlegen, der nur IPv4 spricht:
smtp4 unix - - - - - smtp -o inet_protocols=ipv4
In /etc/postfix/main.cf die Transport Map aktivieren:
transport_maps = hash:/etc/postfix/transport
Die betroffenen Domains in /etc/postfix/transport eintragen:
googlemail.com smtp4:
gmail.com smtp4:
Anwenden und Postfix neu laden:
postmap /etc/postfix/transport
service postfix reload
E-Mails an Google-Domains gehen ab sofort nur noch über IPv4 raus. Wer weitere Domains pro Ziel steuern will, findet in Postfix TLS Policy Maps einen ähnlichen Ansatz.
Habe ich ganz aktuell gesehen dass sich über die Webseite ssl-tools.net nun ebenfalls die DANE RECORDS testen lassen. Also einmal ob sie vorhanden sind und natürlich auch die Gültigkeit des RECORDS. Zu dem Thema bin ich ja bereits ein paar mal gefragt worden, da „einfache“ Test Tools noch rar waren. Was sich ja inzwischen endlich zu ändern scheint.
Es gibt inzwischen viele Webtools die TLSA-Records prüfen. Aber wer es einmal von Hand gemacht hat, versteht was dabei passiert. Der Ablauf ist immer gleich: Zertifikat vom Server holen, Hash berechnen, mit dem DNS-Record vergleichen.
Zertifikat holen
Verbindung zum Mailserver aufbauen und das Zertifikat per STARTTLS abholen:
Welchen Hash man berechnen muss, hängt vom TLSA-Record ab. Die drei Felder im Record bestimmen das:
Usage
0 = CA, 1 = End-Entity (Kette muss gültig sein), 2 = Trust Anchor, 3 = End-Entity (keine Kettenprüfung)
Selector
0 = ganzes Zertifikat, 1 = nur Public Key (SPKI)
Matching Type
0 = exakter Vergleich, 1 = SHA-256, 2 = SHA-512
Am häufigsten sieht man 3 1 1 (End-Entity, nur Public Key, SHA-256) oder 3 0 1 (End-Entity, ganzes Zertifikat, SHA-256). Zuerst den TLSA-Record aus dem DNS holen um zu sehen was erwartet wird:
dig _25._tcp.smtp.kernel-error.de TLSA +short
Dann den passenden Hash berechnen. Bei Selector 0 (ganzes Zertifikat) und Matching Type 1 (SHA-256):
In der Ausgabe steht am Ende entweder Verified TLS connection established (DANE-Prüfung bestanden) oder eine Fehlermeldung mit dem konkreten Problem. Das Tool löst die MX-Records auf, holt den TLSA-Record, baut die TLS-Verbindung auf und vergleicht alles automatisch.
Mailgraph von David Schweikert ist ein simples Perl-Script, das Postfix-Logdateien parst und daraus RRDtool-Graphen erzeugt. Empfangene, gesendete, abgelehnte Mails auf einen Blick. Für kleinere Mailserver oder Testsysteme reicht das völlig.
Was mailgraph nicht kann: SPF-, DMARC– und DKIM-Ergebnisse darstellen. Wie viele Mails bestehen den SPF-Check? Wie oft schlägt DMARC fehl? Gibt es einen Trend? Ich habe zwar einen existierenden SPF-Patch für mailgraph gefunden, wollte aber alle drei Protokolle in einem Aufwasch.
Die folgenden Patches erweitern mailgraph 1.14 um drei zusätzliche Graphen: SPF (pass/none/fail), DMARC (pass/none/fail) und DKIM (pass/none/fail). Ausgelegt für Postfix mit postfix-policyd-spf, opendkim und opendmarc.
Installation
Auf einem Debian-System müssen zwei Dateien ersetzt werden: /usr/sbin/mailgraph (der Daemon) und /usr/lib/cgi-bin/mailgraph.cgi (die Weboberfläche). Vorher sichern.
Der Daemon-Patch fügt neun RRD-Datasources hinzu (spfnone, spffail, spfpass, dmarcnone, dmarcfail, dmarcpass, dkimnone, dkimfail, dkimpass) und parst die Logzeilen von policy-spf, opendmarc und opendkim:
Der CGI-Patch erzeugt die drei neuen Graphen (SPF, DMARC, DKIM) und bindet sie in die HTML-Ausgabe ein. Jeder Graph zeigt pass als Fläche, none als Stack und fail als Linie:
Der Daemon-Patch erweitert die RRD-Datenbank um neun Datasources und erkennt im Syslog die Ausgaben von drei Diensten:
Dienst
Log-Pattern
Ergebnis
policy-spf
Received-SPF: pass/none/*
spfpass, spfnone, spffail
opendmarc
pass/none/fail
dmarcpass, dmarcnone, dmarcfail
opendkim
DKIM verification successful / no signature data / bad signature data
dkimpass, dkimnone, dkimfail
Der CGI-Patch erzeugt drei neue Graphen unterhalb der bestehenden. Jeder zeigt pass als Fläche, none als Stack darüber und fail als rote Linie. Die Zeiträume (Tag, Woche, Monat, Jahr) werden wie bei den Standard-Graphen automatisch erzeugt.
Hinweise
Die Patches sind für mailgraph 1.14 geschrieben. Weil mailgraph die RRD-Datasources beim ersten Start festlegt, muss nach dem Patchen die bestehende mailgraph.rrd gelöscht werden. Die alten Daten gehen dabei verloren, die neuen Graphen fangen bei Null an.
Wer heute mit dem Monitoring anfängt: rspamd bringt eine eigene Weboberfläche mit und prüft SPF, DKIM und DMARC in einem Durchgang. Zusammen mit Prometheus und Grafana bekommt man deutlich flexiblere Dashboards als mit RRDtool. Mailgraph bleibt trotzdem nützlich wenn man schnell was Schlankes braucht, das ohne externe Abhängigkeiten läuft.
Eine DMARC-Policy zu veröffentlichen ist die eine Seite. Die andere ist, eingehende Mails gegen die DMARC-Policy des Absenders zu prüfen. Postfix kann das nicht selbst. Dafür gibt es zwei Wege: OpenDMARC als eigenständigen Milter oder rspamd, der DMARC als eines von vielen Modulen mitbringt.
Variante 1: OpenDMARC
OpenDMARC ist ein dedizierter DMARC-Milter. Er liest die Ergebnisse von SPF und DKIM aus den Mailheadern und prüft ob die DMARC-Policy des Absenders erfüllt ist.
RejectFailures false ist ein guter Startwert. Damit werden Mails die den DMARC-Check nicht bestehen nicht sofort abgelehnt, sondern nur markiert. So kann man erst beobachten bevor man scharf schaltet. AuthservID muss zum Hostnamen des Mailservers passen.
Wichtig: OpenDMARC verlässt sich darauf, dass SPF und DKIM bereits geprüft wurden und die Ergebnisse in den Authentication-Results-Headern stehen. Die Reihenfolge der Milter in Postfix ist daher entscheidend: SPF und DKIM müssen vor OpenDMARC laufen.
Postfix-Integration
In der main.cf den Milter registrieren. OpenDMARC muss nach dem DKIM-Milter stehen:
Port 8891 ist hier OpenDKIM, Port 8893 OpenDMARC. Nach einem postfix reload prüft OpenDMARC jede eingehende Mail und schreibt einen Authentication-Results-Header mit dem DMARC-Ergebnis.
Variante 2: rspamd
Wer rspamd als Spamfilter einsetzt, braucht keinen separaten DMARC-Milter. rspamd prüft SPF, DKIM und DMARC in einem Durchgang und verrechnet das Ergebnis mit dem Gesamtscore. Das DMARC-Modul ist standardmäßig aktiv und unterstützt auch DMARC-Reporting (rua/ruf).
Der Vorteil von rspamd: Statt einer harten Ablehnung bei DMARC-Fail fließt das Ergebnis in die Gesamtbewertung ein. Eine Mail die DMARC nicht besteht aber sonst sauber aussieht, wird nicht sofort abgelehnt. Umgekehrt kann eine Mail die DMARC besteht trotzdem als Spam markiert werden wenn andere Indikatoren dagegen sprechen.
Was passt besser?
OpenDMARC
rspamd
Aufwand
Eigener Dienst, eigene Config
Bereits als Milter integriert
Verhalten
Harte Entscheidung (reject/accept)
Score-basiert, flexibel
Reporting
Eigenes Reporting-Tool nötig
rua-Reports eingebaut
Abhängigkeiten
Braucht SPF/DKIM in den Headern
Prüft SPF/DKIM selbst
Für neue Setups ist rspamd meist die bessere Wahl, weil es SPF, DKIM, DMARC, ARC und Spam-Filterung in einem Paket liefert. OpenDMARC ist sinnvoll wenn man einen minimalen Stack ohne Content-Filter will oder bereits einen anderen Spamfilter einsetzt.
Übrigens: DMARC und Mailinglisten vertragen sich nicht ohne Weiteres. ARC löst das Problem. Fragen? Einfach melden.
Ich muss gerade bei einigen Systemen den Message Size Limit von Postfix kontrollieren. Jetzt liegen die verschiedenen Kundendomains in verschiedenen Containern. Ich muss also immer nachschauen welcher, da ich faul bin hat mir folgender Einzeiler die Arbeit etwas erleichtert….
Er sammelt sich per dig den gesetzten MX Eintrag der jeweiligen Domain aus dem DNS (es gibt nur einen pro Domain), schneidet die Prio und das Leerzeichen ab und übergibt den übrigen Hostname dann an ssh, welches sich direkt als xyz-user dort anmeldet, Postfix nach dem eingestellten Wert fragt und direkt wieder „auflegt“.
Passt natürlich nicht für jeden Fall, war aber hier wieder schön.
Unsichere Protokolle und Chiper aus Postfix, Dovecot und Apache2 sind schonmal weg!
Jetzt ist mein xmpp Jabber Server ejabberd dran… Auch hier müssen die Protokolle SSLv2 sowie SSLv3 weichen. Nur alles größer TLSv1 ist erlaubt…. Bei den Chipern fliegt alles raus das „böse“ ist… Zum Beispiel MD5, RC4 usw. usw… Natürlich werden auch die ECDHE Cipher suite aktiviert um Forward secrecy zu unterstützen.
Nachdem ich nun am Postfix hinsichtlich der SSL / TLS Sicherheit einige Einstellungen vorgenommen habe und sogar die nutzbare Cipher Suite eingeschränkt habe, da interessiert mich natürlich welche von den Clients genutzt werden. Daher fische ich für meinen Testzeitraum einfach mal per Regex (Regular expression) und egrep ein paar Infos aus dem Logfile und lege es hier zur Begutachtung hin.
So lässt sich nun gut verfolgen, welche Cipher, wie oft genutzt wird.
Perfect Forward Secrecy (PFS) sorgt dafür, dass jede TLS-Verbindung einen eigenen temporären Schlüssel verwendet. Selbst wenn jemand den privaten Schlüssel des Servers in die Hände bekommt, kann er damit früher aufgezeichnete Verbindungen nicht entschlüsseln. Für E-Mail ist das besonders relevant, weil Mailverkehr gern auf Vorrat mitgeschnitten wird.
PFS bekommt man durch ECDHE- oder DHE-Schlüsselaustausch. Moderne OpenSSL-Versionen und aktuelle Postfix/Dovecot-Releases machen das Richtige von Haus aus. Trotzdem lohnt sich ein Blick auf die Konfiguration, um sicherzustellen, dass keine veralteten Protokolle oder Cipher-Suiten aktiv sind.
Postfix
Die relevanten Einstellungen in der main.cf:
# Eingehend (smtpd)
smtpd_tls_security_level = may
smtpd_tls_protocols = >=TLSv1.2
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_mandatory_ciphers = medium
# Ausgehend (smtp)
smtp_tls_security_level = dane
smtp_tls_protocols = >=TLSv1.2
smtp_tls_mandatory_protocols = >=TLSv1.2
smtp_tls_mandatory_ciphers = medium
# Cipher-Präferenz beim Server
tls_preempt_cipherlist = yes
>=TLSv1.2 schaltet TLS 1.0 und 1.1 ab. tls_preempt_cipherlist = yes lässt den Server die Cipher-Reihenfolge bestimmen, nicht den Client. Postfix sortiert AEAD-Ciphers (GCM, CHACHA20) automatisch nach vorn, PFS-Ciphers haben Vorrang. Die medium-Stufe schließt alles unterhalb von 128-Bit-Verschlüsselung aus.
Für den ausgehenden Versand ist smtp_tls_security_level = dane die beste Wahl. Damit prüft Postfix TLSA-Records per DANE. Gibt es keinen TLSA-Record, fällt Postfix auf opportunistisches TLS zurück. Wer zusätzlich MTA-STS auswertet, deckt auch Server ohne DNSSEC ab.
Dovecot
In /usr/local/etc/dovecot/conf.d/10-ssl.conf (FreeBSD) bzw. /etc/dovecot/conf.d/10-ssl.conf (Linux):
ssl = required erzwingt TLS für alle Verbindungen. ssl_min_protocol = TLSv1.2 schließt alte Protokolle aus. ssl_prefer_server_ciphers = yes gibt dem Server die Kontrolle über die Cipher-Wahl. no_ticket deaktiviert TLS Session Tickets, die PFS untergraben können wenn der Ticket-Key kompromittiert wird.
Eine explizite Cipher-Liste ist bei aktuellem OpenSSL nicht nötig. Die Defaults bevorzugen ECDHE mit AEAD. Wer es trotzdem einschränken will:
ssl_cipher_list gilt für TLS 1.2, ssl_cipher_suites für TLS 1.3. Bei TLS 1.3 ist PFS immer aktiv, da gibt es keine Cipher-Suiten ohne Schlüsselaustausch mehr.
Testen
# Postfix (STARTTLS auf Port 25)
openssl s_client -starttls smtp -connect smtp.kernel-error.de:25 2>/dev/null | grep -E "Protocol|Cipher|Server Temp Key"
# Postfix (Implicit TLS auf Port 465)
openssl s_client -connect smtp.kernel-error.de:465 2>/dev/null | grep -E "Protocol|Cipher|Server Temp Key"
# Dovecot (STARTTLS auf Port 143)
openssl s_client -starttls imap -connect imap.kernel-error.de:143 2>/dev/null | grep -E "Protocol|Cipher|Server Temp Key"
# Dovecot (Implicit TLS auf Port 993)
openssl s_client -connect imap.kernel-error.de:993 2>/dev/null | grep -E "Protocol|Cipher|Server Temp Key"
Entscheidend ist die Zeile Server Temp Key. Steht dort X25519, ECDH P-256 oder DH 2048, ist PFS aktiv. Mit OpenSSL 3.5+ und entsprechender Konfiguration sieht man dort auch X25519MLKEM768 für Post-Quantum-Schlüsselaustausch.
Meine Domains sind schon lange per DNSSEC gesichert. Für den Webserver hatte ich auch schnell TLSA-Records veröffentlicht, damit die TLS-Verbindung per DANE abgesichert ist. Seit Postfix 2.11 beherrscht auch der MTA die Prüfung von TLSA-Records — damit lässt sich ausgehende E-Mail-Verschlüsselung kryptographisch verifizieren, ohne sich auf das CA-System verlassen zu müssen.
Postfix konfigurieren
Zwei Zeilen in der main.cf reichen, damit Postfix beim Versand TLSA-Records prüft:
smtp_dns_support_level = dnssec weist den SMTP-Client an, DNSSEC-validierte DNS-Antworten zu verlangen. smtp_tls_security_level = dane aktiviert die TLSA-Prüfung — Postfix sucht automatisch nach TLSA-Records für den Zielserver. Gibt es keinen TLSA-Record oder kein DNSSEC, fällt Postfix auf opportunistisches TLS zurück. Die Kommunikation mit Servern ohne DANE leidet also nicht. Details stehen in der Postfix DANE-Dokumentation.
TLSA-Record erstellen
Der TLSA-Record enthält einen Hash des TLS-Zertifikats (oder des Public Keys), den der Empfänger-Mailserver im DNS veröffentlicht. So erzeugt man den SHA-256-Hash des Public Keys aus dem Zertifikat:
Den Hash trägt man als TLSA-Record in die DNS-Zone ein — für Port 25 (SMTP) und optional Port 465 (Implicit TLS):
_25._tcp.smtp.kernel-error.de. 3600 IN TLSA 3 1 1 8cb0fc6c527506a053f4f14c8464bebbd6dede2738d11468dd953d7d6a3021f1
_465._tcp.smtp.kernel-error.de. 3600 IN TLSA 3 1 1 8cb0fc6c527506a053f4f14c8464bebbd6dede2738d11468dd953d7d6a3021f1
Die Felder 3 1 1 bedeuten: DANE-EE (End Entity, kein CA-Vertrauen nötig), SPKI (nur Public Key, nicht das ganze Zertifikat), SHA-256. Der TTL von 3600 Sekunden ist bewusst kurz — bei einem Zertifikatswechsel soll der alte Record schnell ablaufen. Mehr zum Aufbau von TLSA-Records steht in RFC 7672.
Testen
Mit posttls-finger (Teil von Postfix) lässt sich prüfen, ob die DANE-Verifikation funktioniert:
Verified TLS connection established to smtp.kernel-error.de[...]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
Verified statt Untrusted — der TLSA-Record stimmt mit dem Zertifikat überein, die Verbindung ist DANE-verifiziert. Im Postfix-Log sieht man denselben Unterschied:
smtp[3779]: Verified TLS connection established to mx02.example.de[...]:25
smtp[3779]: Untrusted TLS connection established to smtp2.example.de[...]:25
Verified = DANE-geprüft und in Ordnung. Untrusted = TLS aktiv, aber kein gültiger TLSA-Record vorhanden — die Verschlüsselung funktioniert trotzdem, nur ohne kryptographische Verifikation des Zertifikats.
Warum DANE besser ist als das CA-System
DANE verankert das Vertrauen im DNS statt bei Certificate Authorities. Der Domaininhaber veröffentlicht den Hash seines Zertifikats selbst — DNSSEC schützt den Record vor Manipulation. Keine CA kann ein falsches Zertifikat für die Domain ausstellen und damit die Verbindung aufbrechen. Das Ganze kostet nichts außer einem DNS-Record und funktioniert für jeden, der DNSSEC betreibt.
Zum Vergleich: Das damalige „E-Mail made in Germany“ (EmiG) setzte auf eine TÜV-Zertifizierung, die sich nur große Provider leisten konnten. Sicherheit nur für Unternehmen mit Budget — das ist das Gegenteil von dem, was ich unterstütze.