Keep DMARC reports on infrastructure you control

GUIDE · DMARC AGGREGATE (RUA) REPORTS · OWN MAILBOX OR SELF-HOSTED

The rua= tag in your DMARC record tells receiving mail servers where to send daily aggregate reports. Each report lists the IP addresses that sent mail as your domain, how many messages, and whether SPF and DKIM passed. Where those reports go is a choice you make in DNS. This guide shows how to keep them on a mailbox or server you run, then read them offline.

What we observe

When we scan DMARC records, many point rua= at an address on another organisation's domain, usually a reporting service. That works, and it is a common, valid set-up. It also means a copy of your mail-flow data is processed there. If your organisation prefers that data to stay on its own systems, for example to keep the list of processors short, the steps below move it without a gap in reports.

Check your current record with the free scanner: it shows the published rua= addresses and flags reporting destinations outside your domain.

Option 1: a mailbox on your own domain

The simplest set-up. Create a dedicated mailbox (or a shared mailbox) such as [email protected] and point rua= at it:

_dmarc.example.com.  3600  IN  TXT  "v=DMARC1; p=none; rua=mailto:[email protected]; fo=1"
  • Use the mailbox for reports and nothing else, so a mail rule can file the attachments (.xml.gz or .zip).
  • Set a retention period that matches your records policy; 13 months covers a year-on-year comparison.
  • No extra DNS record is needed when the mailbox is on the same domain as the DMARC record.

Option 2: a self-hosted parsedmarc instance

parsedmarc is an open-source Python tool (install it from the Python Package Index) that reads a reports mailbox over IMAP (or a folder of report files), parses aggregate and SMTP TLS reports, and writes JSON and CSV that you keep on your own server. A minimal configuration:

python3 -m pip install parsedmarc

# /etc/parsedmarc.ini  (readable by the service account and no one else)
[general]
save_aggregate = True
save_smtp_tls = True
output = /var/lib/parsedmarc

[imap]
host = mail.example.com
user = [email protected]
password = (from your secrets store)

[mailbox]
watch = True

Run it as a service (parsedmarc -c /etc/parsedmarc.ini). Keep the mailbox password out of version control, and check the project's documentation for the options your version supports.

Option 3: read the reports offline

Whichever mailbox you use, save the report attachments into a folder and open them with the FaultyPacket Local RUA Workbench (£15): one offline HTML file plus a Python CLI. It shows pass and fail by day, top sending sources, DKIM and SPF alignment, failure reasons and senders not seen in earlier imports. The page blocks every network connection, so the reports never leave your computer. Our guide on reading a DMARC aggregate report explains the XML fields if you prefer to read them by hand.

Moving over without a gap

  1. Create a dedicated mailbox on your own domain, for example [email protected], used for nothing else.
  2. Add it to the rua= tag next to the current address, so reports go to both for two to four weeks.
  3. Check that reports arrive and read them locally (mailbox attachments, or a self-hosted parsedmarc instance).
  4. Compare the two sets of reports, then remove the external address from rua=.
  5. Re-scan the domain to confirm the published record.

During the overlap the record lists two addresses, separated by a comma:

_dmarc.example.com.  3600  IN  TXT  "v=DMARC1; p=none; rua=mailto:[email protected],mailto:[email protected]; fo=1"

If the second address is on another domain, that domain must publish the authorisation record shown in the questions below, or receivers skip it. Most reporting services already publish one for their customers.

Related: SMTP TLS reports

TLS-RPT reports (RFC 8460) work the same way: the rua= in your _smtp._tls record decides where they go. See setting up a TLS-RPT record. parsedmarc and the Local RUA Workbench both read them.

Questions

Is an external reporting address a problem?
Not in itself. It is a common, valid set-up. It does mean the reports, which list the IP addresses and message volumes of mail sent as your domain, are processed outside your own systems. Some organisations prefer to keep that in-house; this guide is for them.
Do I need an authorisation record?
Not when the rua= address is on the same domain as the DMARC record. When it is on a different domain, that domain has to publish a record such as example.com._report._dmarc.example.net TXT "v=DMARC1" (RFC 7489 section 7.1), or receivers skip it.
How much mail will the mailbox get?
Roughly one compressed report per receiving organisation per day for each domain. A small business usually sees a handful a day; a busy sender can see dozens.
What about forensic (ruf=) reports?
Few receivers send them, and they can contain message headers. If you keep ruf=, point it at the same controlled mailbox and set a short retention period.