Home / 514 / SPF, DKIM and DMARC: the customs checkpoint that decides if your email gets in or goes to spam

SPF, DKIM and DMARC: the customs checkpoint that decides if your email gets in or goes to spam

Sobre de correo atravesando un control de verificacion digital

Email is one of the few internet services that still works almost the same way it did forty years ago. Its base protocol, SMTP (Simple Mail Transfer Protocol), was defined in 1982 for a small network of machines that knew each other and trusted each other. In that context nobody needed to prove who they were. Today anyone with a five-euro server can connect and declare MAIL FROM:<president@whitehouse.gov> without the destination machine having any way to check it.

That legacy is the root of the problem: anyone can put your address in the sender field. The fix was never applied inside SMTP; it lives in three text records published in the domain’s DNS. They are SPF, DKIM and DMARC, and between the three of them they decide whether your message lands in the inbox or stays at the door.

The envelope and the letter: two different senders

To understand the rest you have to accept one oddity of email: a message carries two senders. One is the envelope from, the address that appears in the MAIL FROM command during the technical conversation; that is what servers use to bounce mail when delivery fails. The other is the From: header you actually see in your client, which is nothing more than text inside the message. They do not have to match, and that mismatch is the root of almost all spoofing.

SPF: the list of authorised postmen

The first of the three mechanisms, SPF (Sender Policy Framework), is an allow-list of IP addresses. It is published as a TXT record on the domain:

v=spf1 ip4:185.199.108.0/22 include:_spf.google.com -all

The syntax is compact and deliberate. ip4: authorises whole address ranges; include: delegates to another domain’s SPF (standard practice when you send through an external provider); the a and mx mechanisms authorise the IPs of your website or your mail servers. The qualifiers say what to do with anything that does not match: -all means “reject everything else”, ~all is a soft fail, ?all is “no opinion”. Publishing +all is giving your domain away.

SPF has two significant limits. The first is by design: it only looks at the envelope, not the From header. Even with a strict SPF, an attacker can send with a different envelope domain and put your address in the visible From: without SPF complaining. The second is technical: every include costs a DNS lookup and the standard caps the total at ten lookups per check. Domains with many subcontractors blow past that limit, get a PermError, and their mail starts failing even though nobody seems to have touched anything.

On top of that, SPF is tied to the IP address, so it breaks on forwarding: if a user forwards your message to another account, it leaves from a different, unauthorised IP. That is why SRS (rewriting the sender on forward) and ARC (signing the forwarding chain) exist.

DKIM: the signature that travels inside the message

DKIM (DomainKeys Identified Mail) attacks the problem from a different angle: instead of authorising machines, it places a cryptographic signature inside the message itself. The sending server signs a digest (SHA-256 hash) of the body and a selection of headers with its private key. The receiver fetches the public key from DNS, recomputes the hash and compares.

The public key is published in a record whose name includes a selector, which lets you keep several keys active at once (say google and selector2) and rotate them without an outage:

google._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."

The message goes out with a DKIM-Signature header naming the key used, the signing domain (d=), the hash and a canonicalisation tag (relaxed or simple). That tag is what allows an intermediate server to reformat whitespace or change header casing without breaking the signature. Watch out for the l= tag, which signs only the first bytes of the body: it lets anyone append unsigned text at the end, and no serious domain should use it. DKIM survives forwarding better than SPF because the signature travels with the message, but it stays fragile: if a forwarder adds a new header or touches the subject, the signature breaks.

DMARC: alignment and policy

SPF and DKIM on their own are easy to dodge. DMARC (Domain-based Message Authentication, Reporting and Conformance) is the glue: it checks that the domain authenticated by SPF or by DKIM matches the domain in the visible From. That is called alignment, and it can be strict (adkim=s, aspf=s) or relaxed (adkim=r), where sharing the root domain is enough.

The record lives in a specific DNS subdomain:

_dmarc.yourdomain.com TXT "v=DMARC1; p=reject; pct=100; rua=mailto:reports@yourdomain.com; sp=quarantine; adkim=s; aspf=s"

The p= tag is the policy: none does nothing, quarantine sends to spam, reject blocks. pct= applies it to a percentage of messages, and sp= sets the policy for subdomains. The two tags almost nobody uses and that are the most valuable are rua= and ruf=: the first requests aggregate reports (compressed XML files telling you how many messages passed or failed from each IP) and the second individual failure reports, now largely abandoned for privacy reasons.

The sensible rollout is gradual and driven by those reports: start with p=none for weeks, review which third-party IPs are sending mail as your domain (old newsletters, forgotten platforms, maybe an attacker), fix the legitimate ones, and only then move to reject. Jumping straight to reject on day one is the fastest way to discover how many systems were sending mail on your behalf without your knowledge.

What these three records do not fix

Strict DMARC does not end scams, and it helps to know why. An attacker can use your name in the display name while sending from a look-alike address: bank <info@banc0.com>. The fake domain’s SPF, DKIM and DMARC will pass perfectly, because its owner configured them correctly. There are also homograph attacks, using Unicode characters that look identical to Latin letters, and the classic compromised legitimate provider: domains with good reputation and correct DMARC sending a fraudulent message.

That is why receivers combine many more signals: IP and domain reputation, blocklists, the age of the domains behind links, content analysis and machine-learning models. In parallel, the transport layer is being hardened: MTA-STS, which publishes an HTTPS policy forcing TLS encryption and forbidding a downgrade to plain text; DANE, which anchors the certificate in DNS; and TLS-RPT for reports when that encryption fails. On the visible side sits BIMI, which shows a brand’s verified logo in the inbox and requires DMARC at reject as a precondition.

Check it yourself in three commands

All of this is audited with dig from any terminal, because these are public DNS records. First, see whether SPF exists and whether the final policy is strict:

dig +short TXT yourdomain.com | grep spf1

Then the DMARC policy and the DKIM selector, which you need to know in advance (the header of any message you send tells you):

dig +short TXT _dmarc.yourdomain.com
dig +short TXT selector._domainkey.yourdomain.com

And the definitive test is in the header of any email you have sent: the Authentication-Results line added by the receiver summarises whether SPF, DKIM and DMARC returned pass and whether the domain was aligned. In practice, that is the message’s customs declaration.

Conclusion

The whole trust model of email today rests on three strings of text in DNS: a list of IPs, a public key and a policy with a mailbox for reports. SPF authorises machines, DKIM signs content, DMARC aligns identities and decides the destination. When all three line up, the message gets in; when one breaks or the domain is not aligned, legitimate mail ends up in spam and the fraudulent kind has an open road. Reviewing those three records is still, today, one of the audits with the best effort-to-result ratio in any company’s infrastructure.