Table of Contents

Networking - DNS - Bind - DMARC (Domain-based Message Authentication Reporting and Conformance)

DMARC is built upon two other authentication protocols:

A DMARC policy allows a sender to indicate that their messages are protected by SPF and/or DKIM, and tells a receiver what to do if neither of those authentication methods passes – such as junk or reject the message.

The receiver will look to the established policy to make a determination on where to filter mail.

So DMARC requires one or the other, though it makes it easier to fail if SPF and DKIM aren't both implemented.


DNS config

DMARC-policies are published as TXT records, in DNS.

The basic record looks like this:

_dmarc.example.com. IN TXT "v=DMARC1; p=reject; adkim=s; aspf=s; fo=1; rua=mailto:postmaster@example.com"

Lookup DMARC record

Use dig or nslookup.

dig -t txt  _dmarc.example.com +short

DMARC tags

DMARC tags tell the email receiver to

  1. Check for DMARC and
  2. What to do with messages that fail DMARC authentication.
Tag NameRequiredPurposeSample
vrequiredProtocol versionv=DMARC1
prequiredPolicy for domainp=quarantine
pctoptional% of messages subjected to filteringpct=20
ruaoptionalReporting URI of aggregate reportsrua=mailto:aggrep@example.com
rufoptionalReporting URI of failure reportsruf=mailto:domain@example.com
spoptionalPolicy for subdomains of the domainsp=reject
aspfoptionalAlignment mode for SPFaspf=r
adkimoptionalAlignment mode for DKIMadkim=r
fooptionalFailure reports optionsfo=0
rfoptionalFailure report formatrf=ATRF

v: Version

This tag is used to identify the TXT record as a DMARC record, so email receivers can distinguish it from other TXT records.

The v: tag must have the value of “DMARC1” and it must be listed as the first tag within the entire DMARC record.

If the value doesn't exactly match “DMARC1” or the v: tag is not listed first, the entire DMARC record will be ignored by the receiver.

Example:

v=DMARC1

p: Requested Mail Receiver Policy

This tag indicates the policy to be enacted by the receiver for messages that fail DMARC authentication and alignment checks, as specified by the domain owner.

This policy will apply to the domain queried and to all subdomains unless a separate subdomain policy is explicitly described.

It must be the second tag within the entire DMARC record.

There are three possible values for the p: tag.

Given the information above, the most basic DMARC record example could be:

v=DMARC1; p=none

rua: Reporting URI of aggregate reports (Optional)

Indicates where aggregate DMARC reports should be sent to.

Senders designate the destination address in the following format:

rua=mailto:domain@example.com.

If not present aggregate reports will not be sent from the receiving MTA.

Where a mailto address lies within the sending zone no additional configuration is required, however if the mailto address lies outside the sending zone an additional empty DMRC RR is required.

Thus, if the email sending zone is example.net and the DMARC TXT RR contains the parameter rua=mailto:dmarc-admin@example.net this lies inside the sending zone and no additional configuration is required.

If, however the email sending zone is example.net and the DMARC TXT RR in the zone file for example.net contains the parameter rua=mailto:dmarc-admin@example.com this lies outside the sending zone and the zone example.com must validate that it will accept reports for the example.net domain by having the following minimal DMARC TXT RR:

# example.com zone file fragment
$ORIGIN example.com.
...
# Authorizes the receiving of DMARC reports for example.net.
example.net._report._dmarc     TXT  "v=DMARC1"

ruf: Reporting URI of failure reports (Optional)

Indicates where forensic DMARC reports should be sent to.

Senders designate the destination address in the following format:

ruf=mailto:domain@example.com.

The addresses is a comma separated list of DMARC URIs used in conjunction with the fo key.

Where a mailto address is lies with the sending zone no additional configuration is required, however if the mailto address lies outside the sending zone an additional empty DMRC RR is required.

Thus, if the email sending zone is example.net and the DMARC TXT RR contains the parameter ruf=mailto:dmarc-admin@example.net this lies inside the sending zone and no additional configuration is required.

If, however the email sending zone is example.net and the DMARC TXT RR in the zone file for example.net contains the parameter ruf=mailto:dmarc-admin@example.com this lies outside the sending zone and the zone example.com must validate that it will accept reports for the example.net domain by having the following minimal DMARC TXT RR:

