CloudPandas Logo
← Blog

SPF: Wer darf in deinem Namen sprechen?

··Security·Microsoft 365DMARCExchange

Teil 1 der Serie Mail-Security-Grundlagen.

Eine Frage, eine Antwort

SPF hat zu Unrecht einen schlechten Ruf. Es gilt als fehleranfällig, als kaputt bei Weiterleitungen, als Ding, das nach drei Cloud-Diensten überläuft. Alles davon stimmt. Trotzdem liegt das Problem selten an SPF, sondern daran, dass ihm Aufgaben zugeschrieben werden, für die es nie gebaut wurde.

SPF beantwortet eine einzige Frage: Ist dieser Server berechtigt, Mail im Namen dieser Domain einzuliefern? Das steht so in RFC 7208, und es ist eine bemerkenswert schmale Zuständigkeit. SPF sagt nichts darüber aus, ob eine Nachricht unterwegs verändert wurde. Es sagt nichts über den Absender, den dein Outlook anzeigt. Es sagt nichts darüber, ob die Mail vertrauenswürdig ist. Es autorisiert eine IP-Adresse für einen Domainnamen, und dann ist es fertig.

Wie ein Record gelesen wird

Ein SPF-Record ist ein TXT-Eintrag im DNS. Er hängt direkt an der Domain und beginnt mit v=spf1:

example.com.  IN TXT  "v=spf1 ip4:192.0.2.1 include:_spf.versanddienst.example -all"

In Alltagssprache: Mail von der Adresse 192.0.2.1 ist in Ordnung. Mail, die über den Versanddienst kommt, ist in Ordnung. Alles andere nicht.

Nachgeschlagen wird der Record für die Domain, die der einliefernde Server im SMTP-Dialog als Absender angibt. Das ist nicht zwingend die Domain, die du im Mailclient siehst. Der Empfänger fragt dabei nur diesen einen Namen ab. Einen Rückgriff auf die übergeordnete Domain gibt es nicht, anders als bei DMARC. Jede Domain und Subdomain, die als Absender auftaucht, braucht deshalb ihren eigenen Record.

Der Empfänger arbeitet die Einträge, im RFC Terme genannt, von links nach rechts ab. Sobald einer auf die einliefernde IP passt, steht das Ergebnis fest und die Auswertung endet. Deshalb steht all am Schluss: Es passt auf jede Adresse und legt fest, was mit allen übrigen passiert.

Jeder Mechanismus trägt einen Qualifier, der bestimmt, welches Ergebnis ein Treffer erzeugt. Ohne Angabe gilt +.

  • + ergibt pass: Der Client ist autorisiert.

  • - ergibt fail: Der Client ist ausdrücklich nicht autorisiert.

  • ~ ergibt softfail: Vermutlich nicht autorisiert, aber der Domaininhaber legt sich nicht fest.

  • ? ergibt neutral: Es wird bewusst keine Aussage getroffen.

Dazu kommen drei Ergebnisse, die nicht aus einem Qualifier stammen: none, wenn gar kein Record gefunden wurde, temperror bei einem vorübergehenden DNS-Problem und permerror, wenn der Record nicht korrekt interpretierbar war.

Die beiden schwachen Ergebnisse werden in der Praxis oft verwechselt. neutral ist laut §8.2 exakt wie none zu behandeln; der Unterschied existiert nur zur Information. Und softfail ist ausdrücklich kein Ablehnungsgrund: §8.5 sagt, dass Empfänger eine Nachricht nicht allein aufgrund eines Softfails zurückweisen sollen. Wer ~all publiziert, hat damit keine halbe Durchsetzung. Er hat eine Absichtserklärung ohne Konsequenz.

Entsprechend steht in §2.1 der Umkehrschluss: Wer will, dass Empfänger negative Entscheidungen treffen können, muss einen Record veröffentlichen, der auf -all endet oder auf einen solchen weiterleitet. Andernfalls ist keine belastbare Aussage über fehlende Autorisierung möglich.

Das Zehn-Lookup-Limit

Ein verbreiteter Defekt ist ein Record, der das DNS-Lookup-Limit reißt. Meist trifft es Organisationen, die über die Jahre Microsoft 365, ein CRM, ein Newsletter-Tool, ein Ticketsystem und zwei Marketingdienste eingesammelt haben, jeweils per include.

