The spoofing report you are already entitled to: who sends mail as your business
One line of DNS turns on a free daily report from every mail provider; this reads it on your own box for EUR 0
- Access to your domain's DNS settings, or someone who will add one TXT record for you
- A written list of every service that sends mail with your name on it - the accounting package, the booking tool, the webshop, the newsletter; the whole exercise is only as good as this list
- A mailbox on your own domain for the reports, and an app password for it
- Any always-on machine with Python; a mini-VPS at EUR 4-6/month if you have none
Version history
Every mail provider on earth will send you a daily report naming every server that sent mail in your company's name. You have to ask for it, in one line of DNS, and then something has to read it. That something costs EUR 0 and runs on a box you already own.
The architecture
the same flow as text
│ you publish this once
▼
[ Google · Microsoft · Yahoo · every other receiver ]
│ one gzipped XML per receiver per day, by email
▼
[ dmarc@yourdomain ] a plain mailbox, nothing special
▼
[ parsedmarc ] reads the mailbox over IMAP, unzips, parses
├─ output: aggregate CSV + JSON → reports/
└─ archives the processed mail, never deletes your evidence
▼
[ 30-line diff script ] sending IPs seen this week vs the known list
▼
[ local model (Ollama) ] one sentence per new sender: who, how much, pass or fail
▼
[ Telegram or email ] + [ reports/ = your dated record ]
Nothing here listens on the public internet. The only inbound thing is a mailbox you already know how to make. The reports folder is the quiet half of the value: when your insurer, your bank or a customer's IT person asks what you did about domain spoofing, a folder of dated CSVs is an answer and a good intention is not.
The problem
Two things are true about your business email and you have no way of seeing either. First: somebody is almost certainly sending mail that claims to come from your domain. The FBI's 2025 Internet Crime Report puts business email compromise at USD 3,046,598,558 across 24,768 complaints — about USD 123,000 per reported case, and the classic version of it is a supplier invoice that arrives from a name your customer trusts. Second: some of your own quotes and invoices are being rejected or filed as spam, and you find out weeks later when a customer says they never got it. Google and Yahoo have enforced authentication for high-volume senders since February 2024; Microsoft joined on 5 May 2025 with a hard 550 5.7.515 rejection. Those rules are aimed at senders above 5,000 messages a day, so as a small business you are not the target — but you are on the same filters, and the same three DNS records decide whether your mail is trusted. In May 2026 the standard itself grew up: the IETF published DMARCbis as RFC 9989, 9990 and 9991, replacing the 2015 document and moving DMARC onto the standards track. What none of that changes is the basic gap. The reports exist, they are free, they arrive daily, and almost nobody reads them because they are compressed XML.
Tool choices — and why
checkdmarc yourdomain.example and it validates your SPF, DKIM and DMARC records and tells you when the SPF record blows past the ten-DNS-lookup limit. Use it the day you publish the record and again every time you add a new service that sends mail for you.Setup outline
- Write down every service that sends mail with your name on it. Your mail provider, your accounting package, your booking tool, your webshop, your newsletter, the contact form on your site, the garage software, whatever your accountant uses to send you documents. This list is the whole job — steps 2 to 9 only tell you whether the list was complete.
- Create a mailbox:
dmarc@yourdomain.example. Nothing clever. It will get a handful of messages a day. - Publish one DNS TXT record at
_dmarc.yourdomain.examplewith the valuev=DMARC1; p=none; rua=mailto:dmarc@yourdomain.example.p=nonemeans "change nothing, just tell me" — it cannot break your mail. That is deliberate and you will stay there for weeks. - Run
checkdmarc yourdomain.exampleand fix whatever it flags in your SPF record before going further. - Wait. The first reports arrive within a day or two, from Google, Microsoft, Yahoo and a long tail of smaller receivers.
- On any always-on box:
pip install parsedmarc, then a smallparsedmarc.iniwith a[mailbox]section pointing at the mailbox (host, user, password,archive_folder) and an[general]section withaggregate_csv_filenameandaggregate_json_filename. Use an app password, not your real one. - Run it by hand once. Open the CSV. You are looking at one row per sending IP per day with counts and pass/fail for SPF and DKIM. Match every IP against your step-1 list.
- Add the cron line — daily is plenty — and keep every output file in a
reports/folder named by date. Never delete them. - Add the diff: a short script holding a text file of known-good sending IPs, comparing this run against it, and messaging you only when something new appears or when a known sender starts failing. Silence is the normal state.
- After four to six weeks of a clean report, tighten to
p=quarantine, then months later top=rejectif your mail flow is simple. Both are real changes to how your mail is treated. Do them on a Tuesday morning, not a Friday evening.
Pitfalls — what goes wrong when you build this
p=none is not caution theatre. It is the only way to find the sender you forgot.include: for a service can eat several. Add one service too many and the whole record turns into a permanent error, which fails everything — including mail you sent yourself. This is why step 4 exists, and why you re-run it every time you add a tool.rua= address is on another domain — your IT person's, say — that domain must publish an authorisation record of the form yourdomain.example._report._dmarc.theirdomain.example with the value v=DMARC1;. Without it, conforming receivers simply do not send the reports, and you sit there for a week thinking nothing arrived.v=DMARC1 valid. It drops the old pct= tag in favour of a plain t=y testing mode, adds np= for subdomains that do not exist, and replaces the Public Suffix List with a DNS tree walk. Nothing to do today. Do not let a vendor tell you your record is "out of date" and sell you a migration.Verified repos
parsedmarc — Apache-2.0, 1,291 stars, last commit 03/09/2026, v11.0.1
checkdmarc — Apache-2.0, 321 stars, last commit 31/08/2026
Ollama — MIT, 180k stars, active (optional, for the plain-language line)
Grafana — AGPL-3.0, 76,568 stars, active (optional trend view, needs a database)
parsedmarc documentation — configuration reference for the mailbox and output sections