# example.com zone file fragment
$ORIGIN example.com.
...
# authorises the receiving of DMARC reports for example.net
example.net._report._dmarc     TXT  "v=DMARC1"

adkim: DKIM identifier alignment

Indicates strict or relaxed DKIM identifier alignment.

The default is relaxed.

In strict mode the sender domain name must exactly match the corresponding d=name (in the DKIM mail headers).

In relaxed mode any subdomain of d=domain (in the mail headers) will also be accepted.

Thus if d=example.com in the mail header then mail from user@example.com will pass from either adkim = r or adkim=s, however, mail from user@a.example.com will fail if adkim=s but pass if adkim=r.


aspf: Alignment mode for SPF

Indicates strict or relaxed SPF identifier alignment.

The default is relaxed.

In strict mode the domain.name in the MAIL FROM command (in SMTP) and the from: header (in the mail item) must match exactly.

In relaxed mode any valid subdomain of domain.name is acceptable.


rf: Report Format (Optional)

Format used for the message-specific failure reports expressed as an optional comma-separated list of values.

The two accepted formats are

Note that receivers can define other formats, albeit this should be a rare occurrence as most operations are embracing ARF as the reporting format of choice.

The default is Authentication Failure Reporting Format, or “AFRF”.


ri: Reporting Interval (Optional)

The number of seconds elapsed between sending aggregate reports to the sender.

The default value is 86400 seconds or a day. This is the value that is most commonly supported. Higher frequencies are accommodated on a best-effort basis.

Implicitly anything less than 1 hour (3600) can be rounded up to 1 hour by the receiving MTA.


pct: Percentage of messages to which the DMARC policy is to be applied (Optional)

Defines the percentage of mail to which the DMARC policy applies.

If omitted defaults to pct=100 (100%) - all mail is subject to DMARC processing.

This parameter allows mail senders to experiment with a small percentage of mail being subject to DMARC action. Problems can be progressively eliminated from the system before turning DMARC on for all mail.

The specification does not mandate how to calculate this percentage. Instead, it suggests that a common way to implement this at the receiver side, is to use the value as a probability that the message is subjected to the DKIM checks.


fo: Failure reports options (Optional)

Dictates what type of authentication and/or alignment vulnerabilities are reported back to the Domain Owner.

There are four values to the latter fo: tag:

While the default is “fo=0,” Return Path advises clients to use fo:1 to generate the most comprehensive failure reports, providing that much more granular visibility into the email channel.

Defines the error reporting policy the sending MTA requests from the receiving MTA. Multiple options may be defined using colon (:) separated values, for example, fo=0:s.


sp: Subdomain Policy (Optional)

If sp= is present it indicates the defined policy that applies to subdomains. It follows the syntax of the p tag.

There are three possible values for the sp: tag.

For example

_dmarc  IN TXT "v=DMARC1;p=reject;sp=quarantine"

Failed mail from user@example.com would be rejected but mail from user@a.example.com or user@b.a.example.com or user@anything.example.com would be quarantined.


What about sub-domains?

The sp: tag is used to indicate a requested policy for all subdomains where mail is failing the DMARC authentication and alignment checks. This tag is only applicable to top-level domains (organizational level domains). It is most effective when a Domain Owner wants to specify different policy for the top-level domain and all subdomains.

For the following scenarios, we will use the top-level domain of “domain.com” and the sub-domain of “mail.domain.com” to illustrate the use cases.

  1. The Domain Owner wants to enforce a reject policy for “domain.com,” but a quarantine policy for “mail.domain.com” (and all other subdomains).
    • The DMARC record for “domain.com” would then include “v=DMARC1; p=reject; sp=quarantine.”
    • This is an effective strategy if the organization needs to maintain separate DMARC policy for the top-level domain and all subdomains.
  2. Domain Owner wants to enforce a reject policy for “mail.domain.com” (and all other subdomains) but not enforce a reject policy for “domain.com.”
    • The DMARC record for “domain.com” would then include “v=DMARC1; p=none; sp=reject.”
    • This would be an effective strategy to combat dictionary attacks in the event that the top-level domain isn't ready to enforce policy, but the fraudsters are spoofing subdomains like mail.domain.com, abc.domain.com, 123.domain.com, xyz.domain.com, etc.
    • Setting the sp: tag to reject will protect the organization from these dictionary attacks targeting subdomains without impacting any of the mail sent from the top-level domain, “domain.com”

