This how-to is created by the Dutch Internet Standards Platform (the organization behind [internet.nl](https://internet.nl)) and is meant to provide practical information and guidance on implementing DMARC.
DMARC is short for **D**omain based **M**essage **A**uthentication, **R**eporting and **C**onformance and is described in [RFC 7489](https://tools.ietf.org/html/rfc7489). With DMARC the owner of a domain can, by means of a DNS record, publish a policy that states how to handle e-mail (deliver, quarantine, reject) which is not properly authenticated using SPF and/or DKIM.
At the same time DMARC also provides the means for receiving reports which allows a domain's administrator to detect whether their domainname is used for phishing or spam.
Before DMARC, organizations already took several measures to determine the authenticity of an e-mail (like SPF and DKIM) to reduce the received amount of SPAM to a minimum. This is basically a good thing, but if these measures fail to choose whether or not an email is SPAM with a high level of certainty, the choice is redirected to the addressee (receiving party). This methodology is prone to abuse, since users are generally not equiped with the knowledge and/or means to classify incoming emails.
DMARC addresses this problem and enables the owner of a domain to take explicit responsiblity with regard to the actions taken by the sending party when the validity of an incoming email cannot be determined.
* Parked domain: “DMARC p=reject”. Make sure to include rua and ruf addresses, since this allows monitoring of possible abuse attempts. Implement additional records (SPF, DKIM, NullMX) if possible, see also our [Parked domain how-to](https://github.com/internetstandards/toolbox-wiki/blob/master/parked-domain-how-to.md).
* RFC 7489 [states](https://tools.ietf.org/html/rfc7489#section-6.4) that the tags dmarc-version ("v=") and dmarc-request ("p=") should be on the first and second position of the DMARC record. The order of the other tags does not matter: "components other than dmarc-version and dmarc-request may appear in any order".
* [Errata 5440 of RFC 7489](https://www.rfc-editor.org/errata_search.php?rfc=7489) states that a semicolon should be included in the DMARC version tag. Correct: "v=DMARC1;". Incorrect: "v=DMARC1".
* When using office 365, the forwarding of calendar appointments from a DMARC projected domain fails. This is a known issue. Read more on the [Office 365 UserVoice forum](https://office365.uservoice.com/forums/264636-general/suggestions/34012756-forwarding-of-calendar-appointments-from-a-dmarc-p) and don't forget to submit your vote!
The DMARC policy is published by means of a DNS TXT record. Before setting up a DMARC record, lets first take a look at all the configuration tags that can be configured within a DMARC record.
| p | mandatory | none<br>quarantine<br>reject | None: don't do anything if DMARC verification fails (used for testing)<br>quarantine: treat mail that fails DMARC check as suspicious<br>reject: reject mail that fail DMARC check |
| fo | mandatory | <br>0<br>1<br>s<br>d | Reporting options for failure reports. Generates a report if:<br>- both SPF and DKIM tests fail (0)<br>- either SPF or DKIM test fail (1)<br>- SPF test fails (s)<br>- DKIM test fails (d) |
| adkim | optional | s<br>r | Controls how strict the result of DKIM verification should be intepreted. Strict or relaxed. |
| aspf | optional | s<br>r | Controls how strict the result of SPF verification should be intepreted. Strict or relaxed. |
| pct | optional | 0..100 | Determine percentage of mail from your domain to have the DMARC verificaton done by other mail providers. Default is 100. |
| rf | optional | afrf<br>aodef | Preferred reporting format for forensic reports. Default is afrf. |
| ri | optional | 60..86400 | Interval (in seconds) at which you want to receive DMARC reports. The DMARC RFC specifies that organizations should be able to send reports at least once every day (86400 seconds) and also states a minimum interval of one hour (60 seconds). Default is 86400. |
| sp | optional | none<br>quarantine<br>reject | Subdomain policy. If not set the policy defined under "p=" will apply to all your subdomains. |
Be aware that implementing a DMARC record without a rua configuration is possible, this is not advised because the DMARC XML files that are received by implementing a rua email address can help with implementing DKIM or SPF to meet the DMARC requirements.
Depending on your preferences and needs, you can determine the value of the configuration tags. The values below seem like a good starting point when setting up
For more information about these configuration parameters, take a look at [its man page](https://manpages.debian.org/unstable/opendmarc/opendmarc.conf.5.en.html).
Make sure the file **/etc/opendmarc/ignore.hosts** contains all hosts that you trust. The e-mail coming from these hosts will not be checked by OpenDMARC:
127.0.0.1
localhost
Make sure the default file **/etc/default/opendmarc** contains:
Now we need to tell Postfix to use OpenDMARC as a mail filter in order to use its functionality. This is done by making sure that **/etc/postfix/main.cf** contains the configuration parameters as listed below. Notice that the DKIM check (localhost:12301) is done _before_ DMARC (localhost:54321) since DMARC relies on the DKIM results.
In order to become DMARC compliant, we need to start sending aggregate DMARC reports. Let's start by creating an OpenDMARC database using the provided MySQL script (/usr/share/doc/opendmarc/schema.mysql) in the OpenDMARC package.
In the example below the user root is used to create the new "opendmarc" database. If you would also like to create a user with access to the database, then uncomment the last two lines in the MySQL script and make sure to change the default 'changeme' password into something strong.
mysql -u root -p < /usr/share/doc/opendmarc/schema.mysql
After creation of the database, you need to create an executable Bash script in order to be able to send out reports. Create the file **/etc/opendmarc/report_script** and use the following content:
SpamAssassin uses a scoring mechanism in order to determine if an e-mail should be considered spam. By default SpamAssassin considers an e-mail to be spam if the score at least "5". An e-mail starts with a score of 0 and points are added based on the [tests](https://spamassassin.apache.org/old/tests_3_3_x.html) performed. The tests performed can be configured by adding specific [configuration parameters](https://spamassassin.apache.org/full/3.4.x/doc/Mail_SpamAssassin_Conf.html) in **/etc/spamassassin/local.cf**.
Now here's the tricky part. The points added to the score of an incoming e-mail based on the results of a specific test, is at its core a custom job. Many variables can be taken into consideration when scoring an e-mail (which is considered the strength of a post-SMTP spam filter) and the detailed scoring depends on a domain owner's specific wishes. For the sake of this how-to, the DMARC scoring will be based on the assumption that the domain owner wants to consider an e-mail to be spam if the sending e-mail server's DMARC validation did fail.
With SpamAssassin this can be configured by adding the following scoring configuration parameters to **/etc/spamassassin/local.cf**:
This means that when the "Authentication-Results" header of your e-mail contains "mail.example.nl; dmarc=fail" 5 points will be added to the score; instantly classifying this e-mail as SPAM. On the other hand, if the "Authentication-Results" header of your e-mail contains "mail.example.nl; dmarc=pass" -1 points will be added to the score; classifying this e-mail as legitimate.