Die Regel steht in §4.6.4. Die Terme include, a, mx, ptr, exists und der Modifier redirect lösen DNS-Abfragen aus. Implementierungen müssen die Gesamtzahl dieser Terme während einer Auswertung auf zehn begrenzen. Wird das Limit überschritten, ist das Ergebnis permerror. Nicht softfail, nicht neutral, sondern ein Fehler, der laut §2.6.7 das Eingreifen des DNS-Betreibers erfordert.

Das Limit ist global. §4.1 stellt klar, dass es über alle rekursiven Auswertungen hinweg als ein einziger Zähler geführt wird. Ein include, das intern vier weitere Lookups auslöst, verbraucht fünf von zehn, nicht eines.

Bei mx kommt ein Unterlimit hinzu: Die Auswertung eines einzelnen MX-Eintrags darf nicht mehr als zehn Adressabfragen auslösen. ptr steht zwar in der Liste, soll laut §5.5 aber nicht mehr veröffentlicht werden. Verifier müssen es nur noch unterstützen, weil es vereinzelt im Einsatz ist.

Das Limit ist keine Schikane. §11.1 beschreibt, wogegen es schützt: Ein Angreifer, der einen SPF-Record mit vielen Verweisen auf eine fremde Domain veröffentlicht und dann massenhaft Mail verschickt, macht aus jedem prüfenden Empfänger einen Verstärker für einen Angriff auf das Opfer. Wenige Bytes im SMTP-Dialog erzeugen ein Vielfaches an DNS-Verkehr, und die Herkunft des Angriffs bleibt verborgen. Deshalb muss die Grenze niedrig liegen.

Ein verwandtes Limit betrifft Leerabfragen. Terme, deren DNS-Abfrage entweder eine leere Antwort oder NXDOMAIN liefert, heißen void lookups. §4.6.4 empfiehlt, sie auf zwei zu begrenzen, mit permerror als Folge beim Überschreiten. Das ist eine SHOULD-Regel, keine Pflicht, und Implementierungen dürfen den Wert konfigurierbar machen. In der Praxis begegnet einem das bei Records, die noch auf längst abgeschaltete Dienste zeigen.

Die Mechanismen kosten unterschiedlich viel. ip4 und ip6 vergleichen direkt gegen ein Netz und verbrauchen keinen Lookup. a und mx lösen DNS auf. include startet eine komplette Auswertung des fremden Records und übernimmt nur dessen Ergebnis, nicht dessen Terme. Der Name war unglücklich gewählt, und die Spezifikation räumt das in §5.2 selbst ein: Ein -all im eingebundenen Record beendet nicht die übergeordnete Auswertung. §10.1.1 und §10.1.2 leiten daraus eine Rangfolge ab, ip4 und ip6 vor a vor mx. Der administrative Preis ist das Spiegelbild davon. Mit mx ändert sich der Record nie, wenn sich die Mailserver ändern, mit ip4 musst du bei jeder Umnummerierung ran.

Wohin die Lookups gehen

Kaum ein Record reißt das Limit durch einen einzelnen Dienst. Meist addieren sich drei Muster.

Aufgeteilte Includes. Manche Anbieter verteilen ihre Netze auf mehrere Unter-Records, etwa nach IPv4 und IPv6 oder nach Region. Aus einem include im eigenen Record werden dann zwei oder drei Lookups. Im eigenen Record ist das nicht zu sehen.

Transitive Includes. Ein eingebundener Dienst bindet seinerseits die Dienste ein, über die er selbst versendet. Er kostet dann nicht nur Lookups, du autorisierst damit auch Versender, die du nie ausgewählt hast. Wer in deinem Namen sprechen darf, entscheidet in diesem Fall zum Teil dein Dienstleister.

Redundanz. Derselbe Dienst steht direkt im Record und wird zusätzlich über einen anderen Include eingebunden. §4.6.4 zählt jeden ausgewerteten Term, eine Ausnahme für doppelte Einträge gibt es nicht. Der zweite Eintrag kostet einen Lookup und autorisiert nichts Neues.

Aus der Praxis: mx neben Microsoft 365

In M365-Umgebungen begegnet einem oft dieser Record:

v=spf1 mx include:spf.protection.outlook.com -all

Zeigen alle MX-Einträge der Domain auf Exchange Online, ist mx redundant. Die Adressen der MX-Ziele liegen in den Netzen, die spf.protection.outlook.com ohnehin veröffentlicht. mx autorisiert dann nichts zusätzlich, kostet aber mindestens einen der zehn Lookups. Microsoft Learn führt für Domains, die nur über Microsoft 365 versenden, den Record ohne mx. Wer bei neun von zehn steht, gewinnt mit dem Entfernen Luft, ohne etwas zu verlieren.

