In the process of “thinking out loud” and doing some Google searches related to email infrastructure I discovered SPF, DKIM, and DMARC. These are technologies to reduce spam and phishing and to improve authentication of email.
SPF – the Sender Policy Framework – allows domain owners to specify the IP addresses that are authorized to send email for their domains.
DKIM – DomainKeys Identified Mail – is a mechanism for email senders to sign email in such a way that the receiver can verify that the message hasn’t been corrupted in transit.
DMARC – Domain-based Message Authentication, Reporting, and Conformance – allows domain owners to recommend an action to be taken in the case of SPF or DKIM failures, and also to request reports from receivers about failing emails, so that a domain owner can measure to what degree their domain is being attacked by spammers or phishing schemes.
I decided that it would be “fun” to set this up for
nimblemachines.com. It’s not that hard. Currently Google is hosting the email for
nimblemachines.com. If you use a different service, or run your own infrastructure, the steps for setting up the digital signing of emails will be different, but all the DNS steps will be substantially the same.
Let’s start with SPF. By publishing the IP addresses of the machines that are authorized to send mail for our domain, we make it possible to identify potential spam and phishing emails: anything sent from an address not on our list should be flagged or rejected.
I followed Google’s G Suite help for configuring SPF.
Since Google’s machines send (and receive) mail for
nimblemachines.com, the SPF record is going to simply “point” to Google’s own SPF record, by using the “include” operator and including _spf.google.com. It’s easy to see this using
$ dig -t txt nimblemachines.com
;; ANSWER SECTION: nimblemachines.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"
and a further
$ dig -t txt _spf.google.com
;; ANSWER SECTION: _spf.google.com. 196 IN TXT "v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all"
I’ll leave it as an exercise for the reader to keep digging, but you’ll be rewarded with a list of the IPv4 and IPv6 addresses that all Google mail orginates from.
The trailing "~all” means that in the case of an IP address mismatch (ie, failure), fail softly. Mark the mail as having failed SPF but don’t reject it outright.
One last comment about SPF: There is an obsolete, experimental DNS record type called “SPF”. Don’t use it!
I initially made the mistake of publishing both an SPF TXT record and an obsolete SPF record (a DNS record with SPF type) to the DNS. RFC 7208 states that SPF records MUST be published as TXT records!
If your DNS provider lets you generate “SPF” records, don’t! Only use TXT.
DKIM makes it possible for the sending machine to cryptographically sign emails that it sends.
DKIM is a bit more complicated than SPF because it involves public key cryptography; in particular, it requires the sending machines to possess the private key; the public key is published to the DNS in a similar fashion to the SPF record. This way anyone can verify the signature.
For this to work for me, Google has to generate the key. Again, I followed the G Suite help for configuring DKIM.
Here is the result:
$ dig -t txt google._domainkey.nimblemachines.com
;; ANSWER SECTION: google._domainkey.nimblemachines.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhki G9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmlYtC9k5N+Ajg5R3esNkMpvybhnou/3k3cNo5fVYIzb2xGSBff0IRIJ qlzOr8XhQckub9emKdA/YDp4BmlBxy2LffPsUVChRXGsN5aM8pwTJ6iQFVKRQ55DjPCgmE4GIUljIMj1OhSn kga9m8KfY25VcTlqHgfQuSyT0uMChdq6tyk9ljU4YuBe5J2oJUHUay" "kmrAGWybvtM6nnARQRw1MIymD8hDwnRabPz2u38UCBAta4KZbiLZTmKmzpC93ac3I/2uta3ml/aJq1sSY+I WlH4LM+y9pehRvhSDZWxUJRhV1SMLdMNHvYJWuIBvrLPPwuFsuCiFKuSkkWVT9QfYQIDAQAB"
To see the public key corresponding to the private key that Google use to sign all gmail.com mail, try this:
$ dig -t txt 20161025._domainkey.gmail.com
In general, the format of the query is
where <s> is a “selector” and <d> is the email’s domain. If you look closely (by viewing an email in Gmail and then clicking “Show original”) you’ll see that there are two other authentication headers in the message: ARC-Seal and ARC-Message-Signature. They both use d=google.com and s=arc-20160816. We can find the matching public key by doing:
$ dig -t txt arc-20160816._domainkey.google.com
(Actually, there is yet another DKIM-related field in there. I leave finding it and digging for the DKIM public key as an exercise for the reader.)
Curiously, Google’s own DKIM TXT records omit the “v=DKIM1” at the beginning, even though RFC 6376 recommends including it.
I understand why a domain owner (and email sender) would want to use SPF and DKIM. DMARC is more mysterious: It is about telling the recipient what to do with emails that “fail” – because the origin machine is not in the SPF list, or because the digital signature is incorrect.
For this reason, I didn’t intially set up a DMARC record, and it seemed like without it, SPF and DKIM weren’t working.
The G Suite admin page for my domain said “Status: Authenticating email”, but when I looked at messages I had sent since setting all this up, I didn’t see any DKIM headers (or SPF headers for that matter), and unlike with messages coming from gmail.com, there was no “SPF: PASS, DKIM: PASS” at the beginning of Gmail’s “Show original” page. I ran the G Suite toolbox Check MX test, which told me I needed a DMARC record... <sigh>
Update (2018 December 11): It turns out I didn’t do a careful enough job checking whether Google was creating SPF and DKIM headers, even in the absence of a DMARC record. I checked today and emails sent to a friend included the SPF and DKIM headers.
Even so, I’ve decided to add a DMARC record. Now the Check MX tool shows
nimblemachines.com passing every test. Yay!
But I may remove the DMARC record. It still seems odd to me that senders should tell receivers how to deal with questionable emails.
I hope this helps! I think these are simple and interesting technologies that all domain owners should be using to make sending and receiving email a litte bit safer.