Guide
Stop email spoofing: SPF, DKIM and DMARC
Why SPF alone cannot stop someone sending mail as you, what DMARC alignment really checks, and a rollout that will not break your invoicing.
Without a DMARC policy, anyone can send email as you
Pick any domain with no DMARC record. Anyone, from any server, can send mail with that domain in the From field, and most receiving servers will deliver it. The person who gets defrauded is your customer, and what they see in their inbox is your name.
This is why it matters more than it looks. It is a deliverability problem — your legitimate mail lands in spam because nothing vouches for it — and simultaneously a fraud problem, where the damage lands on someone who trusted you. Three DNS records fix both. None of them require touching your application.
SPF authorises the wrong From
SPF publishes the list of servers permitted to send for your domain. A receiving server checks the connecting IP against that list.
Here is the gap nobody mentions: SPF validates the envelope sender — the address in the SMTP MAIL FROM command — not the From header the recipient actually sees. Those can differ completely. An attacker sets the envelope to a domain they legitimately control, passes SPF for that domain, and puts your domain in the visible From. SPF passes. The recipient sees you.
Closing that gap is the entire reason DMARC exists. SPF on its own, no matter how carefully written, cannot stop someone spoofing your visible address.
Type: TXT Name: @ (the domain itself, not a subdomain) Value: v=spf1 include:_spf.google.com include:sendgrid.net ~all
Replace the includes with your actual senders. Two rules that matter:
- One SPF record per domain. Two TXT records both starting
v=spf1is a permanent error, and the result is that SPF fails entirely rather than one winning. This is a common outcome of adding a new mail provider without editing the existing record. ~all(softfail) or-all(hardfail) at the end, never+all, which authorises the entire internet. Start with~allwhile you confirm you have found every sender.
The 10-lookup limit that silently breaks everything
SPF permits a maximum of 10 DNS lookups while evaluating a record. Every include:, a, mx and redirect costs at least one, and each include: can nest further lookups inside itself that you never see. Three or four providers is often enough to exceed it.
When you go over, the result is permerror, and most receivers treat permerror as no SPF at all. Your record looks perfectly reasonable in the DNS zone and does nothing. Nothing warns you — which is why this is worth checking rather than assuming.
The fix is to flatten: replace nested includes with the IP ranges they resolve to, and accept that you now have to review them when a provider changes infrastructure. It is a maintenance cost, but a record that silently fails is worse.
DKIM signs the message itself
DKIM puts a cryptographic signature in the message headers, made with a private key held by your mail provider. The public key sits in your DNS under a selector, so any receiver can verify the message was sent by someone holding your key and was not modified in transit.
Because DKIM travels with the message, it survives forwarding — which SPF does not, since forwarding changes the connecting IP. That makes DKIM the stronger of the two, and the one to prioritise if you only get one working.
Type: TXT Name: selector1._domainkey Value: v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB...
The selector name is chosen by your provider — Google uses google, Microsoft selector1 and selector2, and others vary. Your provider gives you both the selector and the key; you do not generate these yourself. If you send from several providers, each publishes its own selector, and all of them can coexist.
DMARC ties them together — through alignment
DMARC is the layer that finally protects the address your recipient sees. It does two things: it tells receivers what to do with mail that fails, and it sends you reports about mail claiming to be from you.
The mechanism is alignment, and this is the part most explanations skip. DMARC passes only if SPF or DKIM passes AND the domain that passed matches the domain in the visible From header. That match is what defeats the SPF gap described earlier: the attacker's envelope domain passes SPF, but it does not align with your From, so DMARC fails.
You need only one of the two to align, not both. In practice DKIM alignment is more reliable, because forwarding breaks SPF.
Type: TXT Name: _dmarc Value: v=DMARC1; p=none; rua=mailto:[email protected]; pct=100; adkim=r; aspf=r
p=none blocks nothing
Be clear about this, because it is the single most common misunderstanding: p=none is a reporting mode. It asks receivers to tell you what they saw and to change nothing. A domain sitting on p=none has no more spoofing protection than a domain with no DMARC record at all. Plenty of organisations publish it, see the record in their zone, and believe they are covered.
Only p=quarantine and p=reject do anything.
The rollout that will not break your invoicing
Going straight to p=reject almost always breaks a sender nobody remembered: the invoicing system, the CRM, the newsletter tool, the recruitment platform, the monitoring alerts. Those senders are exactly what the reports are for.
- Weeks 1-3: publish
p=nonewithrua=. Read the reports. Every sending IP you cannot account for is either a forgotten legitimate system or someone spoofing you, and you need to know which. - Weeks 4-6: bring every legitimate sender under SPF or DKIM. This is the actual work, and it is where the time goes.
- Weeks 7-9: move to
p=quarantine; pct=25, then raisepctgradually. Quarantine sends failures to spam rather than deleting them, so a mistake is recoverable — someone finds the message in their junk folder rather than never receiving it. - Week 10:
p=reject; pct=100.
Keep rua= in place permanently. It is how you find out that a new SaaS tool someone signed up for is sending as your domain and failing.
On the strict variants: adkim=s and aspf=s require exact domain matches rather than allowing subdomains. Leave both relaxed (r) unless you have a specific reason, because strict alignment breaks mail sent from subdomains, and that includes a lot of transactional providers.
DNSSEC protects the answers
SPF, DKIM and DMARC are all DNS records, and DNS answers can be forged. An attacker who can spoof your DNS responses can serve a permissive SPF record of their own choosing, and the receiver has no way to detect the substitution.
DNSSEC signs your zone so a receiver can verify the answer genuinely came from you. It is enabled at your registrar or DNS host, usually as a single toggle, and it is what makes the other three records trustworthy rather than merely present.
One warning: if you move DNS providers with DNSSEC enabled and do not migrate the keys correctly, your domain becomes unresolvable — not slow, not degraded, invisible. Disable DNSSEC before a nameserver change and re-enable it afterwards.
CAA controls who can issue your certificates
Related problem, same toolbox. Without a CAA record, any public certificate authority will issue a certificate for your domain to whoever passes their validation check. CAA restricts that to the authorities you name.
Type: CAA Name: @ Flags: 0 Tag: issue Value: letsencrypt.org
One record per authority. This is where people get caught: if your certificates come from Let's Encrypt but your CDN silently provisions its own through a different CA, and you have only published letsencrypt.org, renewal fails. List every CA actually in use, and remember that a CDN in front of your site is usually one of them. Add iodef with a mailto if you want to be notified about refused issuance attempts.
Verify, do not assume
dig +short TXT yourdomain.com | grep spf1 dig +short TXT _dmarc.yourdomain.com dig +short TXT selector1._domainkey.yourdomain.com dig +short CAA yourdomain.com dig +short DS yourdomain.com # non-empty means DNSSEC is signed
Checking the record exists is not the same as checking it works. The SPF lookup limit, a duplicate v=spf1 record, and a DKIM selector that does not match what your provider actually signs with are all invisible to dig — the record looks fine and mail still fails.
A free scan checks all of these together, including whether your SPF is within the lookup limit, whether DMARC is on a policy that actually enforces anything, and whether DNSSEC and CAA are in place — with the exact record to add for whatever is missing.
Check your DNS records
Free scan, no signup, any domain — SPF lookup count, DMARC policy strength, DKIM, DNSSEC and CAA, with the exact record to add.
Scan free