Prüfen lässt sich das in einer Minute: MX-Ziele auflösen, Adressen gegen die Netze des Includes halten. Die Voraussetzung gilt für alle MX-Einträge, nicht nur für den mit der höchsten Priorität. Steht dort ein Backup-MX oder ein vorgeschaltetes Gateway, autorisiert mx auch dessen Adressen. Ob das Entfernen dann etwas bricht, hängt davon ab, ob dieses System ausgehend sendet.

Lookups regelmäßig prüfen

Aufgeteilte, transitive und redundante Includes haben gemeinsam, dass sie sich ändern können, ohne dass du deinen Record anfasst. Die Lookup-Zahl ist deshalb kein fester Wert. Sie muss regelmäßig geprüft werden, nicht nur bei Änderungen am eigenen Record.

Drei Fehler, die aus der Spezifikation heraus erklärbar sind

Mehrere SPF-Records an einer Domain. Kommt oft bei Migrationen vor: Der alte Record bleibt stehen, der neue kommt dazu. §3.2 verbietet das, und §4.5 beschreibt die Folge. Bleiben nach dem Aussortieren aller Einträge, die nicht mit v=spf1 beginnen, mehr als einer übrig, liefert die Auswertung permerror. Die Domain hat dann nicht zwei Policies, sondern keine.

+all als Feigenblatt. Ein Record, der auf +all endet, autorisiert jeden Server der Welt für deine Domain. Das ist kein SPF, das ist eine Einladung. Es passiert meist, wenn ein Versandproblem unter Zeitdruck gelöst wurde.

Der implizite Abschluss. Ein Record ohne all und ohne redirect endet laut §4.7 mit dem Ergebnis neutral, so als stünde ?all am Schluss. Für die Spezifikation ist das ein gültiger, für den Betreiber ein selten gewollter Zustand. Der RFC empfiehlt deshalb einen expliziten Abschluss, schon um die Fehlersuche zu erleichtern.

Der vierte Punkt ist kein Fehler. Für Namen, über die keine Mail läuft, empfiehlt §10.1.2 als etablierte Praxis einen Record, der nichts autorisiert. Das Beispiel im RFC ist bezeichnenderweise ein Webserver:

www.example.com.  IN TXT  "v=spf1 -all"

Weil SPF nicht vererbt, gilt das für jeden existierenden Namen einzeln. Nicht existierende Namen deckt DMARC über np ab. Wer ein Domainportfolio betreut, hat hier erfahrungsgemäß die meisten unbesetzten Felder.

Die Identität, die niemand sieht

Eine SMTP-Übergabe kennt zwei Absenderangaben, und sie haben nichts miteinander zu tun.

Die erste steht im SMTP-Dialog selbst, im MAIL FROM-Kommando. Sie heißt Envelope-Absender oder Return-Path und dient dem Transport: dorthin gehen Unzustellbarkeitsmeldungen. Ein Endnutzer sieht sie im Normalfall nie.

Die zweite steht im From:-Header der Nachricht. Das ist der Absender, den der Mailclient anzeigt, auf den Menschen reagieren und den ein Angreifer fälschen will.

SPF prüft die erste. §2.4 schreibt die Prüfung der MAIL FROM-Identität verpflichtend vor. Als Prüfgegenstand kommt die From:-Header-Adresse in der Spezifikation nicht vor. Der RFC ist sich dessen bewusst und sagt es in §11.2 deutlich: Eine SPF-autorisierte Mail kann in ihrem Header beliebige andere Identitäten führen, und ein Nutzer, dem der Unterschied nicht auffällt, wiegt sich in falscher Sicherheit.

Das ist keine Schwäche der Implementierung, das ist der Entwurf. SPF autorisiert den Transportweg. Was in der Nachricht steht, liegt außerhalb seiner Zuständigkeit.

Warum SPF bei Weiterleitungen bricht

Wenn eine Mailingliste eine Nachricht weiterverteilt oder eine Adresse automatisch weiterleitet, verlässt die Mail den ursprünglichen Absendeweg. Der RFC nennt solche Zwischenstationen Mediatoren und beschreibt in §10.3, was passiert: SPF bewertet immer die IP des zuletzt sendenden Servers. Das ist dann der Weiterleiter, nicht mehr der Server des Absenders.

