SPF, DKIM, DMARC: stopping email spoofing

Without these three records, anyone can send email in your name. Here is how they work, and how to deploy them without breaking your legitimate mail.

The problem: SMTP trusts the sender

The protocol that carries email was designed in an era when every machine on the network was known and trusted. It has no built-in way to verify who a message actually comes from. The "From" address you see in your mail client is simply a field the sender chose to fill in — nothing more.

Anyone, from anywhere, can therefore write your domain into that field. Unless you publish records saying which servers are allowed to send on your behalf, a receiving server has no way to tell your genuine invoice from a fraudulent one.

This is why business email compromise works so well and remains so profitable. The attacker does not need to break into anything: an unprotected domain hands them a credible identity for free.

Three records, three different jobs - SPF declares which servers may send mail for your domain. - DKIM cryptographically signs your messages so tampering and forgery are detectable. - DMARC ties the two together, tells receivers what to do on failure, and sends you reports.

They are not alternatives. SPF and DKIM without DMARC produce a verdict nobody acts on; DMARC without SPF and DKIM has nothing to verify.

SPF: who is allowed to send

SPF is a single DNS TXT record listing the servers permitted to send email for your domain. You can read your own in one command:

dig +short TXT example.com | grep spf1
"v=spf1 include:_spf.google.com include:sendgrid.net -all"

Read it left to right: version, then each authorised source, then the policy for everything else. That last mechanism is the one that decides whether the record does anything at all.

  • -all is a hard fail. Anything not listed is unauthorised. This is what you want.
  • ~all is a soft fail: unauthorised, deliver anyway, flag it. Useful while testing, not as a destination.
  • +all authorises the entire internet to send as you. It is never correct.

The ten lookup limit This is the trap that catches most organisations, and it fails in a way that gives no warning.

SPF permits a maximum of ten DNS lookups when evaluating a record. Every include: counts, and so does every include: nested inside your providers own records. Google Workspace alone costs several. Add Microsoft 365, a transactional sender and a marketing platform and you are past ten without having done anything unusual.

Beyond the limit the record does not degrade gracefully. It returns permerror, and receivers treat permerror the way they treat a domain with no SPF at all. Your record still looks perfectly valid when you read it.

Remove includes for services you stopped using, prefer the narrowest include a provider documents, and if you are still over, flatten the record into explicit IP ranges. Flattening works, but it converts a maintained record into one you now have to re-check whenever a provider changes its ranges.

DKIM: proving the message is intact

DKIM adds a cryptographic signature to the headers of every message you send. Your provider signs with a private key, the matching public key sits in your DNS, and a receiver fetches the key to verify the signature. Two things follow: the message really was authorised by your domain, and it was not altered in transit.

Reading your own DKIM key requires knowing the selector, which is provider-specific. Google Workspace uses google by default; Microsoft 365 uses selector1 and selector2.

dig +short TXT google._domainkey.example.com
dig +short TXT selector1._domainkey.example.com

The selector is what lets several keys coexist, which is what makes key rotation possible without downtime and lets each provider sign independently.

Why DKIM matters more than SPF for forwarded mail When a message is forwarded, the sending server changes. SPF fails, and it fails correctly: the forwarding server genuinely is not on your authorised list. The DKIM signature travels with the message and still validates.

A domain relying on SPF alone therefore sees legitimate forwarded mail fail authentication. Mailing lists, alumni redirects and role addresses that forward elsewhere all hit this. It is the single most common reason a DMARC rollout gets abandoned halfway, because the failures look real and nobody can explain them.

Enable DKIM with every provider that sends on your behalf. A provider that cannot sign your mail is a provider that will keep failing DMARC.

DMARC: the policy that makes it real

SPF and DKIM produce verdicts. On their own, nothing obliges a receiving server to act on them. DMARC is the record that says what to do, and that asks receivers to report back.

dig +short TXT _dmarc.example.com
"v=DMARC1; p=reject; rua=mailto:dmarc@example.com; adkim=s; aspf=s"
  • p=none: monitor only. Nothing is blocked, you simply receive reports.
  • p=quarantine: failing mail goes to the spam folder.
  • p=reject: failing mail is refused outright. This is the destination.
  • rua: the address that receives aggregate reports. Without it you are deploying blind.

Alignment, and the false green it produces DMARC does not only ask whether SPF or DKIM passed. It asks whether the domain that passed is the same one your reader sees in the From field.

A message can pass SPF for a providers own domain and still fail DMARC, because that domain is not yours. This is deliberate. Without alignment, anyone could pass SPF for a domain they control while displaying yours.

It is also the reason a domain shows green on a generic SPF or DKIM checker and remains fully spoofable. Those tools answer "is this record syntactically valid", which is a different question from "does this record protect the address my customers actually see". ReconScope evaluates the three records the way a receiving server does, against the visible From domain, which is why its verdict sometimes contradicts a checker that reported everything fine.

One more thing worth being blunt about: p=none offers no protection whatsoever. A domain sitting at p=none is exactly as impersonable as one with no DMARC record at all. It simply generates reports about it.

Reaching p=reject without losing mail

