Email·7 min read·

Enforcing DMARC: Transitioning from Monitoring to Reject with Aggregate Reports

Safely advance your domain's DMARC policy from p=none to p=reject without dropping legitimate transactional emails using automated RUA report analysis.

NB

Netbay Infrastructure Team

Netbay Engineering

On this page

DMARC (Domain-based Message Authentication, Reporting, and Conformance) is the final arbiter of email sender identity. While SPF specifies which IP addresses are authorized to send mail and DKIM cryptographically signs message contents, only DMARC links those checks directly to the visible RFC 5322 From header displayed to users in email clients.

Jumping directly to p=reject on day one is catastrophic: legitimate third-party transactional providers (such as GitHub, Zendesk, or billing gateways) will have their emails dropped if their SPF or DKIM alignment is not configured beforehand. The proven path to DMARC enforcement is a three-stage rollout backed by automated XML aggregate report (RUA) processing.

The core concept that causes confusion in DMARC implementation is Identifier Alignment. SPF verifies the RFC 5321 Return-Path (envelope sender), while DKIM verifies the domain specified in the d= tag of the cryptographic signature. An attacker can easily send an email with their own malicious Return-Path (passing SPF) while forging your domain in the visible From: header. DMARC closes this loophole by requiring that either the SPF-authenticated domain or the DKIM-signing domain matches the domain in the From: header. In relaxed alignment (the default), subdomains match the organizational domain; in strict alignment, exact domain matching is enforced.

Expand
DMARC Policy Enforcement
DMARC policy enforcement and XML aggregate reporting

Stage 1: Publishing a Monitoring Policy (p=none)

Publish the initial monitoring record at _dmarc.example.com. This instructs receiving servers to evaluate SPF and DKIM without rejecting any messages, while sending daily XML aggregate reports:

DMARC Policy Enforcement Progression & Alignment Matrix Stage 1: Monitoring p=none; pct=100 Collect RUA XML reports Zero message drops Stage 2: Quarantine p=quarantine; pct=50 Suspect mail to spam folder Ramp pct to 100% Stage 3: Reject p=reject; pct=100 Unauthenticated mail dropped Spoofing eliminated DMARC Alignment Rule: A message passes DMARC if EITHER SPF aligns with the visible From: header domain OR DKIM aligns with the visible From: header domain. Both mechanisms working in concert ensure robustness.
dns
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-rua@example.com; ruf=mailto:dmarc-ruf@example.com; fo=1; aspf=r; adkim=r;"

Tags explained:

  • **p=none:** Monitoring mode only. No delivery actions taken on failures.
  • **rua:** Destination email address for daily XML aggregate reports.
  • **aspf=r & adkim=r:** Relaxed alignment mode (subdomains match parent domain).
  • **fo=1:** Generates forensic failure reports if either SPF or DKIM fails.

Stage 2: Parsing RUA Aggregate Reports with Python

Mailbox providers (Google, Microsoft, Yahoo) send zipped XML reports containing source IPs, message counts, and alignment results. The following Python script scans aggregate XML reports to identify unauthenticated IP addresses sending as your domain:

python
#!/usr/bin/env python3
import xml.etree.ElementTree as ET
import gzip
import sys

def parse_dmarc_report(filename):
    opener = gzip.open if filename.endswith('.gz') else open
    with opener(filename, 'rt') as f:
        tree = ET.parse(f)
        root = tree.getroot()

    org = root.findtext('report_metadata/org_name')
    print(f"--- DMARC Report from {org} ---")

    for record in root.findall('record'):
        ip = record.findtext('row/source_ip')
        count = record.findtext('row/count')
        disposition = record.findtext('row/policy_evaluated/disposition')
        spf = record.findtext('row/policy_evaluated/spf')
        dkim = record.findtext('row/policy_evaluated/dkim')

        if spf != 'pass' or dkim != 'pass':
            print(f"ALIGNMENT ISSUE: IP={ip} Count={count} Disp={disposition} SPF={spf} DKIM={dkim}")

if __name__ == '__main__':
    if len(sys.argv) > 1:
        parse_dmarc_report(sys.argv[1])

Reviewing these reports for two to three weeks reveals every SaaS integration, newsletter tool, and internal script that sends email on your domain's behalf. Update your DNS SPF record and DKIM keys to ensure all legitimate services pass alignment.

Stage 3: Escalating to Quarantine and Hard Reject

Once you have verified that 100 percent of your legitimate outbound traffic originates from authenticated systems, advance the policy to quarantine:

dns
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=50; rua=mailto:dmarc-rua@example.com;"

The pct=50 parameter applies the quarantine policy to 50 percent of failing messages while allowing the remaining 50 percent through, providing a gradual safety net. After 7 days without user complaints, advance to full rejection:

dns
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; pct=100; rua=mailto:dmarc-rua@example.com; aspf=r; adkim=r;"

With p=reject in place, any phishing attempt or unauthorized server impersonating your domain is rejected at SMTP connection time by all major email providers.

Enforcing DMARC protects your brand reputation and seals off domain spoofing permanently.

DMARC Policy Enforcement Guide
YouTube

You can spin up an Ubuntu 24.04 instance on Netbay in under 60 seconds with Intel Xeon Platinum compute and high-speed SSD storage in Lucknow — netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance