WhyDMARC adds what SPF and DKIM lack: a published policy telling receivers what to do with failing mail (deliver, quarantine or reject), and alignment — the authenticated domain must match the From: address the reader actually sees.

See also

Policies are a ramp, not a setting: publish p=none first and read the reports, move to p=quarantine once every legitimate source authenticates, and end at p=reject. A domain taken straight to reject silently loses whichever mail stream was forgotten — and it stays lost until someone thinks to suspect the DNS.

Configuration

The policy is a TXT record at _dmarc under the domain. The minimal useful record names a policy and an address for aggregate reports:

_dmarc     IN  TXT  "v=DMARC1; p=Policy; rua=mailto:Report address"

Receivers apply the policy to mail whose From: domain is example.com and which produced no aligned SPF or DKIM pass. Subdomains inherit the policy unless a separate one is published for them (sp= overrides the inherited value).

If the report address lives in another domain, that domain must consent to receiving the reports by publishing an authorization record in its zone; without it, reporters drop the reports on the floor:

Policy domain._report._dmarc  IN  TXT  "v=DMARC1"

Alignment

A DMARC pass needs one of the two underlying proofs to pass for the right domain:

Forwarding breaks SPF — the forwarder’s address is not in the record — but a DKIM signature survives any relay that does not rewrite the body, which is why a domain that sends real mail should have both proofs in place before its policy leaves p=none.

One policy per kind of domain

A mail installation rarely serves one domain. Before writing records, classify each domain against the mail server’s own configuration — the virtual alias map is the authority on which names still receive mail, and reply habits decide which names still send:

The sending domain
Full SPF record, DKIM signing, and the policy ramp described above.
Receive-only domains (aliases that may be replied from)
A domain whose addresses only receive can still appear as a sender the day someone answers from that identity. Publishing the same SPF host list as the sending domain keeps such replies aligned when they leave through the domain’s own relay, while third parties still fail. Such a domain enters the ramp at quarantine rather than none: its legitimate stream is too thin for reports to prove anything in reasonable time, and quarantine is recoverable — a wrongly failed reply lands in a spam folder instead of vanishing:
           IN  TXT  "v=spf1 a:mrelay1.example.com -all"
_dmarc     IN  TXT  "v=DMARC1; p=quarantine"
Domains that never send
A parked domain, or one kept only for its web presence, gets the lockdown pair — nothing may send, failures are rejected outright, and no ramp is needed since there is no legitimate stream to lose:
           IN  TXT  "v=spf1 -all"
_dmarc     IN  TXT  "v=DMARC1; p=reject"

Verification (inbound)

Inbound, the published policies are enforced by opendmarc (mail/opendmarc), a milter that reads the From: domain’s record, checks alignment and applies the verdict. It consumes the Authentication-Results header written by OpenDKIM, so it must come after it in the milter chain; built with the port’s SPF option (the default) it evaluates the SPF leg itself, so no separate inbound SPF checker is needed:

opendmarc_enable="YES"
smtpd_milters =
    unix:/var/run/milteropendkim/sock,
    inet:localhost:8893,
    ...

The behaviour is set in /usr/local/etc/mail/opendmarc.conf (the port’s sample already points PublicSuffixList at the installed public-suffix list, which alignment checking needs):

AuthservID                 Server name
TrustedAuthservIDs         Server name
SPFSelfValidate            true
IgnoreAuthenticatedClients true
RejectFailures             true

RejectFailures makes the milter apply a p=reject published by the sender’s domain at SMTP time; left at its default (false) the verdict is only recorded in Authentication-Results, where SpamAssassin can weigh it.