
DMARC-Report lesen: rua-Berichte auswerten ohne Bezahl-Tool
<feedback xmlns="urn:ietf:params:xml:ns:dmarc-2.0">
<report_metadata>
<org_name>empfaenger.example</org_name>
<email>dmarc-reports@empfaenger.example</email>
<report_id>20261016.beispiel.at</report_id>
<date_range><begin>1792108800</begin><end>1792195199</end></date_range>
</report_metadata>
<policy_published>
<domain>beispiel.at</domain>
<adkim>r</adkim><aspf>r</aspf><p>none</p>
</policy_published>
<record>
<row>
<source_ip>198.51.100.7</source_ip>
<count>312</count>
<policy_evaluated>
<disposition>none</disposition><dkim>fail</dkim><spf>fail</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>beispiel.at</header_from>
<envelope_from>bounce.versanddienst.example</envelope_from>
</identifiers>
<auth_results>
<dkim><domain>versanddienst.example</domain><selector>s1</selector><result>pass</result></dkim>
<spf><domain>bounce.versanddienst.example</domain><scope>mfrom</scope><result>pass</result></spf>
</auth_results>
</record>
</feedback>
So ist ein DMARC-Sammelbericht aufgebaut, hier ein Beispiel nach dem Schema aus RFC 9990, gekürzt auf einen einzigen Datensatz, mit einer IP-Adresse aus dem Dokumentationsbereich und Beispieldomains. Er sagt: Am 16.10.2026 hat der Empfänger empfaenger.example 312 Mails mit beispiel.at im Absender von der Adresse 198.51.100.7 bekommen. DKIM und SPF haben beide bestanden, aber für versanddienst.example. Für DMARC hat deshalb keines gezählt, und weil die Richtlinie auf none steht, wurden die Mails trotzdem zugestellt.
Ein Bericht beantwortet eine einzige Frage: Wer verschickt Mails in deinem Namen, und bestehen sie? Er enthält keine Betreffzeilen, keine Empfänger und keinen Inhalt, nur Absender-IP, Anzahl und Prüfergebnisse. Mehr braucht man nicht, um jeden Versandweg zu finden, bevor die Richtlinie strenger wird. Den Eintrag mit Berichtsadresse anzulegen, beschreibt DMARC einrichten, dort steht auch die Kurzfassung des Lesens. Hier geht es um die Auswertung im Alltag.
Wie die Berichte ankommen#
Die Berichtsadresse steht im DMARC-Eintrag als rua:
_dmarc.beispiel.at TXT "v=DMARC1; p=none; rua=mailto:dmarc@beispiel.at"
Mehrere Adressen gehen durch Komma getrennt, jede mit eigenem mailto:. Ein Zusatz wie !10m hinter der Adresse begrenzt die Größe eines Berichts. Dann schicken die großen Empfänger täglich eine Mail. Google schreibt, dass es je nach Versandmenge Hunderte oder Tausende Berichte am Tag werden können, und empfiehlt dafür ein eigenes Postfach oder einen spezialisierten Dienst.
Jede Berichtsmail trägt die XML-Datei als Anhang, laut RFC 9990 mit GZIP gepackt. In der Praxis kommen auch ZIP-Dateien, Werkzeuge wie parsedmarc lesen beides. Der Dateiname folgt einem festen Muster:
empfaenger.example!beispiel.at!1792108800!1792195199.xml.gz
Empfänger, berichtete Domain, Beginn und Ende des Zeitraums in Sekunden seit 1970, UTC. Der Betreff lautet nach RFC 9990 sinngemäß Report Domain: beispiel.at Submitter: empfaenger.example Report-ID: …. Damit lassen sich Berichte im Postfach filtern, bevor man einen öffnet.
Wichtig bei fremden Adressen: Zeigt rua auf eine andere Domain, etwa einen Dienstleister, darf ein Empfänger laut RFC 9990, Abschnitt 4, dorthin nur berichten, wenn die Zieldomain zustimmt. Das tut sie mit einem TXT-Eintrag:
beispiel.at._report._dmarc.dienstleister.example TXT "v=DMARC1"
Fehlt er, gehen die Berichte nicht raus, und niemand bekommt eine Fehlermeldung. Dienstleister setzen den Eintrag für ihre Kunden selbst. Wer Berichte an eine eigene zweite Domain schicken lässt, muss ihn selbst anlegen.
Der Bericht Feld für Feld#
| Element | Bedeutung | Worauf achten |
|---|---|---|
report_metadata/org_name | wer berichtet, etwa google.com | Ein Bericht je Empfänger und Tag |
date_range | Zeitraum, Sekunden seit 1970, UTC | meist 24 Stunden |
policy_published | dein DMARC-Eintrag, wie der Empfänger ihn gelesen hat | Steht hier etwas anderes als gedacht, liest der Empfänger einen anderen Eintrag |
row/source_ip | IP-Adresse, von der die Mails kamen | der Schlüssel für die Zuordnung |
row/count | Anzahl Mails von dieser Adresse mit diesem Ergebnis | |
policy_evaluated/dkim, /spf | Ergebnis für DMARC: pass nur, wenn bestanden und zur Absenderdomain passend | das, was zählt |
policy_evaluated/disposition | was der Empfänger getan hat: none, quarantine, reject | bei p=none immer none |
policy_evaluated/reason | Grund, wenn der Empfänger von der Richtlinie abgewichen ist | etwa forwarded oder mailing_list |
identifiers/header_from | die Domain im sichtbaren From: | sollte deine sein |
identifiers/envelope_from | die Umschlagadresse | bei Versanddiensten oft deren Domain |
auth_results/dkim | jede gefundene Signatur mit domain, selector, result | für welche Domain signiert wurde |
auth_results/spf | SPF-Prüfung mit domain und result | für welche Domain SPF geprüft wurde |
Der häufigste Lesefehler steckt zwischen den beiden markierten Zeilen. auth_results zeigt die rohen Prüfungen, policy_evaluated das Urteil nach dem Abgleich mit dem Absender. Ein pass unten und ein fail oben ist kein Widerspruch, sondern genau der Fall aus dmarc=fail trotz SPF und DKIM pass.