Create a DMARC record in monitor mode

v=DMARC1; p=none; fo=1; rua=mailto:dmarc_agg@auth.example.com;ruf=mailto:dmarc_afrf@auth.example.com

With DMARC in monitor mode, you can gather the information on your entire email ecosystem, including who is sending email on behalf of your brand, what emails are getting delivered, and what emails are not.

Request to receive the daily aggregate and forensic reports by specifying your email address in the rua tag and the ruf tag, respectively. Use the email address(es) you identified in step three above.


Deploy Slowly

It is strongly recommended to ramp up DMARC use slowly by employing these policies in this order.

First, monitor your traffic and look for anomalies in the reports, such as messages that are not yet being signed or are perhaps being spoofed.

Then, when you're comfortable with the results, change the TXT record policy setting from “none” to “quarantine.” Once again, review the results, this time in both your spam catch and in the daily DMARC reports.

Finally, once you're absolutely sure all of your messages are signed, change the policy setting to “reject” to make full use of DMARC. Revisit reports to ensure your results are acceptable.

Similarly, the optional pct tag can be used to stage and sample your DMARC deployment. Since 100% is the default, passing “pct=20” in your DMARC TXT record results in one-fifth of all messages affected by the policy actually receiving the disposition instead of all of them. This setting is especially useful once you elect to quarantine and reject mail. Start with a lower percent and increase it every few days.

A conservative deployment cycle would resemble:

Monitor all.
Quarantine 1%.
Quarantine 5%.
Quarantine 10%.
Quarantine 25%.
Quarantine 50%.
Quarantine all.
Reject 1%.
Reject 5%.
Reject 10%.
Reject 25%.
Reject 50%.
Reject all.

Attempt to remove the percentages as quickly as possible to complete the deployment.

As always, review your daily reports.


Examples

v=DMARC1; p=reject; fo=1; rua=mailto:domain@example.com; ruf=mailto:domain@example.com; rf=afrf; pct=100

Choose how you want recipient servers to handle email from your domain that fails SPF/DKIM validation. Options are outlined below in red:

None: "v=DMARC1; p=none; sp=none; rf=afrf; pct=100; ri=86400"
Reject: "v=DMARC1; p=reject; sp=none; rf=afrf; pct=100; ri=86400"
Quarantine: "v=DMARC1; p=quarantine; sp=none; rf=afrf; pct=100; ri=86400"

Alternately, you can request an email report of failed DMARC validations by adding a valid email address, such as the following:

None: "v=DMARC1; p=none; sp=none; ruf=mailto:user@example.com; rf=afrf; pct=100; ri=86400"
Reject: "v=DMARC1; p=reject; sp=none; rf=afrf; pct=100; ruf=mailto:user@example.com; ri=86400"
Quarantine: "v=DMARC1; p=quarantine; sp=none; ruf=mailto:user@example.com; rf=afrf; pct=100; ri=86400"

Single Domain Name using DKIM and SPF - Aggressive

This is an aggressive policy and should only be adopted where the sender is certain that both DKIM and SPF are correctly configured. Not for the faint-hearted.

Assume the domain example.net only sends mail in the form user@example.net (mail is not sent from any subdomain) and that both DKIM and SPF are used in relaxed format. The domain owner wishes to have a daily aggregate report from mail receivers (in Abuse Report format - RFC 5965) of any problems at the address dmarc-admin@example.com if either SPF or DKIM fails, suggests that mail failing any checks should be rejected and that 100% of mail should be checked.

The following addition to example.net's zone file implements such a policy:

# example.net zone file fragment
$ORIGIN example.net.
...
_dmarc   TXT ( "v=DMARC1;p=reject;sp=reject;pct=100;"
   "adkim=r;aspf=r;fo=1;ri=86400;rua=mailto:dmarc-admin@example.com")
 
