DMARC allows you to disallow participating recipients to reject emails that spoof your domain and report these violations to you. You can even run it in reporting only mode if the board is too scared to “loose email delivery”.
If you are concerned with phishing and spoofing and would like to know who is sending emails under the identifiy of your domain(s) this article is for you! But beware DMARC will not magically solve all your email related problems. It can, however, add to your telemetry.
Just by setting up a SPF and a DMARC record you will receive reports about which IPs send emails as your domain. You can then go down the rabbit hole to figuring out which of these machines are yours and which aren’t… and eventually assess how big of a spoofing problem you have.
(This article does not focus on how to use DMARC as recipient nor on any implementation aspects beyond getting reports.)
tl;dr: Domain-based Message Authentication, Reporting and Conformance (DMARC) is an email authentication protocol that prevents unauthorized entities to spoof emails from a DMARC protected domain. It further enables reporting of policy violation (i.e. spoofing attempts) to the domain owner by recipients of spoofed email.
DMARC uses SPF and DKIM. So first a quick introduction to those:
tl;dr: Sender Policy Framework (SPF) is a TXT record in a domains DNS zone setting the policy for which IP addresses are allowed to send email for that domain.
A SPF record is as follows:
example.com. 86400 IN TXT "v=spf1 mx ip4:128.0.11.0/26 include:subdomain.example.org -all"
The v=spf1 mx ip4:128.0.11.0/26 include:_spf.example.org -all
is the policy:
v=spf1
: Gives the version.mx ip4:128.0.11.0/26 include:_spf.example.org
: List who is allowed to send:
mx
: The domains MX record.ip4:128.0.11.0/26
: That IP range,include:sub.example.org
: Everything that is in the SPF record of sub.example.org
.-all
: This is the actual policy:
+all
pass: Everyone is explicitly allowed to send email under the identify of the domain.-all
fail: No one besides the listed are allowed to send email under the identify of the domain.~all
softfail: Probably no one besides the listed are allowed to send email under the identify of the domain.?all
neutral: Equivilant to not having an SPF record.The full SPF RFC: https://tools.ietf.org/html/rfc7208
tl;dr: DomainKeys Identified Mail (DKIM) is an email signing mechanism with the senders public key published in the DNS of the email sending domain.
DKIM only signs over some parts of the email. However, the RFC says that:
“The From header field MUST be signed”
– RFC6376 https://tools.ietf.org/html/rfc6376
This ensures that at the very least the From header field is signed. (But usually all headers plus the body are signed anyway.)
Why requiring singing the From header is important follows:
DMARC now combines SPF and DKIM to authenticate legitimate email.
To see how DMARC does this we will look at an example email being send via SMTP. In the following lines starting with S denote communication by the server and C what the client sends:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
SPF will ensure that the client is actually allowed to send from the domain it gives as the RFC5321.MailFrom (also known as the envelope-from
) address in the MAIL FROM
command in line 4.
It does so by comparing the clients connecting IP with the IPs listed in the claimed from domain’s (in this example domain.tld
) SPF record. If the IP is not authorized to send the server evaluates the SPF policy (see SPF).
DKIM then ensures that the email data is signed. First, a DKIM signature is placed in the header of the email to be send (lines 10-16), which in this case is signed over the From
, Date
, Message-Id
, Subject
and To
headers (h=
parameter in line 12). It is signed by domain gmail.com (d=
parameter in line 11). And with the key found in selector 20161025 (s=
parameter in line 11).
The server will download the key used for signing by querying the TXT record 20161025._domainkey.gmail.com
. This would contain:
20161025._domainkey.gmail.com. 29 IN TXT "k=rsa\; p=MIIB...QqR" "tqE....AQAB"
Then it verifies the signed hash over the signed fields. If this succeeds it verified that the domain named in the d=
parameter has signed the message. Nothing more! The domain in the d=
parameter can actually be different than the RFC5321.MailFrom or RFC5322.From domains (in line 4 and 17)!
This is where DMARC comes into play:
DMARC authenticates use of the RFC5322.From domain by requiring that it match (be aligned with) an Authenticated Identifier.
– RFC7489 https://tools.ietf.org/html/rfc7489
DMARC checks if the domain in the RFC5322.From header (line 17) aligns (i.e. is identical) to either the SPF authenticated RFC5321.MailFrom domain (line 4) or the valid DKIM signature domain.1
The RFC5322.From is also known as the Display From and it is formated as "Display Name" <user@domain>
and it is usually displayed in MUAs. It can be set independently from the RFC5321.MailFrom used in the envelope (hence also sometimes called envelope-from). The RFC5321.MailFrom is usually not displayed in MUAs.
The mail processed with and with added headers from OpenDKIM and python-policyd-spf
looks as follows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Lines 4-5 are the SPF results and lines 6-7 the DKIM results.
In the example the domain domain.tld
did not contain a SPF record.
If Company.tld had set SPF correctly on their domain company.tld
the above example would read
4 5 |
|
because obviously they would not include the spammers IP 42.42.42.42 as an allowed sender.
Similarly, if a DKIM signature was missing from the email the server could not check the email and hence the Authenticated-Results
line would be missing (line 6-7).
Only iff:
OR
d=
DKIM parameter ) AND DKIM signature validateswill DMARC validate.
The DMARC policy, i.e. whether email that does not validate gets rejected or quarantined or can still pass normally, is controlled via a DNS TXT record under the _dmarc
subdomain. So e.g. you have example.com
a DMARC record would be:
_dmarc.example.com. 360 IN TXT "v=DMARC; p=reject; rua=mailto:dmarc@example.org;"
This record set the policy p=
to reject
this means mail not passing DMARC will be rejected. Possible policies are:
none
: Request that no special action should be performed based on DMARC results.quarantine
: Quarantine the email, e.g. move to spam folder, or mark as suspicious.reject
: Reject email already during SMTP transmission.Another aspect here is the rua=
option. It sets an email address to which (daily2) aggregated feedback reports should be send.
NOTE: One pitfall is when the domain of the email that should receive the reports is not the same as the domain of the DMARC record the receiving domain needs a special DNS TXT record allowing DMARC reports for the other domain to be send.
This is to prevent causing spam by sending reports to a domain that does not expect them.
In our example the email dmarc@example.ORG
should receive the reports of example.COM
. To this end, you need to add the following record to example.ORG
:
example.com._report._dmarc.example.org. IN TXT "v=DMARC1;"
Full RFC for DMARC: https://tools.ietf.org/html/rfc7489
If you setup a DMARC record with a valid email address in the rua=
field you should eventually receive emails like:
Subject: Report domain: example.com Submitter: google.com Report-ID: 748039912866467146
From: noreply-dmarc-support@google.com
To: dmarc@example.com
Content-Type: application/zip;
name="google.com!example.com!1563148800!1563235199.zip"
Content-Disposition: attachment;
filename="google.com!example.com!1563148800!1563235199.zip"
Content-Transfer-Encoding: base64
Domains I regularity receive reports from are: - google.com - yahoo.com - aol.com
Unfortunately, not more providers par take in DMARC reporting.
The attached report will look as follows and not only include data of failed DMARC validations but also successful validations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
|
Lines 3-12 give you metadata, such as:
org_name
: Organization that received the emails that are reported ondate_range
: The UNIX timestamp range for which the events in the report where observedLines 13-20 your published DMARC policy as seen by the organization (during the reporting timespan). Obviously DNSSEC will ensure that everyone can verify the authenticity of your published policy (but DNSSEC is not required).
In line 17 you can also clearly see that the p=
parameter, i.e. the policy, is set to none
but we still receive reports.
Line 21-65 are the report records:
Here we have one spoofed email (line 23-40). This spoofed email was send from 42.42.42.42 (line 23) and did not contain any DKIM records and the SPF validation failed (line 37).
We also have 23 (line 44) legitimate emails (line 41-65) send from 13.13.13.13 (line 43) with valid SPF and DKIM (line 55-59) authentication result.
None of the emails was rejected. This can be seen in lines 26 and 46. Only if we set our policy to reject
would line 26 read <disposition>reject</disposition>
and indicate that this spoofed email was rejected.
As you can see analyzing the report is straight forward.
If you can not read an XML file or your reports are just way too big and require data analytics you can buy DMARC analytic services. For example, Twitter and Facebook use Agari, while Google instructs to send the reports directly to a Google owned email address, and hence probably use internal tools.
Forensic reporting (requested via the ruf
tag in the DMARC record) will include message details in these forensic reports.
So you should handle these forensic reports (should you every receive some) with care, as these could include legitimate email from your organisation, that (for whatever reason) failed the DMARC check.
On the other hand these forensic reports (which are supposed to be send in realtime) are highly valuable as they can contain From
and Subject
fields as well as parts of the email’s Body
.
NOTE: Unfortunately, it seems that no one is actually sending these forensic reports. At least I have never received any forensic reports.
While I do understand that in large organizations it may be difficult to determine what IPs should be allowed to send email, to form a valid SPF record. Also I understand that preventing to loose email deliverability is number 1 priority in many organizations.
But as outlined previously, setting up reporting only requires one DNS TXT record to be added to the domain. I consider this to be free.
While the benefits may be marginal: You receive a couple of reports that you need to analyze to get any useful information out of them. Not taking this free tailored threat intelligence is just absurd!
So please take this rant part with a grain of salt, but:
Not consuming DMARC reports is answering the question of “Do you want to know who is stealing your identify online / pretending to be you?” with “No.”
But I don’t send emails from that domain.
– Excuse #1 for people to not set SPF and DMARC DNS records.
This excuse is also used by big players you’d assume should know better such as the @certbund (the federal CERT of Germany):
Instead of excuses here is what you should do:
If you have domain (nomail.com
) you don’t send mail from set the following records:
SPF:
nomail.com. IN TXT "v=spf1 -all"
The setup a DMARC record that instructs to reject all mail that fails to validate and while you are at it include a request to send those rejection reports to your domain yesmail.com where you do emails on:
DMARC with reporting:
_dmarc.nomail.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc-23@yesmail.com; ruf=mailto:dmarc-reports-23@yesmail.com"
In the yesmail.com domain you need to allow DMARC reports for nomail.com to be send via the following DNS TXT record:
nomail.com._report._dmarc.yesmail.com. IN TXT "v=DMARC1;"
So you see that even if you don’t send emails you can still request to receive DMARC reports, .e.g. in this case to your yesmail.com
domain. This is free threat intelligence you should take. Even if you only look into one report once every few month. It tells you what IPs violate your DMARC policy.
You not only get free threat intelligence, but also help recipients to better protect against spam spoofing your domain! So please be nice and set SPF records on your non email sending domains! Thank you.
So who is already using DMARC?
I scanned the first 14,794 domains of the Alexa Top 1M for the availability of various security features and policies that can be set via DNS records.
The data was obtained 2019-08-13. The data is not updated and reflects the state on that day.
You can search the results of the scan here:
Domain | MX | SPF | Sender ID | HIBP | DKIM | DMARC | ASDP | MTA-STS | CAA | DNSSEC | TLSA | ||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
policy | rua | ruf | issue | iodef | valid | DNSKEY | |||||||||
Domain | MX | SPF | Sender ID | HIBP | DKIM | DMARC | ASDP | MTA-STS | CAA | DNSSEC | TLSA | ||||
policy | rua | ruf | issue | iodef | valid | DNSKEY |
You can also filter for policies, e.g. p=reject
will filter for all entries with a reject DMARC policy set.
You can combine searches, e.g. searching for “-all dkim p=reject rua ruf issue dnssec
” will filter for all domains that have a SPF fail policy, DKIM, a DMARC reject policy with aggregate and forensic reporting, a CAA issue policy, and valid verifiable signed DNSSEC.
The listed entries are:
-all
, +all
, ~all
, ?all
).-all
, +all
, ~all
, ?all
)._domainkey.
DNS record is present (indicating DKIM). This only indicates that the _domainkey
record is present.none
, reject
or quarantine
(discerning p=
and sp=
)unknown
, discardable
, all
).issue
) or even wildcard certificates (issuewild
) for the domain (or no one can issue certificates ;
).Here are some over all numbers of the dataset:
TOTAL: 14794
TOTAL: NO MX record 2432 = 16 %
SPF: NO POLICY 5026 = 33 %
SPF: all 9768 = 66 %
SPF: -all 3220 = 21 %
SPF: ~all 5526 = 37 %
SPF: ?all 579 = 3 %
SPF: +all 9 = 0 %
SPF: illegal (multiple all tags) 173 = 1 %
(missing % use a pure redirect policy)
SPF: NO POLICY while no MX 2130 = 87 % of domains without MX record
SPF: -all while no MX 159 = 6 % of domains without MX record
DKIM: NO _domainkey. 6969 = 47 %
DKIM: YES a _domainkey. exists 7825 = 52 %
(missing % are rounding errors)
DMARC: NO POLICY 11062 = 74 %
DMARC: p= 3732 = 25 %
DMARC: p=none 2195 = 14 %
DMARC: p=reject 958 = 6 %
DMARC: p=quarantine 577 = 3 %
DMARC: rua 3191 = 21 %
DMARC: ruf 1907 = 12 %
DMARC: illegal (contradicting) 1 = 0 %
DMARC: p=none 2195 = 58 % of domains with DMARC
DMARC: p=reject 958 = 25 % of domains with DMARC
DMARC: p=quarantine 577 = 15 % of domains with DMARC
DMARC: rua 3191 = 85 % of domains with DMARC
DMARC: ruf 1907 = 51 % of domains with DNARC
DMARC: illegal (contradicting) 1 = 0 % of domains with DNARC
ASDP: NO POLICY 14546 = 98 %
MTA-STS: 17 = 0 %
CAA: issue 710 = 4 %
CAA: iodef 230 = 1 %
DNSSEC: 482 = 3 %
DNSKEY: 886 = 5 %
TLSA: port 25/tcp or 443/tcp 45 = 0 %
TLSA: but no DNSSEC 18 = 0 %
TLSA: but not even DNSKEY 18 = 0 %
What makes my sad about these numbers is:
87 % of the domains that have no MX record listed do not specify via SPF that said domain does not send email. (Granted it is possible that the domain does send mail, but still it could be specified in SPF!)
74 % of the domains do not have a DMARC policy set. As outlined in this article you get good free reporting on abuse of your domain. Why not take it?
What makes me facepalm:
18 domains have TLSA records for DANE, which is supposed to prevent MitM attacks against mostly SMTP communications by publishing trusted TLS key data via DNS, but don’t have DNSSEC to protect these records themself from MitM. UPDATE 1: This includes TLSA records for port 25, which were queried from the MX records of the domains. While the MX domains may have DNSSEC the domains themself don’t. This equates to these domains not having a DANE at all.
The 9 domains publishing a +all
SPF policy basically explicitly allow anyone to send email under the identity of their domain. Not gonna name any names … search the table above!
What I can related to:
What give me hope:
66 % do have a SPF policy.
52 % do have “something” in the _domainkey.
DNS entries. Unfortunately to check DKIM accurately a key selector is needed, which would require signed email samples from all domains to be assessed.
85 % of the domains that have DMARC also want reports.
In case you are wondering what the gradient is between top sites and lower Alexa ranked sites:
Top | 100 | 100 - 200 | 200 - 300 | 300 - 400 | 400 - 500 | 500 - 1k | 1k - 2k | 2k - 3k | 3k - 4k | 4k - 5k | 5k - 10k |
---|---|---|---|---|---|---|---|---|---|---|---|
DMARC | 65% | 66% | 54% | 37% | 43% | 38% | 30% | 30% | 26% | 27% | 22% |
SPF | 89% | 83% | 77% | 76% | 76% | 71% | 72% | 71% | 68% | 66% | 64% |
DKIM | 68% | 65% | 66% | 61% | 60% | 62% | 56% | 56% | 54% | 52% | 51% |
Here you can clearly see that there is a significant gradient to DMARC deployment. However, the SPF and DKIM gradient isn’t as harsh.
A good introduction on DMARC is DMARC.org’s Introduction to Email Authentication presentation [1].
DMARC.org also has a lot of resources. The most interesting are:
Some resources to help with setting up an maintaining SPF records:
The Messaging, Malware and Mobile Anti-Abuse Working Group has a great best practice guide for managing SPF records [2].
Vladimir Dubrovin has a good article on the myths and legends of SPF [3].
Hang Hu and Gang Wang of Virginia Tech scanned the SPF and DMARC records of the Alexa top 1 million domains [4]. They also checked for mail receivers DMARC policy regarding rejection of spoofed emails. They found that GMail (gmail.com) still lets around 53% of spoofed emails though despite not passing authentication checks. Only Hotmail (hotmail.com) rejected 100% of emails that did not pass authentication checks. T-Online (t-online.de) doesn’t even support any of SPF, DKIM nor DMARC and thus lets 100% of the spoofed emails pass without authentication checks.
So spam prevention happens at the receiver. Even if your company has a working DMARC policy if a receiver does not reject emails that don’t pass DMARC authentication there is nothing you can do about it.
On the other hand if you do not set a DMARC policy you are solely responsible when your domain gets spoofed and users can’t protect against it.
Hence at least enable DMARC reporting to know how bad the spoofing problem is for your organization. Then, if warranted, work towards a full DMARC p=reject
policy.
[1] DMARC.org, “Introduction to Email Authentication - An explanation of how SPF, DKIM, and DMARC function.” https://dmarc.org/presentations/Email-Authentication-Basics-2015Q2.pdf, 2015.
[2] Messaging, Malware and Mobile Anti-Abuse Working Group, “M3AAWG best practices for managing sPF records.” https://www.m3aawg.org/sites/default/files/m3aawg_managing-spf_records-2017-08.pdf, August-2018.
[3] Vladimir Dubrovin, “Myths and Legends of SPF.” https://hackernoon.com/myths-and-legends-of-spf-d17919a9e817, October-2017.
[4] Hang Hu and Gang Wang, “End-to-End Measurements of Email Spoofing Attacks,” 27th USENIX security symposium (USENIX security 18). https://www.usenix.org/conference/usenixsecurity18/presentation/hu; USENIX Association, Baltimore, MD, pp. 1095–1112, Aug-2018.