Behält der Weiterleiter den ursprünglichen Envelope-Absender bei, prüft der Empfänger den SPF-Record der Absenderdomain gegen die IP des Weiterleiters. Die passt dort nicht, und die Prüfung schlägt fehl. Die Mail ist völlig in Ordnung, das Ergebnis ist trotzdem fail.

Ändert der Weiterleiter den Envelope-Absender auf seine eigene Domain, funktioniert SPF wieder, aber es bestätigt jetzt den Weiterleiter und nicht mehr den Absender. Für den Transport ist das sauber gelöst. Für die Frage, ob der ursprüngliche Absender echt war, ist die Aussage wertlos geworden.

Diese zweite Variante hat einen Namen: Sender Rewriting Scheme, kurz SRS. Der Weiterleiter setzt als Envelope-Absender eine Adresse in seiner eigenen Domain und kodiert darin die ursprüngliche, damit Unzustellbarkeitsmeldungen zum Absender zurückfinden. RFC 7208 beschreibt dieses Vorgehen in Anhang D.2 als mögliche Abhilfe, ohne ein bestimmtes Verfahren vorzuschreiben. SRS ist kein IETF-Standard. Exchange Online wendet es automatisch an, wenn Mail an externe Empfänger weitergeleitet wird (Microsoft Learn), mit einer Ausnahme: Nachrichten, die über den sogenannten Relay-Pool laufen, vor allem solche, die schon beim Eingang an SPF gescheitert sind, werden nicht umgeschrieben.

Für DMARC ändert SRS nichts. Die umgeschriebene Adresse gehört zur Domain des Weiterleiters, und DMARC verlangt, dass die geprüfte Domain zum From:-Header passt. Hat der ursprüngliche Absender kein DKIM, bleibt der weitergeleiteten Nachricht nichts, womit sie DMARC bestehen könnte.

Hier setzt DKIM an: Eine kryptografische Signatur klebt an der Nachricht statt am Transportweg. Sie übersteht einen Zwischenhop, solange niemand die signierten Teile anfasst. Das ist der Gegenstand von Teil 2.

SPF-Pass ist nicht DMARC-Pass

DMARC bewertet die Domain im From:-Header. SPF prüft die Domain im Envelope. Damit ein SPF-Ergebnis für DMARC überhaupt zählt, müssen beide zusammenpassen. Diese Prüfung heißt Identifier Alignment, und sie kennt zwei Modi. Im Standardmodus relaxed genügt es, wenn beide Domains dieselbe Organizational Domain haben. Im Modus strict müssen sie exakt übereinstimmen.

Der praktisch wichtigste Fall sieht so aus: Du verschickst über einen Dienstleister, der bounce@mail.versanddienst.example als Envelope-Absender setzt, während im From: deine eigene Domain steht. Der SPF-Record des Dienstleisters passt, die Prüfung besteht. Für DMARC ist das Ergebnis trotzdem wirkungslos, weil versanddienst.example und deine Domain nicht dieselbe Organisation sind. Der Pass steht im Header, trägt aber nichts bei.

Deshalb ist es irreführend, DMARC-Probleme über SPF lösen zu wollen.

Ein SPF-Pass ohne Alignment ist für DMARC dasselbe wie gar kein SPF.

Wie die Organizational Domain unter DMARCbis ermittelt wird und warum sich das gegenüber der alten Public Suffix List geändert hat, steht in Teil 3 der DMARCbis-Serie.

Was du prüfen kannst, ohne jemanden zu fragen

Der Zustand eines SPF-Records ist öffentlich. Du brauchst keinen Zugang zu einem Tenant, um zu sehen, ob eine Domain mehrere Records hat, wie viele DNS-Lookups die Auswertung kostet oder ob der Record einen definierten Abschluss besitzt. Das alles steht im DNS.

Unser Tool mailaudit löst die Include-Kette einer Domain vollständig auf und zeigt für jeden Term den laufenden Zählstand, auch in verschachtelten Einträgen. Aufgeteilte, transitive und doppelte Includes werden so sichtbar. Was aus dem DNS nicht ablesbar ist, bleibt außen vor. Ob eine Weiterleitungskette in deiner Organisation SPF regelmäßig bricht, zeigt nur die Auswertung deiner DMARC-Reports.


Serie Mail-Security-Grundlagen

  1. SPF: Wer darf in deinem Namen sprechen?

  2. DKIM: Wer hat diese Nachricht unterschrieben?


Quellen

Ähnliche Beiträge