Email and domain security

How to stop criminals sending email as your business: SPF, DKIM and DMARC

Nothing in the design of email stops a stranger writing your business's address in the From line. Three DNS records fix that, they cost nothing, and most Kenyan businesses have one of the three, half-configured. This guide is complete enough to fix your domain from, without calling anyone.

The short answer

Publish SPF listing which servers may send for your domain, turn on DKIM signing at every provider that sends mail as you, and publish a DMARC record at _dmarc.yourdomain. Start DMARC at p=none with a rua reporting address, read the reports for two to four weeks until every legitimate sender passes in alignment, then move to p=quarantine and finally p=reject.

Until DMARC is at quarantine or reject, anyone in the world can put your domain in the From line of an email to your guests, your patients or your suppliers, and their mail server has no instruction to stop it. SPF and DKIM alone do not close that — DMARC is the record that does.

Why does this matter for a Kenyan business?

The attack is not sophisticated. Someone sends an email that appears to come from your address — to a guest confirming a booking, to a supplier chasing an invoice, to your own accounts clerk — and changes the bank or till details. The money moves once and does not come back. It costs the attacker nothing, needs no access to your systems, and works precisely because the recipient trusts the name in the From line.

Kenya's national computer incident response team, KE-CIRT, detected 4.56 billion cyber threat events in the fourth quarter of 2025 — a 441% rise on the previous quarter — and 3.37 billion in the first quarter of 2026. Serianu puts Kenyan cybercrime losses at roughly USD 230 million, about KES 29.9 billion, across 2024 and 2025.

What makes this the first thing to fix is not the threat number, though. It is the economics: the fix is three DNS records, it costs nothing but attention, and nothing has to be installed on a single machine. There is no other control in security with that ratio.

Where most businesses actually are $ dig TXT baharicourt.example +short
  1. "v=spf1 include:_spf.google.com ~all"

    SPF is published, and it is fine as far as it goes. It authorises Google to send for this domain.

  2. ; no TXT record at _dmarc.baharicourt.example

    And this is the gap. With no DMARC policy, a receiving server has no instruction about mail that claims to be from this hotel and is not. Most simply deliver it.

baharicourt.example is a fictional hotel on the reserved .example domain — the same one used in our worked sample report.

What is SPF, and what does a good one look like?

SPF — Sender Policy Framework, RFC 7208 — is a single TXT record at your domain listing which servers are allowed to send mail for it. A receiving server looks up the record and checks whether the machine connecting to it appears in the list.

SPF record, taken apart $ dig TXT baharicourt.example +short
  1. v=spf1

    The version. It must come first, and it is how a resolver tells this TXT record apart from the dozen other TXT records on your domain.

  2. include:_spf.google.com

    Delegates to Google Workspace’s own published list of sending servers. Each provider publishes one; you never list their IP addresses yourself.

  3. include:spf.protection.outlook.com

    A second provider. A hotel commonly has two or three: mailbox provider, booking engine, invoicing or marketing tool.

  4. ip4:41.203.0.10

    A specific server you run — an on-premises PMS or accounting box that sends its own mail. Use this only for addresses that will not change.

  5. ~all

    The catch-all. ~ is softfail: anything not listed above is suspicious but still delivered. - is fail, the strict form. Never use + all, which authorises the entire internet.

One record, read left to right, first match wins. The whole thing is a single TXT value at the domain apex.

The three rules that break SPF in practice

  1. Exactly one SPF record. Two TXT records beginning v=spf1 is a permanent error, and a permanent error is not a fail — many receivers simply stop evaluating. If you add a provider, merge its include: into the record you already have.
  2. Ten DNS lookups, maximum. Each include:, a, mx, exists, ptr and redirect= costs a lookup, and so does everything they in turn include. Exceed ten and the result is again a permanent error. Four include: terms can quietly be eleven lookups.
  3. SPF does not authenticate what the recipient sees. This is the one that matters. SPF checks the envelope sender — the address used in the SMTP conversation, recorded as Return-Path — not the From: header shown in the mail client. An attacker can pass SPF perfectly for a domain they own while writing your domain in the From line.

SPF also breaks on forwarding: when a message is forwarded, the forwarding server's address is not in your list, so SPF fails through no fault of yours. That is not a reason to skip it. It is the reason DKIM exists.

What is DKIM?

