Domain-based Authentifizerung für Emails mit SPF, DKIM und DMARC
Vorwort:
Als Admininstrator von Servern stößt man immer wieder auf die Schlagwörter SPF, DKIM, DMARC. Da ich mich nun aufgrund eines aktuellen Projekts ebenfalls mit Email Versand und nicht-als-spam-markiert-werden beschäftigt habe möchte ich hier eine kleine Erklärung und Anleitung zu diesem Thema bereitstellen.
Die Beispielkonfiguration in diesem Artiel verwendet debian Linux mit postfix und opendkim und bind als DNS Server.
Was ist SPF, DKIM, DMARC
Zuerst einmal zur Begriffserklärung:
SPF = Sender Policy Framework – http://en.wikipedia.org/wiki/Sender_Policy_Framework
DKIM = Domain Key Identified Mail – http://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
DMARC = Domain-based Message Authentication, Reporting and Conformance – http://en.wikipedia.org/wiki/DMARC
Wozu?
Alle 3 Methoden helfen, dass die Gegenstelle (Mailempfänger) überprüfen kann ob der Absender (Server) der Email authorisiert ist, Emails unter dieser Domain zu versenden.
Was braucht man dazu und wie funktionierts?
-
opendkim (=milter für Postfix)
-
dns TXT Records
Wird eine Email verschickt hängt der opendkim Dämon (ACHTUNG: nicht mehr dkim-filter verwenden, wird nicht mehr weiterentwickelt) an jede ausgehende Email einen Key an. D.h. er signiert jede Email einer Domain für die er authorisiert ist mit dem hinterlegten Schlüssel.
Dieser Key wird dann vom Empfänger überprüft indem er den entsprechenden DKIM TXT Record (mail._domainkey.domain.tld. IN TXT “v=DKIM1; …”) aus dem DNS abruft und die Signatur prüft.
Zusätzlich kann der Empfänger auch prüfen ob der Versenderserver vom Domaininhaber authorisiert wurde, Emails für diese Domain zu versenden. Dies geschieht indem er den SPF TXT Record (domain.tld. IN TXT “v=spf1 ….”) überprüft. Dort ist z.B. hinterlegt, welcher Mailserver mit welchen Hostnamen und welchen IP Adressen Mails verschicken darf.
Zuletzt kann der Empfänger über den DMARC TXT Record (_dmarc.domain.tld. IN TXT “v=DMARC1; …”) eine Regel einholen, wie er denn mit den Emails verfahren soll, die die Prüfung nicht bestanden haben (z.B. von einem Host geschickt, der im SPF Record nicht erlaubt ist oder die DKIM Signatur nicht überprüft werden konnte).
ran ans Eingemachte – die Konfiguration
Um die zusammengehörigen Konfigurationseinstellungen besser ersichtlich zu machen wurden einzelne zusammengehörige Teile farblich markiert. z.B. die Domain, der Selektor, usw. …
Konfiguration opendkim Daemon
Wie bereits beschrieben sind die Rahmenbedingungen eine funktionierende postfix Installation und voller Zugriff auf die DNS Einträge einer Domain (zum Anlegen von TXT Records).
Installation des opendkim Pakets (debian):
root@shmail:/etc# apt-get install opendkim
Nun muss für den opendkim Daemon und für Postfix noch die Schnittstelle konfiguriert werden, über die beide miteinander kommunizieren. Dies geschieht im /etc/default/opendkim Konfigurationsfile:
root@shmail:/etc/default# cat opendkim # 20141108 leo.eibler add listener SOCKET="inet:8891@localhost" # listen on loopback on port 8891
In diesem Beispiel hört der opendkim Daemon auf den localhost Socket Port 8891.
Dazu passend muss nun postfix im Konfigurationsfile /etc/postfix/main.cf konfiguriert werden:
root@shmail:/etc/postfix# cat main.cf ... # 20141108 leo.eibler add DKIM support milter_default_action = accept milter_protocol = 2 smtpd_milters = inet:localhost:8891 non_smtpd_milters = inet:localhost:8891
Die Konfigurationsdatei des opendkim Pakets selbst liegt in /etc/opendkim.conf . Hier sind nun einige Anpassungen durchzuführen:
root@shmail:/etc# cat opendkim.conf # Log to syslog Syslog yes SyslogSuccess yes LogWhy yes # Required to use local socket with MTAs that access the socket as a non-privileged user (e.g. Postfix) UMask 002 # 20141109 leo.eibler this is a multidomain setup (use different keys for different domains) # run command for each domain to generate keys: # cd /etc/mail # opendkim-genkey -r -s mail -d otherdomain.com # mv mail.private otherdomain.com.dkim.private # mv mail.txt otherdomain.com.dkim.txt # chmod ugo+r otherdomain.com.dkim.* # /etc/init.d/opendkim restart # add TXT record to dns from file otherdomain.com.dkim.txt # append domain to these 2 files: KeyTable /etc/mail/DkimKeyTable SigningTable refile:/etc/mail/DkimSigningTable
Nach der Konfiguration des opendkim Pakets müssen die entsprechenden Signatur Einträge für die jeweilige Domain erzeugt werden. Hierzu gibt es das opendkim-genkey tool, welches im opendkim Paket mitinstalliert wird:
root@shmail:/etc/mail# opendkim-genkey -r -s mail -d domain.tld
Nach der Ausführung des Kommandos finden sich 2 neue Dateien im Verzeichnis /etc/mail:
-
mail.private = enthält den Schlüssel mit dem die versendete Email vom opendkim/postfix Gespann signiert wird
-
mail.txt = enthält den TXT DNS record mit der Signatur, die vom Empfänger geprüft werden kann
Nun muss opendkim noch mitgeteilt werden, wie es die Keys findet. Der erste Schritt dazu ist die SigningTable Datei. Sie enthält das Mapping von Versender Adresse (FROM: ….@domain.tld) zu Keyfile das für die Signatur verwendet wird:
root@shmail:/etc/mail# cat /etc/mail/DkimSigningTable # format: # $pattern $keyname *@domain.tld domain.tld *@otherdomain.tld otherdomain.tld
Der Einfachheit halber wird der keyname gleich wie der Domainname gewählt. Hier könnte man z.B. auch 2 Domains mit dem selben Key signieren, indem der gleiche keyname verwendet wird.
Die zweite Konfigurationsdatei KeyTable enthält mehrere Komponenten:
-
den Verweis auf die Datei mit der Signatur (die Datei mail.private mit opendkim-genkey erstellt wurde):
-
die Domain für die signiert wird
-
den Selektor der vom Empfänger in der DNS Abfrage verwendet wird um die Signatur zu überprüfen
root@shmail:/etc/mail# cat /etc/mail/DkimKeyTable # format: # $keyname $domain:$selector:$keypath domain.tld domain.tld:mail:/etc/mail/domain.tld.dkim.private otherdomain.tld otherdomain.tld:mail:/etc/mail/otherdomain.tld.dkim.private
Nach Abschluss der Konfiguration (oder hinzufügen einer Domain) muss der opendkim Daemon neu gestartet werden:
root@shmail:/etc# /etc/init.d/opendkim restart
Häufige Fehler:
-
Die Signaturdatei kann aufgrund der Dateirechte von opendkim nicht gelesen werden (chmod ugo+r … oder chown postfix …)
-
opendkim wurde nicht neugestartet: /etc/init.d/opendkim restart
-
postfix wurde nicht neugestartet: /etc/init.d/postfix restart
Konfiguration DNS Records
Nach der Konfiguration des opendkim Daemons wird nun jede Email von Postfix entsprechend um eine DKIM Signatur ergänzt. Nun fehlen die DNS Einträge, mit denen der Empfänger nun den Versender überprüfen kann.
DNS: Sender Policy Framework (SPF)
Hierzu ist im DNS Zone Record (in diesem Beispiel bind) ein entsprechender TXT Record für die Domain einzurichten:
; TXT records for SPF domain.tld. IN TXT ( "v=spf1 mx a ip4:10.1.1.40/29 ip4:192.168.0.64/29 " "a:www.domain.tld a:subdomain.domain.tld " "include:mail.hoster.tld" )
Was bedeuten diese Angaben im SPF Record?
-
Der TXT record wird durch die Angabe v=spf1 als SPF Version 1 Record identifiziert
-
mx und a bedeuten, dass der in den MX Records eingetragene Mailserver und die Domain selbst berechtigt ist Emails zu versenden
-
Die beiden ip4:…. Einträge bedeuten, dass Server mit einer IP Adresse in den angegebenen Subnetzen berechtigt sind, Emails für diese Domain zu versenden. Es können durch Hinzufügen mehrerer ip4 Abschnitte mehrere IP Nutze angegeben werden (in diesem Beispiel 2). Hier müssen z.B. die IP Adressen der Mailrelays des Hosters eingetragen werden
-
Die a:<subdomain>.domain.tld Einträge erlauben das Versenden von Mails von den angegebenen Subdomains. Auch hier sind mehrere Einträge für mehrere Subdomains erlaubt
-
Die include:<andere Domain> Einträge fügen weitere Domains bzw. Hosts hinzu, denen es erlaubt ist, Emails zu versenden. Hier wird z.B. das Mailrelay des Hosters eingetragen. Auch hier sind mehrere Einträge für mehrere andere Domains erlaubt
Häufige Fehler:
-
Der Punkt nach dem Domainnamen fehlt: domain<PUNKT>tld<PUNKT> IN TXT ”….”
-
Der TXT Record ist zu lange. Hier in diesem Beispiel wurde der TXT Record auf mehrere Zeilen aufgetrennt. Die Syntax hierfür lautet: Klammer auf ( danach in Anführungszeichen “erster Teil<Leerzeichen>” danach nächste Zeile in Anführungszeichen “zweiter Teil” usw. und abschließend Klammer zu ). Wichtig hierbei: Die Leerzeichen innerhalb der einzelnen in Anführungszeichen eingeschlossenen Abschnitte nicht vergessen: “erster Teil” “zweiter Teil” wird sonst zu “erster Teilzweiter Teil” zusammengesetzt.
-
Die Serial Number des Zone Records wurde nicht erhöht
-
Die Ablaufzeit des Zone Records ist sehr hoch gesetzt und die anderen Server haben die Änderungen noch nicht mitbekommen
DNS: Domain Key Identified Mail (DKIM)
Für das DKIM Signatur Verfahren sind ebenfalls im DNS Zone Record (in diesem Beispiel bind) ein entsprechender TXT Record für die Domain einzurichten:
mail._domainkey.domain.tld. IN TXT ( "v=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvkDET02OqKcvgkpSxRvGMVzqwj5fxNFcuLWhLCcMsdx7hxlquRppBjbirvEV0HgRHS/za+KKp45edd4qBeChASEbJJ2NpNGIyL+Jy0jmpCK1E5AZKopjSLnSMo78lkaZDj/t5XRqj0qhnldUgtOGj6M8PHvN7AH9UBpXxhXAe1QIDAQAB" )
Nun ist der Selektor “mail” wichtig, der in der opendkim Konfiguration angegeben wurde:
-
siehe opendkim-genkey -r -s mail -d domain.tld Aufruf mit -s mail = Selektor “mail”
-
siehe Konfigurationsdatei KeyTable mit domain.tld domain.tld:mail:/etc/mail/domain.tld.dkim.private = Selektor :mail:
Der TXT Record wird also mit mail._domainkey.domain.tld. angelegt.
Was bedeuten diese Angaben im DKIM Record?
-
Der TXT record wird durch die Angabe v=DKIM1 als DKIM Version 1 Record identifiziert
-
Das Verschlüsselungsverfahren RSA wird mit k=rsa festgelegt
-
Der Schlüssel zum Überprüfen wird mit p=<key> festgelegt. Dies ist der Schlüssel der durch opendkim-genkey in der mail.txt Datei erzeugt wurde
Häufige Fehler:
-
Der Punkt nach dem Domainnamen fehlt: mail<PUNKT>_domainkey<PUNKT>domain<PUNKT>tld<PUNKT> IN TXT ”….”
-
Der Selektor (hier im Beispiel mail) ist falsch bzw. stimmt nicht mit der opendkim Konfiguration überein
-
Serial Number oder Caching des Zone Records
DNS: Domain-based Message Authentication, Reporting and Conformance (DMARC) Richtlinie
Die DMARC Richtlinie sagt dem Empfänger, wie er denn mit einer Email die nicht die Prüfungen für SPF und/oder DKIM bestanden hat umzugehen hat.
Die DMARC Richtlinie wird ebenfalls im DNS Zone Record (in diesem Beispiel bind) über einen entsprechenden TXT Record für die Domain veröffentlicht:
_dmarc.domain.tld. IN TXT “v=DMARC1; p=quarantine; rua=mailto:postmaster@domain.tld”
Der TXT Record wird also mit _dmarc.domain.tld. angelegt.
Was bedeuten diese Angaben in der DMARC Richtlinie?
-
Der TXT record wird durch die Angabe v=DMARC1 als DMARC Version 1 Record identifiziert
-
Die Angabe p=quarantine bedeutet, dass eine Email die nicht die Prüfungen besteht entsprechend markiert (z.B. als Spam) werden soll. Weitere Alternativen hierzu wären p=none – dies wird als TEST Mode bezeichnet (der Empfänger prüft zwar ignoriert aber das Ergebnis und behandelt die Domain wie wenn keine SPF und DKIM Records existieren würden). Die härteste Variante ist mit p=reject anzugeben – Emails werden bei fehlerhafter Überprüfung abgewiesen
-
An die im optionalen Parameter rua=<Email-Adresse> angegebene Email Adresse wird täglich ein XML Report versendet mit einer Zusammenfassung über die fehlerhaften Emails die beim Empfänger eingelangt sind
Weitere Parameter und Angaben finden sich auf der DMARC Webseite: http://www.dmarc.org
Häufige Fehler:
-
Der Punkt nach dem Domainnamen fehlt: _dmarc<PUNKT>domain<PUNKT>tld<PUNKT> IN TXT ”….”
-
Es ist der Test Modus aktiv p=none
-
Serial Number oder Caching des Zone Records
Testen der Einrichtung
Testen der DNS Konfiguration
Zuerst kann die DNS Einrichtung der TXT Records z.B. mit dig oder nslookup überprüft werden (alle Ausgaben gekürzt).
Überprüfen des DNS Servers ns1.hoster.tld auf dem die TXT Records für die Domain angelegt wurden – SPF:
root@soyuz:~# dig @ns1.hoster.tld. TXT domain.tld ; <<>> DiG 9.7.3 <<>> @ns1.hoster.tld. TXT domain.tld domain.tld. 21600 IN TXT "v=spf1 mx a ip4:10.1.1.40/29 ip4:192.168.0.64/29 a:www.domain.tld a:subdomain.domain.tld include:mail.hoster.tld"
Man sieht hier schön, dass die einzelnen Teile in Anführungszeichen zusammengefügt wurden und als ein ganzer Block ausgegeben werden. Hier kann man nun kontrollieren ob man z.B. ein Leerzeichen in einem Block vergessen hat.
Überprüfen des DNS Servers ns1.hoster.tld auf dem die TXT Records für die Domain angelegt wurden – DKIM:
root@soyuz:~# dig @ns1.hoster.tld. TXT mail._domainkey.domain.tld ; <<>> DiG 9.7.3 <<>> @ns1.hoster.tld. TXT mail._domainkey.domain.tld mail._domainkey.domain.tld. 21600 IN TXT "v=DKIM1\; g=*\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvkDET02OqKcvgkpSxRvGMVzqwj5fxNFcuLWhLCcMsdx7hxlquRppBjbirvEV0HgRHS/za+KKp45edd4qBeChASEbJJ2NpNGIyL+Jy0jmpCK1E5AZKopjSLnSMo78lkaZDj/t5XRqj0qhnldUgtOGj6M8PHvN7AH9UBpXxhXAe1QIDAQAB"
Überprüfen des DNS Servers ns1.hoster.tld auf dem die TXT Records für die Domain angelegt wurden – DMARC:
root@soyuz:~# dig @ns1.hoster.tld. TXT _dmarc.domain.tld ; <<>> DiG 9.7.3 <<>> @ns1.hoster.tld. TXT _dmarc.domain.tld _dmarc.domain.tld. 21600 IN TXT "v=DMARC1\; p=quarantine\; rua=mailto:postmaster@domain.tld"
Testen der Mail Konfiguration
Verschicken einer Email von der jeweiligen Domain an einen Test Service wie z.B. check-auth@verifier.port25.com
root@test:~# echo "Dies ist ein Test" | mail -s "test email" check-auth@verifier.port25.com -- -f postmaster@domain.tld
Nun sollte auf der Absender Email Adresse postmaster@domain.tld eine Antwort eintreffen die hoffentlich so aussieht:
... ========================================================== Summary of Results ========================================================== SPF check: pass DomainKeys check: neutral DKIM check: pass DKIM check: pass Sender-ID check: pass SpamAssassin check: ham ...
Falls bei SPF, DKIM und Sender-ID jeweils pass steht funktioniert die Konfiguration.
Eine Prüfung ist auch einfach mittels gmail möglich.
Hat alles geklappt zeigt gmail Signiert durch: domain.tld
Gratulation!
Über den Autor
Ing. Leo Eibler ist hauptberuflich im Bereich Beratung und IT Service Management tätig. Neben seiner beruflichen Tätigkeit entwickelt er Webapplikationen und kümmert sich auf freiwilliger Basis um den Betrieb von diversen Servern.
Schreibe einen Kommentar