# NOTE: since the required email address is out-of-zone the 
# following change to the zone file for example.com must be made
# example.com zone file fragment
$ORIGIN example.com.
...
example.net._report._dmarc   TXT "v=DMARC1"
# functionally identical
example.net._report._dmarc.example.net.   TXT "v=DMARC1"
...

Strictly, the adkim=, aspf=, ri= and pct= are not necessary since their defaults are used. However, explicit use of defaults is good defensive configuration policy, and can prevent catastrophic errors in the event that a default is subsequently changed. The use of an out-of-zone email address requires an additional change in the report receivers zone file (example.com in this case) to authorize the reports from the example.net organizational name.


Single Domain Name using DKIM and SPF - Timid

This is a timid (or cautious if you prefer) policy where the sender is discovering the real pathology of their mail service and is unsure (or has no idea) if either DKIM and SPF are correctly configured.

Assume the domain example.net only sends mail in the form user@example.net (mail is not sent from any subdomain) and that both DKIM and SPF are used in relaxed format. The domain owner wishes to have a daily aggregate report from mail receivers (in Abuse Report format - RFC 5965) of any problems at the address dmarc-admin@example.net if either SPF or DKIM fails, does not want the receiver to reject any failing mail and suggests that only 10% of mail should be checked.

The following addition to example.net's zone file implements such a policy:

# example.net zone file fragment
$ORIGIN example.net.
...
_dmarc   TXT ( "v=DMARC1;p=none;sp=reject;pct=10;"
   "adkim=r;aspf=r;fo=1;ri=86400;rua=mailto:dmarc-admin@example.net")

Strictly, the adkim=, aspf=, ri= and pct= are not necessary since their defaults are used. However, explicit use of defaults is good defensive configuration policy.


Single Domain Name using SPF only - Aggressive

This is an aggressive policy and should only be adopted where the sender is certain that SPF is correctly configured.

Assume the domain example.net only sends mail in the form user@example.net (mail is not sent from any subdomain) and that only SPF is used in relaxed format. The domain owner wishes to have a daily aggregate report from mail receivers (in Abuse Report format - RFC 5965) of any problems at the address dmarc-admin@example.net if SPF checks fail, suggests that all mail failing the SPF checks should be rejected and that 100% of mail should be checked.

The following addition to example.net's zone file implements such a policy:

# example.net zone file fragment
$ORIGIN example.net.
...
_dmarc   TXT ( "v=DMARC1;p=reject;sp=reject;pct=100;"
   "aspf=r;fo=0;ri=86400;rua=mailto:dmarc-admin@example.net")

Strictly, the aspf=, ri= and pct= are not necessary since their defaults are used.

However, explicit use of defaults is good defensive configuration policy. It is the presence or absence of either DKIM headers or an SPF RR tested when the mail arrives at the receiver that determine which mail security method is in use rather than the configuration of the DMARC RR. In this case we have eliminated the adkim= to make the actual policy explicit and, since only SPF is in operation, fo=0. The same functional result would have ocurred if adkim=r had been retained and fo=1 as in Example 1 above.

If only DKIM was being used adkim=r would have been added and aspf=r removed - but again the previous comment also applies - it is the received mail that determines which checks are invoked not the DMARC RR.


No mail

This is a supreme act of good neighborliness.

Assume the domain never sends email.

The presence of a DMARC is good practice since mail could be forged with the domain's name.

There is, however, no way to explicitly configure a DMARC RR to indicate that mail will never to sent from this domain.

Again this emphasis the point that DMARC processing is only invoked once the incoming mail protection mechanisms have been discovered.

To indicate that a domain will never send mail must be done with a DMARC RR AND a dummy SPF TXT RR as shown:

# example.net zone file fragment
$ORIGIN example.net.
...
# negative (or dummy) SPF RR
example.net. TXT "v=spf1 -all"
...
_dmarc   TXT "v=DMARC1;p=reject;sp=reject;pct=100;aspf=s"

In this case the DMARC is simply saying reject any mail from this domain that fails the SPF check and the SPF TXT RR, by use of the -all ensures that all mail fails the SPF test. Net result - no mail is allowed to be sent from this domain name.


References

https://dmarc.org/resources/deployment-tools/