The fear is legitimate: a rushed p=reject blocks real invoices, real newsletters, real recruitment mail. The staged rollout exists precisely to prevent that, and it is not optional.

1. Inventory what sends on your behalf Almost always more than expected: your mail platform, the CRM, the invoicing tool, the ticketing system, the marketing platform, the monitoring alerts, the recruitment software. Every one of them needs SPF authorisation and DKIM signing.

2. Publish SPF and DKIM, then DMARC at p=none Nothing is blocked at this stage. You are opening the reporting channel.

3. Read the reports for two to four weeks Aggregate reports arrive as XML and are painful to read raw; a report analyser is worth the setup. What you are looking for is a legitimate source that fails, which means a provider you forgot to authorise.

4. Fix the failures, then move to quarantine Do not advance while legitimate sources are still failing. Advancing early is what breaks real mail.

5. Move to p=reject once reports are clean Typically two to three months end to end for an organisation with several senders. There is no benefit to rushing, and there is real damage in doing so.

A useful intermediate step: pct=25 applies the policy to a quarter of failing mail, so you can raise the policy gradually rather than all at once.

Look-alike domains: what DMARC cannot stop

DMARC protects your domain. It does nothing about a different domain that merely looks like yours.

An attacker who cannot send as example.com registers exemp1e.com, example-support.com or example.co instead. To a reader glancing at an inbox the difference is invisible, and the attacker fully controls that domain, so they can publish flawless SPF, DKIM and DMARC records for it.

Not every neighbour is a threat Any domain has dozens of typographical neighbours, and treating them all as attacks produces a list nobody acts on. ReconScope only counts a look-alike when two conditions hold together: it could genuinely be mistaken for yours, meaning your exact brand name under another extension or a variant the eye does not catch, and it was registered after your own domain.

A spelling neighbour that predates your brand is not targeting you. It is listed separately and never counts against your score. Nor does a mail server on its own, since every real business has one.

That leaves the two shapes that matter:

  • Your exact brand name under a different extension. The most convincing of all, because the name itself is right.
  • Characters that do not register visually: a lowercase l for an i, rn for m, a doubled letter.

A look-alike becomes dangerous when it is configured to send email, at which point it can invoice your customers in your name, or when it hosts a login page, at which point it harvests credentials from your customers and your staff.

What to do Report the domain to its registrar and to anti-phishing services such as Google Safe Browsing. Warn your teams, and your customers when the risk is concrete. Keep DMARC at p=reject so a look-alike cannot also spoof your real domain. Then consider defensively registering the closest variants you do not yet own. A domain costs about ten euros a year, which is cheaper than one fraudulent invoice.

Sending reputation: the other half of deliverability

Authentication decides whether a receiver trusts your identity. Reputation decides whether they accept your mail at all. The two are related but distinct, and a perfectly authenticated domain can still land in spam.

Blocklists If your sending IP or your domain appears on a blocklist such as Spamhaus, SpamCop or SURBL, legitimate mail goes to spam or is rejected outright. The cause is almost always one of three: a compromised mailbox sending on your behalf, an open relay, or a misconfiguration.

Find the cause and fix it before requesting delisting. A delisting request on an uncorrected problem simply relists you a few days later, and repeated requests damage your standing with the list operator.

Malware and phishing flags If a page on your domain is flagged for hosting phishing or malware, the consequences reach well past email: browsers show a red interstitial to every visitor, and that appears before your site does.

A single compromised page is enough to flag an entire domain, and it usually arrives through an outdated CMS plugin or a set of credentials that leaked elsewhere. Clean the page, request review, then find out how it was published. Skipping that last step is why the same domain gets flagged twice.

Frequently asked questions

What is the difference between SPF, DKIM and DMARC?

SPF lists the servers allowed to send for your domain. DKIM signs messages cryptographically so forgery and tampering are detectable. DMARC ties both to the address your reader actually sees, tells receivers what to do when checks fail, and sends you reports. You need all three: SPF and DKIM produce verdicts nobody enforces without DMARC, and DMARC has nothing to check without them.

Is DMARC p=none enough?

No. p=none blocks nothing at all — a domain at p=none is exactly as impersonable as one with no DMARC record. It is a valuable monitoring stage while you find every legitimate sender, but it is a step on the way, not a destination. Only p=reject actually prevents spoofing.

Will p=reject break my legitimate email?

Only if you skip the staged rollout. Deployed properly — inventory your senders, publish SPF and DKIM, run p=none, read reports for a few weeks, fix failing sources, then raise the policy — legitimate mail is unaffected because every real sender has been authorised before the policy is enforced. Breakage comes from jumping straight to p=reject.

My SPF record no longer works. Why?

The most likely cause is the ten DNS lookup limit. Every include: counts, including those nested inside your providers own records, and three or four SaaS senders are often enough to exceed it. Past ten lookups SPF returns a permanent error and receivers behave as though you had no SPF at all. Remove unused includes, use the narrowest include each provider offers, and flatten the record if you are still over.

See where your own domain stands

A free, fully passive scan. Public data only, no intrusion, no account required.

Scan my domain

Go deeper