SPF, DKIM and DMARC in practice: stop your domain from being spoofed
Email was born without any way to verify who sends what. By default, anyone can put your domain in the From: field and send a message that looks like yours. That is where phishing, CEO fraud and much of spam live. The fix is three DNS records that, combined, make clear which servers may send on your behalf and what to do with anything that does not add up: SPF, DKIM and DMARC.
None of them is hard on its own; what usually goes wrong is the order and a few details that silently break the protection. Let's set them up properly.
1. SPF — who may send as you
SPF (Sender Policy Framework) is a TXT record listing the servers allowed to send mail for your domain. The receiver checks the sender's IP against that list.
example.com. IN TXT "v=spf1 include:_spf.google.com include:amazonses.com -all"
The key pieces:
include:delegates to your provider's SPF (Google Workspace, Microsoft 365, SendGrid…).ip4:/ip6:authorize a specific IP (your own server).- The final
-allmechanism means "reject everything else". That's the goal.~all(softfail) is an acceptable interim step;?alloffers no protection and+allis a disaster: it authorizes anyone.
Mistake #1: exceeding 10 DNS lookups
The SPF standard allows at most 10 DNS lookups when evaluating the record. Each include, a, mx or redirect counts, and nested includes add their own. Exceed it and many receivers return permerror and your SPF stops protecting you. It's very easy to hit 10 by chaining providers. Consolidate includes and drop the ones you no longer use.
2. DKIM — the cryptographic signature
SPF validates the IP, but it doesn't survive forwarding and doesn't sign the content. That's where DKIM (DomainKeys Identified Mail) comes in: your server signs every message with a private key, and the receiver verifies the signature with the public key you publish in DNS.
selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhki..."
- The selector (
selector1above) lets you keep several keys and rotate them. Your provider picks it, or you do. - The private key lives on the mail server and never leaves it. You only publish the public one.
- Use 2048-bit keys. 1024-bit ones are considered weak.
If you handle signing yourself (e.g. Postfix with OpenDKIM), you need to generate the key pair. You can do it without installing anything: the generator creates the pair with WebCrypto in your own browser and the private key is sent nowhere.
3. DMARC — what to do with unauthenticated mail
SPF and DKIM tell whether a message is legitimate; DMARC tells the receiver what to do when it fails and sends you reports of who mails on your behalf. It's the glue that closes the loop.
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; adkim=s; aspf=s"
p=is the policy:none(observe only),quarantine(to spam) orreject. The goal isreject.rua=is the address where you receive the aggregate reports. Without it you're flying blind.- Alignment: DMARC requires the
From:domain to match the SPF or DKIM domain. In strict mode (adkim=s/aspf=s) it must be exact; in relaxed, the organizational domain is enough.
Mistake #2: staying on p=none forever
Many people publish p=none and leave it there. That only monitors: it blocks exactly zero spoofed messages. p=none is the starting point, not the destination.
The rollout, in the right order
- SPF and DKIM first. Make sure all your legitimate mail (your provider, newsletters, billing, the app that sends alerts…) passes SPF or DKIM and aligns with your domain.
- DMARC at
p=nonewithrua. Let reports flow for 2–4 weeks and review them: you'll discover legitimate senders you didn't know about. - Move to
p=quarantine, optionally withpct=to apply it to a share of mail while you build confidence. - Reach
p=reject. This is where you actually stop spoofing.
The golden rule: don't raise the policy until the reports confirm your good mail aligns. Rush it and you'll drop legitimate email.
How to verify it
Before and after each change, check the real state of your domain's three records (and your providers'). It's the fastest way to catch an SPF with too many lookups, a DMARC forgotten on p=none, or a DKIM whose selector can't be found.
Common mistakes (recap)
- Two SPF records on the same domain: only one is allowed; with two,
permerror. - Exceeding the 10 DNS lookups by chaining SPF includes.
- Ending on
~allor?alland forgetting to move to-all. - DMARC stuck on
p=nonewithout reviewing theruareports. - Forgetting subdomains: if you don't set
sp=, they inherit the domain's policy; don't let them end up weaker by accident. - 1024-bit DKIM keys or revoked selectors (empty
p=) still published.
With all three in place, spoofing your domain goes from trivial to very hard, and your legitimate mail's deliverability improves as a bonus. Half an hour of DNS that saves a lot of headaches.