SPF, DKIM, DMARC — the three records that stop email spoofing
A plain-English guide to the three DNS records that decide whether attackers can forge email from a domain. If you own a domain, you need all three.
Email was designed in the 1970s. It has no built-in mechanism for verifying who a message is actually from. Every mail server on the internet trusts every other mail server. That's why phishing works: without extra DNS records, anyone can send an email that claims to be from your domain, and most inboxes will happily deliver it.
Three DNS records fixed this over the last twenty years. Together they let receiving servers verify that mail claiming to be from you actually is from you. Individually they leak. Together they close the door.
SPF — Sender Policy Framework
SPF is a TXT record in your DNS listing every server that's allowed to send mail on your behalf. When a receiving server gets a message claiming to be from you, it looks up your SPF record and checks whether the sending IP is in the list. If not, the message fails SPF.
v=spf1 include:_spf.google.com include:mailgun.org ~allThe '~all' at the end is a soft-fail — everything not explicitly allowed should be treated as suspicious, but not necessarily rejected. Use '-all' (hard-fail) once you're confident you've listed every legitimate sender.
DKIM — DomainKeys Identified Mail
SPF verifies the sending server. DKIM verifies the message itself. Every outbound message gets a cryptographic signature computed from its headers and body. Receivers fetch your public key from DNS and verify the signature. If it matches, the message wasn't tampered with in transit and really came from a sender who holds the private key.
Each email provider (Google, Microsoft, Mailgun, SendGrid, etc.) gives you a DKIM selector — a subdomain like 'google._domainkey.yourdomain.com' — and a public key to publish there. You set it once and forget about it.
DMARC — the policy layer
SPF and DKIM tell receivers whether a message is authentic. DMARC tells receivers what to do when it isn't. It also tells you what's happening — DMARC reports include every server sending mail as your domain, legitimate or not.
v=DMARC1; p=reject; rua=mailto:dmarc-reports@yourdomain.comThe three DMARC policies
- p=none — monitor only. Receivers report failures but deliver mail as usual. Start here.
- p=quarantine — send failing mail to spam. A middle step once your reports are clean.
- p=reject — refuse failing mail outright. The end goal. This is what makes spoofing impossible.
Why all three matter
SPF alone breaks when mail is forwarded — the forwarding server isn't in your SPF record. DKIM alone doesn't tell receivers what to do with failures. DMARC without both is toothless. Together, a receiver can say: this message claims to be from your domain, it failed both cryptographic and network checks, and your DMARC policy is 'reject' — so it goes in the bin.
Practical rollout
- Publish SPF listing every legitimate sender, with ~all.
- Enable DKIM on every mail sender you use (Google Workspace, Mailgun, etc.).
- Publish DMARC with p=none and a reports mailbox.
- Read the reports weekly for two months, add missing senders to SPF, fix DKIM misconfigurations.
- Move DMARC to p=quarantine, then p=reject.
- Change SPF to -all.