DKIM — DomainKeys Identified Mail, RFC 6376 — has your sending server cryptographically sign each message. The signature covers the message body and a chosen set of headers, and travels with the message in a DKIM-Signature header. You publish the matching public key in DNS; a receiving server reads the d= (domain) and s= (selector) tags from the signature, looks up the key and checks it.

DKIM public key record $ dig TXT google._domainkey.baharicourt.example +short
  1. google._domainkey.baharicourt.example.  IN  TXT

    The name is always <selector>._domainkey.<your domain>. The selector is chosen by whoever generates the key — "google", "selector1", "s1", "mj" and "k1" are all common.

  2. "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA…"

    The public key. The private half never leaves your provider. 2048-bit keys are the sensible default; some DNS panels need the long value split into quoted chunks.

You do not generate this by hand. Each sending provider produces the key and tells you the record to publish.

Because the signature is carried inside the message, DKIM survives forwarding as long as the message is not modified in transit. That makes it the more robust of the two, and it is why a domain with both SPF and DKIM ends up with far fewer false failures than one with SPF alone.

Turn it on everywhere that sends mail as you, not just at your mailbox provider. The booking engine that sends confirmations, the accounting package that sends invoices and the newsletter tool all offer DKIM, usually as a checkbox and a DNS record. Every sender you miss becomes a failure you will have to explain to yourself later, in a report.

What is DMARC, and why is it the one that works?

DMARC — RFC 7489 — does three things none of the others do. It ties SPF and DKIM results to the From: domain the recipient actually sees, through a rule called alignment. It tells receiving servers what to do when that check fails. And it asks them to send you reports about mail claiming to be from you.

A message passes DMARC if either SPF passes and the envelope domain aligns with the From domain, or DKIM passes and the signing domain aligns with the From domain. One is enough. Relaxed alignment, the default, accepts a match on the organisational domain; strict alignment requires an exact match.

DMARC record, taken apart $ dig TXT _dmarc.baharicourt.example +short
  1. v=DMARC1

    Required, and required to be first.

  2. p=none

    The policy: none, quarantine or reject. p=none asks receivers to change nothing and only to report — it is a measuring instrument, not a control.

  3. rua=mailto:dmarc@baharicourt.example

    Where daily aggregate reports go. Without this, p=none achieves nothing at all: no policy, no data.

  4. fo=1

    Ask for a failure report when any underlying check fails, rather than only when everything does. Useful while you are still finding senders.

  5. adkim=r; aspf=r

    Alignment mode for DKIM and SPF: r is relaxed (the default), s is strict. Leave both relaxed until you are at p=reject and certain.

  6. sp=reject

    Subdomain policy. If you omit it, subdomains inherit p — so the real risk is not omission, it is publishing a separate, weaker DMARC record on a subdomain and undoing yourself. Setting sp=reject early protects subdomains you never send from, while the apex is still at none.

A single TXT record at _dmarc.yourdomain. Everything above is one value, semicolon separated.

How do I read a DMARC report?

Aggregate reports arrive as compressed XML attachments, usually once a day, from each participating receiver — Google, Microsoft, Yahoo and others. Each one lists the source IP addresses that sent mail claiming to be from your domain, how many messages each sent, and the SPF and DKIM results with their alignment.

You are looking for three groups.

Sources you recognise, passing
Your mailbox provider, mostly. Nothing to do.
Sources you recognise, failing
The interesting group, and usually the largest at first: the booking engine, the invoicing tool, the mail-merge plugin somebody in sales installed. Fix each by enabling DKIM at that provider, or by adding it to SPF — then check the next report to confirm it now passes in alignment. This is the whole job.
Sources you do not recognise
Some are forwarders — a guest forwarding a confirmation to a colleague — which fail SPF harmlessly and are the reason to have DKIM. The rest is mail sent as you by people who are not you. That is the volume your policy will eventually stop.

Send rua to a mailbox a person opens, or to a report-processing service that renders the XML into something readable. One caution: if you send reports to an address at a domain you do not control, that domain must publish an authorisation record for yours — a TXT record at yourdomain._report._dmarc.theirdomain containing v=DMARC1. Report processors document this; if reports never arrive, it is the first thing to check.

The staged rollout, week by week

Publishing p=reject on day one is the classic way to break your own invoicing and spend an afternoon explaining it. Go in stages, and let the reports tell you when to move.

