Understanding DMARC Reports
If you’re new to DMARC, it’s wise to start by receiving DMARC reports. Reports provide to you the IP addresses of mail servers that are sending messages in the name of your mail domain. This includes messages originating legitimately from your mail server, illegitimate uses by spammers and spoofers and, probably most importantly, the grey area where SPF or DKIM authentication fails unexpectedly. This article explains the format of DMARC aggregate reports for humans.
Set Up DMARC DNS Record
Receiving DMARC reports is very easy. All you need is a DNS record and an email address. Prepend your mail domain with the keyword _dmarc
and create a new TXT record that looks like the following example. Replace reports@example.net
with a valid email address.
_dmarc.example.net. IN TXT "v=DMARC1; p=none; rua=mailto:reports@example.net"
p=none
indicates that you don’t want mail receivers to enforce any policy if message authentication fails. This is the equivalent of not having a DMARC record, i.e., testing mode. At this point, you don’t necessarily need to set up SPF or DKIM authentication.
A proper SPF and DKIM configuration is a prerequisite for raising the poliy to p=quarantine
or p=reject
. DMARC reports are extremely helpful to ensure that your SPF and DKIM setup is working correctly.
Aggregate Reports vs. Forensic Reports
There are two types of reports:
Aggregate reports are sent to rua
addresses. They contain aggregated information like number of messages, sender IP address, header-from domain name and message authentication status. Each mail receiver that received a message from your mail domain and supports DMARC reporting will send an aggregate report for the past day.
Forensic reports (or failure reports) are sent to ruf
addresses. Forensic reports are per-message reports, roughly comparable to non-delivery notifications. Note however that few mail receivers send forensic reports due to privacy considerations and thus you’ll seldom receive any forensic report.
If you’re new to DMARC, concentrate on aggregate reports and ignore forensic reports for the time being.
Example Aggregate Report
We will now break down the different parts of an example report. Reports are in XML format and transported as compressed *.gz or *.zip files via email.
The format is defined by an XML Schema Definition (XSD) in an appendix of RFC 7489. See the pyrua validator for more information about the schema.
Subject and Filename
Subject: Report Domain: example.net Submitter: blue.example Report-ID:1621172850.0001
Subject: Report Domain: <your-domain> Submitter: <reporter-domain> Report-ID:<id-string>
Filename: blue.example!example.net!1621123200!1621209599.xml
Filename: <reporter-domain>!<your-domain>!<time-start>!<time-end>.xml
The subject line of the email and the filename of the report consist of the following information:
example.net
is the domain covered by this report for which you created the DMARC DNS record.blue.example
is the report submitter, also known as mail receiver. This is not necessarily the same as the recipient domain, because a mail receiver may report about multiple recipient domains.1621172850.0001
is a unique report identifier for a given report submitter. Some reporters happen to send duplicate reports. The Report-ID can be used to ignore duplicates.1621123200
and1621209599
is the timespan covered by this report, given in unixtime format. A report covers typically 24 hours.
Metadata
<?xml version="1.0"?>
<feedback>
<version>1.0</version>
<report_metadata>
<org_name>Blue Inc.</org_name>
<email>noreply@blue.example</email>
<extra_contact_info>https://www.blue.example/postmaster/</extra_contact_info>
<report_id>1621172850.0001</report_id>
<date_range>
<begin>1621123200</begin>
<end>1621209599</end>
</date_range>
</report_metadata>
The report starts with meta information about the report and contact information of the reporter.
Blue Inc.
is the reporter. It may be the same as the report submitter domain, but also any other string, e.g. organization name or hostname.1621172850.0001
is the same as the Report-ID in the Subject line.- The date range is the same as the report timespan in the filename.
Policy Published
<policy_published>
<domain>example.net</domain>
<p>reject</p>
<sp>reject</sp>
<pct>100</pct>
<fo>0</fo>
</policy_published>
The <policy_published>
section consists of your DMARC DNS record as evaluated by the reporter. Sometimes discrepancies become apparant, for example wrong defaults being used when a specific tag is unset in the DNS record.
example.net
is your domain.<p>reject</p>
is the policy you wish to be used when SPF and DKIM authentication fails. In this example we want to enforce a reject policy, i.e., drop unauthenticated emails.<sp>reject</sp>
indicates the policy for subdomains of *.example.net.<pct>100</pct>
indicates that the policy should be applied to 100% of all emails.<fo>0</fo>
is a setting for forensic reports only. 0 is the default value. Some reporters omit the element or report an empty one if they do not support forensic reports.
Record: Pass
The main body of the report consists of one or more <record>
sections, each representing aggregated authentication results of SPF, DKIM and DMARC. The aggregation of multiple messages implies that all of them had the same authentication result. If the results differ, then this will be reported as different records.
The following example shows a successful DMARC validation.
<record>
<row>
<source_ip>192.0.2.4</source_ip>
<count>3</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<envelope_from>example.net</envelope_from>
<header_from>example.net</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>example.net</domain>
<selector>1234-rsa</selector>
<result>pass</result>
</dkim>
<spf>
<domain>example.net</domain>
<scope>mfrom</scope>
<result>pass</result>
</spf>
</auth_results>
</record>
- The reporter received
<count>3</count>
messages from<source_ip>192.0.2.4</source_ip>
. - Section
<policy_evaluated>
shows the DMARC result:- DKIM and SPF have both passed DMARC validation. The messages have been authenticated successfully.
- Therefore the message has not been disposed by the DMARC mechanism.
- Section
<identifiers>
includes the domain name of the envelope-from per RFC 5321 and the header-from per RFC 5322. The header-from equals your report domain. - Section
<auth_results>
shows the detailed results of SPF and DKIM. Note that some reporters omit certain fields.- There may be any number of DKIM elements subject to the number of DKIM-Signatures in the message.
<domain>
corresponds to parameterd=
in the DKIM-Signature and<selector>
corresponds tos=
. - There will be at least one SPF elements, but the result may be
none
if your domain does not use SPF.<domain>
usually comprises the envelope-from, but may also comprise theHELO
/EHLO
host name instead.<scope>mfrom</scope>
indicates that the example shows the envelope-from.
- There may be any number of DKIM elements subject to the number of DKIM-Signatures in the message.
Analysis result: This record indicates 3 authentic messages from your system.
Record: Fail
The following example shows a failed DMARC validation, which results in a rejection.
<record>
<row>
<source_ip>192.0.2.188</source_ip>
<count>1</count>
<policy_evaluated>
<disposition>reject</disposition>
<dkim>fail</dkim>
<spf>fail</spf>
</policy_evaluated>
</row>
<identifiers>
<envelope_from>red.example</envelope_from>
<header_from>example.net</header_from>
</identifiers>
<auth_results>
<spf>
<domain>red.example</domain>
<scope>mfrom</scope>
<result>pass</result>
</spf>
</auth_results>
</record>
- There is no DKIM element below
<auth_results>
and the overall result below<policy_evaluated>
is:<dkim>fail</dkim>
. This indicates that there was no DKIM-Signature in the message. - There is one SPF element below
<auth_results>
and its result is a pass, but yet the overall result below<policy_evaluated>
is:<spf>fail</spf>
. This is because DMARC has the requirement of identifier alignment, which goes beyond what SPF or DKIM offer. The SPF check succeeded for envelope-from domainred.example
, which differs from the header-from domainexample.net
. However, the two domains are not in alignment and thus DMARC considers the overall SPF result as failure. - DMARC requires a pass and alignment from either SPF or DKIM. If one mechanism fails, the other one may still authenticate the message. In this example, both have failed (or were unavailable) and thus
p=reject
has been applied and the message has disposed.
Analysis result: This record indicates either a spoofed message or a sender for which you haven’t configured a clean SPF/DKIM/DMARC setup yet. Decide by looking at the source IP address: is it one of your legitimate systems?
Record: Forwarder
The following example shows an authentication error, which was overriden by the reporter.
<record>
<row>
<source_ip>203.0.113.15</source_ip>
<count>1</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>fail</dkim>
<spf>fail</spf>
<reason>
<type>forwarded</type>
<comment>Message forwarded by trusted relay</comment>
</reason>
</policy_evaluated>
</row>
<identifiers>
<envelope_from>example.net</envelope_from>
<header_from>example.net</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>example.net</domain>
<selector>1234-rsa</selector>
<result>fail</result>
<human_result>Body hash did not verify</human_result>
</dkim>
<spf>
<domain>example.net</domain>
<scope>mfrom</scope>
<result>fail</result>
</spf>
</auth_results>
</record>
</feedback>
- The SPF check has clearly failed, although it uses the correct envelope-from
<domain>example.net</domain>
. Determine whether<source_ip>203.0.113.15</source_ip>
is one of your legitimate senders.- If yes, then you should adapt your SPF DNS record.
- If no, then this may be a spoofer, but it may be also a forwarder who kept the header-from and envelope-from unchanged.
- The DKIM check has failed as well. The reporter found a DKIM-Signature, but it does not authenticate the message. Either the message has been altered after signing or it does not originate from your system.
<domain>example.net</domain>
together with<selector>1234-rsa</selector>
can be used as weak evidence about where the message originates from. If it shows one of your selectors, chances are that this message originates from your system and has been forwarded by a third party. However, it’s also possible that the DKIM-Signature is simply spoofed.<human_result>Body hash did not verify</human_result>
is an optional field for additional human-understandable information about the result. Most reporters use<result>fail</result>
only and omit<human_result>
.
- Overall, the message has failed DMARC authentication. Yet, the reporter has overriden the policy
p=reject
and decided not to dispose it. This is indicated by element<reason>
, which gives the override reason.- Overriding a policy is not the common case, but the reporter may have a reason why they decided to do so. The reporter indicates with override reason
<type>forwarded</type>
that they believe this is a forwarded message and should be delivered.
- Overriding a policy is not the common case, but the reporter may have a reason why they decided to do so. The reporter indicates with override reason
Analysis result: This record probably indicates a forwarded message. With forwarding, SPF is expected to fail because the IP address of the forwarder does not match your SPF DNS record. DKIM is expected to pass, but may fail when the forwarder alters the message, e.g. prefixes the subject or adds boilerplate text to the body. In this example, the forwarder broke the DKIM-Signature but the reporter decided to override the DKIM failure and accept the message anyway.
Conclusion
Aggregate reports are a great source of information about the SPF/DKIM/DMARC results of your mail domain. Yet, uncertainties remain during analysis. Keep also in mind that the report itself may be flawed or bogus.
I found the best value by monitoring reports for potential configuration errors on my side: did I include all IP addresses in the SPF DNS record? Is the DKIM signer working correctly? Another use is the estimation of impact when raising the DMARC policy: should I expect delivery problems with mailing lists and forwarders?
Though we manually dissected an aggregate report in this article, the XML data is supposed to be processed by tools. You have the option to either subscribe to a DMARC service provider or install a self-hosted open-source tool.