(KEEPSITESAFE)

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.

By KeepSiteSafe ·

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=spf1 is 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 ~all while 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=none with rua=. 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 raise pct gradually. 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.

Every check described here is one KeepSiteSafe actually runs, using named open-source engines — Mozilla’s HTTP Observatory, CryptoLyzer and the CISA KEV catalogue. You can verify any finding against its source rather than taking our word for it.

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
Stop email spoofing: SPF, DKIM and DMARC, with the exact DNS records | KeepSiteSafe