A rollout that does not break anything
Stage What you do Move on when
Inventory List every system that sends email as you: mailbox provider, booking engine, POS or PMS receipts, invoicing, payroll, CRM, website contact form, newsletter tool, the accountant's portal The list stops growing when you ask around the office
Week 1 Publish one correct SPF record covering that list. Enable DKIM at every provider on it Each provider shows DKIM as enabled and verified
Week 1 Publish v=DMARC1; p=none; rua=mailto:dmarc@yourdomain; fo=1. Consider sp=reject now if no subdomain sends mail Reports start arriving, usually within 48 hours
Weeks 2–4 Read every report. Fix each legitimate sender until it passes in alignment. Expect to find two or three you had forgotten A full week of reports where everything you recognise passes, and the only failures are forwarders and strangers
Weeks 4–6 Move to p=quarantine. Keep rua flowing and keep reading. Some administrators ramp with pct; support for it varies, so treat it as a nudge rather than a precise dial Two weeks at quarantine with no legitimate mail affected
Week 6+ Move to p=reject, with sp=reject. Keep the reports coming — permanently Done. Revisit whenever you add a system that sends mail, which is the moment this breaks

Once you are at reject and stable, MTA-STS (RFC 8461) and TLS reporting are the sensible next records — they protect mail arriving at your domain rather than mail leaving it. They are a genuine improvement and a much smaller one than what you have just done.

The mistakes we see most

  1. Two SPF records. Almost always because a new provider's setup guide said "add this TXT record" and nobody merged it. The result is a permanent error, and a permanent error protects nobody.
  2. More than ten DNS lookups. Silent, and invisible unless you count. Trim providers you no longer use — the marketing tool from three years ago is still in there.
  3. +all, or a stray ?all. This authorises the whole internet to send as you. It is usually a copy-paste from a troubleshooting thread that was never reverted.
  4. DMARC published, reports going nowhere. p=none with no rua, or a rua pointing at a mailbox nobody has opened since it was created. You have the record and none of the value.
  5. Staying at p=none forever. This is the big one. A domain at p=none is measured, not protected, and a great many businesses stop here believing they are done. Nothing changes for an attacker until the policy is quarantine or reject.
  6. A weaker DMARC record on a subdomain. Subdomains inherit the apex policy unless a record of their own says otherwise, so publishing p=none at booking.yourdomain while the apex is at reject reopens exactly the door you closed.

What about a domain that sends no email?

Old trading names, campaign domains, the misspelling you bought defensively — these are attractive precisely because nobody watches them. Three records, ten minutes, and they can no longer be used to send anything.

A domain that sends and receives nothing
  1. baharicourt-offers.example.   IN  TXT  "v=spf1 -all"

    No server on earth is authorised to send for this domain.

  2. _dmarc.baharicourt-offers.example.  IN  TXT  "v=DMARC1; p=reject; rua=mailto:dmarc@baharicourt.example"

    Reject outright, and still send the reports somewhere you read — you will see attempts.

  3. baharicourt-offers.example.   IN  MX  0 .

    The null MX of RFC 7505: this domain accepts no mail at all. Sending servers stop trying immediately instead of queuing for days.

How do I check what I have today?

Four commands. They read public DNS records, which is the same thing every mail server on the internet does to find you, and they touch nobody's servers.

On macOS or Linux
  1. dig TXT baharicourt.example +short

    Your SPF record — and everything else published as TXT at the apex.

  2. dig TXT _dmarc.baharicourt.example +short

    Your DMARC policy. An empty result is the answer that matters most.

  3. dig MX baharicourt.example +short

    Who handles your mail. This tells you which provider’s DKIM settings to go and enable.

  4. dig TXT google._domainkey.baharicourt.example +short

    A DKIM key, if you know the selector. If you do not, look at the s= tag in the DKIM-Signature header of any mail you have sent yourself.

On Windows: nslookup -type=TXT _dmarc.yourdomain — same answer, different tool.

If reading DNS output is not your idea of an afternoon, our free snapshot reads exactly these records for you and returns a plain-language report on what they say. It is free, a person writes it, and it arrives in one to two business days. We read public records — DNS, mail records, certificate transparency logs and the domain registry. We never connect to your website or servers, never log in, and never test your defences. This is not a penetration test.

Who should do this work?

