RFC 9989 löst RFC 7489 ab: was sich für DMARC wirklich ändert
Stefan Haun von cyberscale.io hat mir per Mail einen Hinweis geschickt: mein alter Beitrag zu DMARC bezieht sich auf RFC 7489, das seit Mai 2026 durch RFC 9989 abgelöst ist. Der Hinweis kam, so fühlt es sich für mich an, ggf. im Rahmen von Linkbuilding, mit Verweis auf seinen eigenen Guide zu DKIM und DMARC. Das schmälert die fachliche Korrektheit des Hinweises nicht, deshalb hier der ehrliche Dank und der längst überfällige Nachtrag. Mitbekommen hatte ich die neue RFC schon vor einer Weile, geschrieben aber noch nichts, weil es bei einem frischen RFC erstmal eine Zeit braucht, bis sich das in der Praxis herumspricht und Implementierungen nachziehen. Genau dieser Verzug taucht unten beim Praxis-Check nochmal auf.
### Was RFC 9989 überhaupt ist
In der Community läuft das Projekt unter dem Namen DMARCbis. Anders als der Name vermuten lässt, ist daraus keine einzelne neue RFC geworden, sondern drei:
* RFC 9989, die Kernspezifikation: Policy, Alignment, die Tags im Record.
* RFC 9990, die aggregierten Reports, also die täglichen XML-Berichte.
* RFC 9991, die Failure Reports, das ARF-Format pro Nachricht.
Alle drei tragen offiziell „Obsoletes: 7489“ im Kopf, RFC 9989 zusätzlich noch „Obsoletes: 9091“ (der 2021 veröffentlichte, experimentelle Vorläufer, der `np` und die Public-Suffix-Domain-Idee einführte und dessen Inhalt RFC 9989 jetzt vollständig integriert und ersetzt). Dazu ein Reifegrad-Sprung, der eine eigene Erwähnung wert ist: RFC 7489 war „Informational“, RFC 9989 ist „Standards Track“, also auf dem offiziellen Weg zum Internet Standard. DMARC verlässt damit den Status der informellen Beschreibung eines etablierten Verfahrens und wird zu einer echten IETF-Spezifikation.
### Die Tags: drei raus, drei gegenüber RFC 7489 neu
Der eigentliche technische Kern steckt in der Menge der Policy-Tags im Record. Drei Tags sind aus der aktiven Spezifikation gestrichen (in der IANA-Registry stehen sie weiterhin, nur als `historic` markiert), drei sind gegenüber RFC 7489 neu, wobei `np` davon eigentlich ein Wiedersehen ist:
Entfernt (RFC 7489)| Neu gegenüber RFC 7489 (RFC 9989)
---|---
`pct`, Prozent-Rollout der Policy| `t`, expliziter Test-Modus
`rf`, Report-Format, quasi nie genutzt| `np`, Policy für nicht existierende Subdomains, importiert aus RFC 9091
`ri`, Report-Intervall, von Empfängern ignoriert| `psd`, Public-Suffix-Domain-Flag
`rf` und `ri` werden von einem RFC-9989-konformen Empfänger nicht mehr ausgewertet, RFC 9989 selbst nennt für die Streichung keine ausführlichere Begründung als das Fehlen praktischer Relevanz. `pct` ist der interessantere Fall, dazu gleich mehr.
### `t`: der Testmodus, der `pct` ersetzt
`t=n` ist der Default und bedeutet normale Durchsetzung. `t=y` setzt die in `p`, `sp` oder `np` konfigurierte Policy eine Stufe herab: aus `reject` wird `quarantine`, aus `quarantine` wird `none`. Reports laufen dabei unverändert weiter, man sieht also weiterhin, wer durchfallen würde. RFC 9989 selbst nennt `t` ausdrücklich nur einen Ersatz für einen Teil der alten `pct`-Funktionalität, nämlich für die beiden Randwerte: `t=n` und `t=y` sollen sich bei Empfängern und Zwischenstationen analog zu `pct=100` und `pct=0` verhalten, nicht zu jedem beliebigen Prozentwert dazwischen. `pct=0` unter RFC 7489 führte nach Abschnitt 6.6.4 bei `reject` ebenfalls schon zu `quarantine` statt zu gar keiner Reaktion, `t=y` übernimmt diesen einen Spezialfall, nur ohne Prozentrechnung. Für einen echten Teil-Rollout mit Werten zwischen 0 und 100 gibt es dagegen keinen direkten Nachfolger, dazu unten mehr.
### `np`: eine eigene Stufe für nicht existierende Subdomains
Unter RFC 7489 galt für Mail von einer Subdomain, egal ob sie einen eigenen DNS-Eintrag hat oder nicht, immer dieselbe Regel: `sp`, falls gesetzt, sonst `p`. Eine Subdomain, die gar nicht existiert, zum Beispiel `irgendwas.example.com`, wo `irgendwas` nie angelegt wurde, bekam also exakt dieselbe Policy wie eine echte, konfigurierte Subdomain. Genau das ist ein bekanntes Spoofing-Einfallstor, weil sich beliebige, nie existierende Namen fälschen lassen, für die es nie eine eigene Policy gab. `np` schafft jetzt erstmals eine eigene, von `sp` und `p` unterscheidbare Stufe genau für diesen Fall. Neu erfunden ist das Tag dabei nicht: RFC 9989 übernimmt es wörtlich aus dem 2021 veröffentlichten, experimentellen RFC 9091, das mit RFC 9989 ebenfalls obsolet wird, und macht daraus einen festen Bestandteil der Hauptspezifikation. Fehlt `np` weiterhin, fällt die Regel auf `sp` zurück, falls gesetzt, sonst auf `p`, genau wie in RFC 9989 Abschnitt 4.7 definiert. Wer schon vorher ein striktes `sp=reject` gesetzt hatte, bekommt also weiterhin exakt das gleiche Verhalten wie zuvor, nur jetzt mit der Möglichkeit, es bei Bedarf davon zu lösen.
### DNS-Tree-Walk statt Public Suffix List, `psd` markiert die Grenze
Die eigentliche Änderung ist strukturell: RFC 9989 löst die Bestimmung der Organizational Domain von der statischen, extern gepflegten Public Suffix List und ersetzt sie durch einen DNS-Tree-Walk-Algorithmus. `psd` (Werte `y`, `n`, `u`, Default `u`) liefert dafür die expliziten Grenzmarkierungen: `psd=y` setzt ein Public Suffix Operator auf seinem eigenen Record, um zu sagen, dass darunter fremde, eigenständige Organizational Domains beginnen, `psd=n` sagt umgekehrt, dass genau diese Domain die Organizational Domain für sich und ihre Subdomains ist. Relevant ist das vor allem für Registries und Hoster, die selbst öffentlich registrierbare Second-Level-Domains betreiben, also Strukturen wie bei `.co.uk`. RFC 9989 weist ausdrücklich darauf hin, dass Public-Suffix-List-Auflösung und Tree-Walk in Einzelfällen zu unterschiedlichen Ergebnissen kommen können. Für eine gewöhnliche Domain wie diese hier, ohne PSO-Rolle, ändert sich am eigenen Verhalten dadurch nichts.
### Macht das bestehende Records ungültig? Nein, by design, mit einer Ausnahme in beide Richtungen
DMARC trägt seit RFC 7489 die Regel, dass unbekannte Tags ignoriert werden müssen. RFC 9989 übernimmt das wörtlich und baut die ganze Abwärtskompatibilität darauf auf. Ein alter, nur RFC-7489-konformer Validator, der `t` oder `np` nicht kennt, überliest sie einfach und wendet weiterhin `p` und `sp` an. Er stürzt dabei nicht ab und verhält sich nicht falsch, er kennt nur die feinere neue Steuerung noch nicht. Das hat aber eine Kehrseite, die man beim Einsatz von `t=y` kennen sollte: genau derselbe alte Validator ignoriert auch `t=y` und wendet bei `p=reject` weiterhin `reject` in voller Härte an. `t=y` schützt also nur gegenüber Empfängern, die RFC 9989 bereits verstehen, nicht gegenüber alten Implementierungen. Umgekehrt ignoriert ein RFC-9989-konformer Validator ein vorhandenes `pct`, weil das Tag schlicht nicht mehr definiert ist.
Genau an dieser Stelle steckt die Nuance, die wehtun kann: wer noch mit `pct` zwischen 1 und 99 einen echten Teil-Rollout fährt, das klassische schrittweise Hochfahren auf `reject` mit einem Bruchteil der Nachrichten, bekommt bei einem RFC-9989-konformen Empfänger keine reduzierte Durchsetzung mehr. Das Tag wird ignoriert, die volle in `p` konfigurierte Policy greift sofort. Einen direkten Nachfolger für genau diesen Zwischenbereich gibt es nicht, `t` kennt nur an und aus. Wer so einen Teil-Rollout fährt, muss stattdessen auf eine echte Stufenmigration ausweichen, etwa `p=none`, dann `p=quarantine`, dann `p=reject`, mit `t=y` jeweils als zusätzliche Bremse innerhalb einer Stufe. Nur der Randfall `pct=0` hat mit `t=y` einen echten, direkten Ersatz. Für alle anderen gilt: bestehende `v=DMARC1`-Records bleiben syntaktisch gültig, niemand muss etwas ändern, um funktionsfähig zu bleiben. Weitgehend kompatibel ist die richtige Beschreibung, additiv dagegen nicht ganz, weil eben doch drei Tags aus der aktiven Auswertung verschwinden und die Organizational-Domain-Bestimmung sich strukturell ändert.
### Mailinglisten und die p=reject-Warnung
Abschnitt 7.4 rät Domains, deren Nutzer möglicherweise auf öffentlichen Mailinglisten schreiben, ausdrücklich von `p=reject` ab. Der Grund ist alt und in RFC 7960 im Detail beschrieben: Listen-Reflektoren brechen die SPF-Alignment, weil die Mail über einen fremden Server läuft, und selbst DKIM-Signaturen überleben nicht jede Listen-Software unverändert. Der konkrete, im RFC-Text selbst genannte Weg ist eine gestufte Migration: zuerst mindestens einen Monat `p=none`, dann mindestens ebenso lange `p=quarantine`, jeweils mit Auswertung der Reports, bevor überhaupt über `p=reject` nachgedacht wird. `t=y` wird an dieser Stelle im RFC nicht namentlich erwähnt, würde sich als zusätzliche Bremse innerhalb einer Stufe aber inhaltlich genauso eignen wie der frühere `pct`-Ansatz, das ist an dieser Stelle meine eigene Einordnung, keine RFC-Vorgabe. Wichtig zusätzlich, weil es die Wucht von `p=reject` etwas relativiert: RFC 9989 verpflichtet Empfänger, nicht allein aufgrund eines `p=reject` abzulehnen, und schreibt vor, einen DMARC-Fail ohne weitere eigene Erkenntnisse wie `quarantine` zu behandeln.
### RFC 9990: DKIM-Ergebnisse und der Selector werden verbindlicher
In den regelmäßigen, in der Praxis meist täglichen aggregierten XML-Reports war das DKIM-Auth-Ergebnis unter RFC 7489 eher beiläufig spezifiziert. RFC 9990 macht daraus eine klare Pflicht, allerdings nur bedingt: wurde für eine Nachricht überhaupt eine DKIM-Signatur validiert, muss das Ergebnis im Report stehen, eine komplett unsignierte Nachricht braucht weiterhin kein eigenes DKIM-Element. Neu und für die Praxis besonders nützlich ist zusätzlich, dass der verwendete Selector jetzt ebenfalls verpflichtend im Report steht, unter RFC 7489 war er optional. Damit lässt sich aus den Reports direkt ablesen, welcher Selector bei welchem berichtenden Mail-Receiver (nicht) verifiziert, was Diagnosen bei DKIM-Key-Rotationen deutlich erleichtert.
### RFC 9991: Failure Reports und die Datenschutzfrage
Das ARF-Format für die einzelnen Failure Reports ist nicht neu, das nutzte schon RFC 7489. Neu ist, dass RFC 9991 dieses Thema aus der Kernspezifikation herauslöst, in eine eigene RFC packt und dabei ein altbekanntes Problem konkreter adressiert: Failure Reports können personenbezogene Daten enthalten, Empfängeradressen und im schlechtesten Fall Teile des Mail-Inhalts. Genau deshalb liefern nach eigener Beobachtung viele große Empfänger schon seit Jahren kaum bis gar keine `ruf`-Reports aus, RFC 9991 selbst schreibt, dass die Datenschutzbedenken viele Betreiber dazu gebracht haben, den Einsatz von Failure Reports einzuschränken. RFC 9991 bringt jetzt konkrete Redaction-, Datenminimierungs- und Transport-Security-Empfehlungen mit, formuliert als starke Empfehlung, nicht als Pflicht oder Garantie. Ob das in der Praxis tatsächlich mehr Empfänger dazu bringt, `ruf` überhaupt zu bedienen, bleibt abzuwarten, ein Schritt in die richtige Richtung ist es trotzdem.
### Praxis-Check an den eigenen sechs Domains
Live abgefragt mit `dig +short TXT _dmarc.<domain>`, Stand heute:
kernel-error.de: v=DMARC1; p=reject; rua=mailto:postmaster@kernel-error.de; ruf=mailto:postmaster@kernel-error.de; fo=1; sp=reject; aspf=s;
kernel-error.com: (identisch)
kernel-error.org: (identisch)
vandemeer.de: (identisch)
fuchs-meckenheim.de: (identisch)
heidbreders.de: (identisch)
Drei Beobachtungen dazu. Erstens: `pct=100` stand ursprünglich noch auf allen sechs Records, ein Überbleibsel aus der Zeit vor dem eigentlich gewünschten vollen Rollout, dazu weder `rf` noch `ri`. Weil überall ohnehin die volle Durchsetzung gewollt war und kein Teil-Rollout lief, war die neue Bedeutungslosigkeit von `pct` genau der Anlass, das Tag von allen sechs Records ersatzlos zu streichen, kein Muss, aber ein guter Moment dafür.
Zweitens: `heidbreders.de` stand bislang als einzige der sechs Domains auf `sp=none`, die anderen fünf auf `sp=reject`. Beim Aufräumen gleich vereinheitlicht, jetzt tragen alle sechs `sp=reject`. `np` explizit zu setzen würde am eigenen Verhalten trotzdem nichts ändern, weil der Default, der Rückfall auf `sp`, für alle sechs Domains ohnehin schon `reject` ist. Es besteht kein Handlungsbedarf, ein expliziterer Record wäre höchstens Geschmackssache.
Drittens, und das ist der Punkt, der zur eingangs erwähnten Adoptionsverzögerung passt: rspamd, hier in Version 4.1.0 der eigene DMARC-Validator für eingehende Mail, unterstützt `np` nach aktuellem Stand von September 2026 noch nicht. Bekommt der eigene Filter eine gespoofte Mail von einer nicht existierenden Subdomain einer fremden Marke, deren Domain-Owner über `np` strenger sein wollte als über `sp`, wendet rspamd aktuell trotzdem die laxere `sp`-Policy an. Eine kleine, aber reale Lücke auf der Empfänger-Seite, bis rspamd nachzieht. Vier Monate nach Publikation der RFC haben ohnehin die wenigsten Absender-Domains `np` überhaupt gesetzt, akuten Grund zur Sorge gibt das nicht, einen Blick in die rspamd-Release-Notes aber schon.
Die Frage aus Abschnitt 7.4 ist dabei nicht, ob ich selbst eine Mailingliste betreibe, sondern ob Absender meiner Domains an fremden Mailinglisten oder ähnlichen indirekten Mail-Flows teilnehmen. Bei mir ist das praktisch nicht der Fall, für die eigene Infrastruktur bleibt die gestufte Migration also Theorie. Für Leser mit Nutzern, die auf Mailinglisten schreiben, ist sie es sehr wohl.
> **Kurzfassung:** Kein akuter Handlungsbedarf für Domains mit bestehendem `p=reject` und `pct=100`. Wer noch einen Teil-Rollout mit einem `pct`-Wert zwischen 1 und 99 fährt, findet in `t` keinen direkten Ersatz und muss auf eine echte Stufenmigration über `p` ausweichen, nur der Randfall `pct=0` lässt sich eins zu eins durch `t=y` ersetzen. `np` ist ein sinnvolles Sicherheits-Add-on, dessen Wirkung von der Update-Geschwindigkeit der empfängerseitigen Implementierungen abhängt, ein gutes Beispiel dafür, dass ein neues RFC nicht am Tag der Veröffentlichung live ist, sondern über Monate und Jahre durch Software-Updates bei allen Beteiligten durchsickert.
### Siehe auch
* DMARC einrichten: Policy, Alignment und Reporting für deine Domain, der ursprüngliche Beitrag zu RFC 7489, weiterhin als historisches Dokument korrekt.
* SPF-Record einrichten, die Grundlage, auf der auch DMARC aufbaut.
* DKIM einrichten mit rspamd und Postfix, die zweite Grundlage.
Eigene Erfahrungen mit der Umstellung auf RFC 9989, oder Fragen zu DMARC allgemein? Dann darfst du mich sehr gerne fragen.