Jede Quelle einem Versandweg zuordnen#
Ein Bericht nennt IP-Adressen, keine Namen. Die Zuordnung ist die eigentliche Arbeit, und sie folgt immer demselben Muster:
- Liste der eigenen Versandwege aufschreiben, bevor man den ersten Bericht öffnet: Postfächer, Website-Formulare, Newsletter, Shop, Rechnungsprogramm, Buchungssystem, Drucker mit Mailfunktion.
- Für jede unbekannte Adresse den Rückwärts-Eintrag abfragen.
dig +short -x 198.51.100.7liefert meist einen Namen, der den Betreiber verrät, etwa einen Versanddienst oder den eigenen Hoster. Fehlt der Name, hilft eine Whois-Abfrage der Adresse. - Die Adresse einordnen, in eine von vier Gruppen:
| Gruppe | Bild im Bericht | Was zu tun ist |
|---|---|---|
| eigener Weg, besteht | policy_evaluated mindestens einmal pass | nichts |
| eigener Weg, besteht nicht | fail oben, pass für fremde Domain unten | beim Dienst eigene Absenderdomain mit DKIM einrichten |
| Weiterleitung oder Liste | Adresse eines Mail-Anbieters oder einer Universität, DKIM pass für deine Domain, SPF fail | meist nichts, DKIM trägt |
| fremd | unbekannte Adresse, kein pass für deine Domain, oft wenige Mails | genau das, was quarantine und reject abfangen sollen |
Erst wenn die zweite Gruppe leer ist, ist der Zeitpunkt für eine strengere Richtlinie gekommen. Woran man ihn sonst noch erkennt, steht in DMARC-Policy: none, quarantine oder reject.
Ohne Bezahl-Tool auswerten#
Für eine kleine Domain reichen ein paar Berichte pro Woche und eines von drei Werkzeugen.
Einen einzelnen Bericht lesbar machen. Auf Linux und macOS:
gunzip -c 'empfaenger.example!beispiel.at!1792108800!1792195199.xml.gz' | xmllint --format -
Viele Berichte als Tabelle. Das folgende Skript braucht nur Python, liest .xml, .xml.gz und .zip und gibt je Datensatz eine Zeile aus. Weil jeder eine Mail an die rua-Adresse schicken kann, ist ein Bericht eine fremde Datei: Ist defusedxml installiert, liest das Skript damit, und es liest höchstens 50 MB je Bericht. Getestet mit dem Beispielbericht oben:
#!/usr/bin/env python3
"""DMARC-Sammelberichte als Tabelle: python3 dmarc_lesen.py *.xml.gz *.zip"""
import gzip, sys, zipfile
try:
from defusedxml import ElementTree as ET # pip install defusedxml
except ImportError:
import xml.etree.ElementTree as ET
GRENZE = 50_000_000 # Bytes je Bericht, gegen gepackte Riesendateien
def lesen(pfad):
if pfad.endswith(".gz"):
return [gzip.open(pfad).read(GRENZE)]
if pfad.endswith(".zip"):
with zipfile.ZipFile(pfad) as z:
return [z.open(n).read(GRENZE) for n in z.namelist() if n.endswith(".xml")]
return [open(pfad, "rb").read(GRENZE)]
def t(el, pfad):
x = el.find(pfad)
return x.text.strip() if x is not None and x.text else "-"
for pfad in sys.argv[1:]:
for roh in lesen(pfad):
wurzel = ET.fromstring(roh)
for el in wurzel.iter(): # Namensraum entfernen
el.tag = el.tag.split("}")[-1]
print("#", t(wurzel, "report_metadata/org_name"), "p=" + t(wurzel, "policy_published/p"))
for r in wurzel.findall("record"):
dk = ",".join(t(d, "domain") + ":" + t(d, "result") for d in r.findall("auth_results/dkim")) or "-"
sp = ",".join(t(s, "domain") + ":" + t(s, "result") for s in r.findall("auth_results/spf")) or "-"
print(t(r, "row/source_ip"), t(r, "row/count"),
"dkim=" + t(r, "row/policy_evaluated/dkim"), "spf=" + t(r, "row/policy_evaluated/spf"),
t(r, "row/policy_evaluated/disposition"), dk, sp)
Für den Beispielbericht gibt es diese Zeile aus:
# empfaenger.example p=none
198.51.100.7 312 dkim=fail spf=fail none versanddienst.example:pass bounce.versanddienst.example:pass
Laufend und mit Oberfläche: parsedmarc. Ein freies Python-Werkzeug unter Apache-2.0-Lizenz, das Sammel- und Fehlerberichte und auch die TLS-Berichte aus MTA-STS und TLS-RPT liest, gepackt oder nicht, direkt aus Dateien oder aus einem IMAP-Postfach:
pip install parsedmarc
parsedmarc -o auswertung/ berichte/*.xml.gz berichte/*.zip
Im Ordner auswertung/ liegen danach JSON- und CSV-Dateien, die jede Tabellenkalkulation öffnet. Wer täglich viele Berichte bekommt, kann parsedmarc an Elasticsearch, OpenSearch oder Grafana hängen und hat eine eigene Übersicht ohne Abo.
Messung: Wer in Tirol Berichte bekommen kann#
In eigener Sache: Am 05.10.2026 um 08:12 UTC habe ich die DMARC-Einträge derselben 149 Tiroler Domains wie in meinen bisherigen Messungen abgefragt, 34 Tourismusverbände und 115 Betriebe aus meiner Akquise-Liste, und für jede Berichtsadresse auf einer fremden Domain nachgesehen, ob dort die Freigabe nach RFC 9990 steht. Passiv per DNS-over-HTTPS bei Cloudflare, die beiden fehlenden Freigaben mit Google Public DNS gegengeprüft. Drei Domains gibt es nicht mehr, bleiben 146.
- 79 Domains haben einen gültigen DMARC-Eintrag, 30 davon eine Berichtsadresse. 49 haben einen Eintrag, bekommen aber keine Berichte. Sie können nie belegen, dass alle ihre Versandwege bestehen.
- 16 schicken die Berichte an eine fremde Domain, an 13 verschiedene Dienstleister und Anbieter, 16 an die eigene. Zwei Domains schicken an beide.
- Bei 2 der fremden Ziele fehlt die Freigabe. Empfänger, die sich an RFC 9990 halten, schicken dorthin nichts. Die Dienste, die auf DMARC-Berichte spezialisiert sind, hatten alle ihre Freigabe gesetzt. Die Betreiber der beiden Domains sehen einen sauberen Eintrag und warten auf Berichte, die nicht kommen.
- 1 Eintrag nennt zwei Adressen, die zweite ohne
mailto:. Sie ist damit keine gültige Adresse. - 13 Domains haben zusätzlich
ruf=für Fehlerberichte zu einzelnen Mails gesetzt. Für die Auswertung, um die es hier geht, sind die Sammelberichte entscheidend.
Namen veröffentliche ich nicht. Ob die eigene Domain einen DMARC-Eintrag mit rua hat, zeigt der E-Mail-Check, einen neuen erzeugt der DMARC-Generator.
Was nicht hilft#
Berichte an das normale Postfach schicken lassen. Nach einer Woche sind es Dutzende Anhänge zwischen Kundenmails, nach einem Monat liest sie niemand mehr.
Nur auf die Summe pass und fail schauen. Eine Prozentzahl sagt nicht, welcher Versandweg scheitert. Die Zuordnung je IP-Adresse ist die Arbeit, die den Unterschied macht.
Jede fremde IP-Adresse für einen Angriff halten. Weiterleitungen und Mailinglisten sehen im Bericht aus wie Fremde, bestehen aber meist DKIM.
Den Bericht eines einzigen Tages als Grundlage für reject nehmen. Versandwege, die einmal im Monat laufen, Rechnungen, Mahnungen, Newsletter, fehlen darin.
Eine Berichtsadresse auf einer fremden Domain ohne Freigabe. Siehe Messung.
Häufige Fragen#
Was ist ein DMARC-Report?
Ein Bericht, den empfangende Mailserver an die Adresse aus rua im DMARC-Eintrag schicken, meist täglich, als gepackte XML-Datei. Er listet je Absender-IP, wie viele Mails mit deiner Domain angekommen sind und ob SPF und DKIM für DMARC bestanden haben.
Was ist der Unterschied zwischen rua und ruf?
rua bestellt Sammelberichte, also Zahlen je IP-Adresse und Tag. ruf bestellt Fehlerberichte zu einzelnen Mails. Für die Frage, welche Versandwege scheitern, reichen die Sammelberichte.
Wie oft kommen DMARC-Berichte?
Laut Google in der Regel einmal am Tag je Empfänger. Wer viel verschickt, bekommt täglich viele Berichte, wer wenig verschickt, an manchen Tagen gar keinen.
Warum bekomme ich keine DMARC-Berichte?
Häufige Gründe: rua fehlt oder hat kein mailto:, die Adresse liegt auf einer fremden Domain ohne Freigabe unter _report._dmarc, das Postfach filtert die Anhänge als Spam, oder es wurden schlicht keine Mails an große Empfänger verschickt.
Wenn du es nicht selbst machen willst#
In eigener Sache: cyberscale bin ich, Stefan Haun aus Tirol. Im Paket E-Mail-Schutz sind vier Wochen Auswertung der DMARC-Berichte enthalten: jede Quelle einem Versandweg zugeordnet, was scheitert, repariert, und danach die Richtlinie Stufe für Stufe umgestellt.
Stand 05.10.2026. Quellen an diesem Tag abgerufen, DNS-Messung am 05.10.2026.
Quellen (7)
- RFC 9990: DMARC Aggregate Reporting: XML-Schema mit
report_metadata,policy_published,record,identifiers,auth_results(Abschnitt 3.1.1), GZIP, Dateiname und Betreff (3.5.2), Freigabe fremder Ziele unter_report._dmarc(4) - RFC 9989: DMARC: Tag
rua, Sammel- und Fehlerberichte (4.1, 4.7) - RFC 7489: DMARC: Vorgänger mit Schema in Anhang C, Größenangabe hinter der Adresse, Freigabe fremder Ziele (7.1)
- Google: About DMARC reports: Berichte in der Regel einmal täglich, Hunderte bis Tausende am Tag möglich, eigenes Postfach oder Dienst empfohlen
- parsedmarc und Dokumentation: Apache-2.0-Lizenz, liest Sammel-, Fehler- und SMTP-TLS-Berichte, gzip und zip, Ausgabe als JSON und CSV
- RFC 5737 und RFC 2606: Beispiel-IP-Adressen und Beispieldomains
- Eigene Messung: DMARC-Einträge von 149 Tiroler Domains (34 Tourismusverbände, 115 Betriebe) am 05.10.2026 um 08:12 UTC per DNS-over-HTTPS (Cloudflare), Freigaben
<domain>._report._dmarc.<ziel>am selben Tag, fehlende mit Google Public DNS gegengeprüft. Veröffentlicht werden nur Summen, keine Namen.
Weiterlesen
Kommentare
Gespeichert werden nur dein Name und dein Text — keine E-Mail-Adresse, keine IP-Adresse, kein Cookie. Jeder Kommentar wird vor der Veröffentlichung gelesen; das dauert meist einen Tag. Näheres in der Datenschutzerklärung.