Whoever controls your DNS: your hosting provider, your domain registrar's control panel, or your IT provider. If you have a competent IT provider, send them this page. Most of what is described here is under an hour of actual change for someone who does it regularly, plus a few weeks of reading reports — and many providers simply have not been asked to look.

If you would rather it were done for you, Reconesys sells this as a fixed-price piece of work — the Email and Domain Shield sprint, USD 199, about KES 25,700 — where we make the records correct, clean up stray DNS entries, and re-check afterwards to show it worked. Prices are in US dollars with the shilling equivalent at about 129 shillings to the dollar; you are billed in shillings.

Start with the free snapshot either way, because it tells you where you actually stand before anyone spends money. See a worked sample report, what the free snapshot covers, or what the fix sprints cost.

One caveat we would rather state than have you assume: fixing your mail records stops other people sending as you. It does not protect a mailbox that has been broken into, it is not monitoring, and it does not make your business compliant with the Data Protection Act — although it is squarely the kind of measure regulation 32 of the General Regulations has in mind.

Questions

Questions people ask about this

What is the difference between SPF, DKIM and DMARC?
SPF is a DNS record listing which servers may send mail using your domain in the envelope sender address. DKIM adds a cryptographic signature to each message, checked against a public key you publish in DNS. DMARC ties both to the From address a recipient actually sees: it tells receiving mail servers what to do when neither SPF nor DKIM passes in alignment with that domain, and asks them to send you reports. SPF and DKIM on their own do not stop anyone putting your domain in the From header — DMARC at p=quarantine or p=reject is the part that does.
What does a good DMARC record look like?
A finished one is a TXT record at _dmarc.yourdomain, reading v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain; fo=1. Start instead at p=none with the same rua address, read the reports for two to four weeks until every legitimate sender passes in alignment, then move to p=quarantine and finally to p=reject. Publishing p=reject on day one will silently stop your own invoices and booking confirmations.
Does SPF stop someone sending email as my business?
Not by itself. SPF authenticates the envelope sender, which is the address used in the SMTP conversation and which recipients almost never see. An attacker can pass SPF for a domain they control while putting your domain in the visible From header. DMARC is what requires SPF or DKIM to pass in alignment with the From domain, and what tells receiving servers to reject the message when neither does.
How long does it take to set up DMARC properly?
The DNS changes themselves take under an hour. The part that takes time is the reporting phase: two to four weeks at p=none, reading the aggregate reports until every legitimate sender — your booking engine, your invoicing tool, your marketing platform — passes in alignment. A typical small business reaches p=reject in six to eight weeks without breaking anything.
Do I need DMARC if my domain does not send any email?
Yes, and it is easier. A domain that sends no mail should publish an SPF record of v=spf1 -all, a DMARC record of v=DMARC1; p=reject with a reporting address, and a null MX record. Unused and parked domains are attractive precisely because nobody is watching them, and the three records above take ten minutes.

Sources

Every legal and statistical claim above traces to one of these. We link to the publisher's own copy rather than to a summary, and name the provision in full so the citation survives a broken link.

Sources

  1. RFC 7208 — Sender Policy Framework (SPF) for Authorizing Use of Domains in Email — IETF

    The record syntax, the qualifiers, the ten DNS-lookup processing limit and the permanent-error behaviour when it is exceeded.

  2. RFC 6376 — DomainKeys Identified Mail (DKIM) Signatures — IETF

    The signature header, the selector, and the public key record published in DNS.

  3. RFC 7489 — Domain-based Message Authentication, Reporting, and Conformance (DMARC) — IETF

    Identifier alignment, the policy and reporting tags, subdomain policy inheritance, and the authorisation record required to send reports to a domain you do not control.

  4. RFC 7505 — A "Null MX" No Service Resource Record for Domains That Accept No Mail — IETF

    The record to publish on a domain that neither sends nor receives email.

  5. RFC 8461 — SMTP MTA Strict Transport Security (MTA-STS) — IETF

    The next step after DMARC, for mail arriving at your domain rather than leaving it.

  6. DMARC overview — dmarc.org

    A vendor-neutral introduction, useful for handing to a colleague.

  7. National KE-CIRT/CC — Communications Authority of Kenya

    Kenya’s national computer incident response team, which publishes the quarterly threat event figures cited above and is the route for reporting incidents.

Read next

Read next