If you’re looking for the fastest and easiest way to get DMARC verification working on a RedHat (Fedora, RHEL or CentOS) mail server, I highly recommend OpenDMARC. I’m a bit biased, as I currently maintain the OpenDMARC package in the Fedora and EPEL repositories. This article will help you install the necessary RPMs and then configure OpenDMARC with Postfix or Sendmail.
For general information about DMARC, check out http://dmarc.org/. For more information about the OpenDMARC project, check out http://www.trusteddomain.org/opendmarc/.
Before you start
This tutorial assumes the following:
- You are running a “modern” RedHat-compatible Linux distro (RHEL, CentOS, Fedora, etc).
- You are running a milter-aware MTA, such as Postfix or Sendmail.
- Your Postfix or Sendmail configuration is currently working (this is very important – you don’t want to troubleshoot two programs at once).
- If you’re using Postfix, Sendmail is turned off (do service sendmail status to verify).
- If you’re using Sendmail, Postfix is turned off (do service postfix status to verify).
- The necessary commands in this tutorial are done as root or as a privileged user (with sudo). If you don’t know what that means, then you probably shouldn’t be doing this.
Install OpenDMARC with Yum
If you’re running Fedora 20 (or newer) or RHEL/CentOS 5 (or newer) then you can use Yum to quickly install OpenDMARC (RHEL/CentOS users must have the EPEL repositories enabled). Just do:
yum install opendmarc
This will download and install OpenDMARC with all the default configuration options included below.
For those who like getting their hands dirtier, you can manually download one of my RPMs or even build your own RPM from my Source RPM, which are all available through the Fedora BuildSystem.
Edit the configuration files
On install, the RPM package created a default /etc/opendmarc.conf file with some default options. Use your favorite text editor to open /etc/opendmarc.conf and make the following edits:
Find the # AuthservID name line, uncomment it by removing the #, then replace the word “name” with “HOSTNAME,” like this:
AuthservID HOSTNAME
This will use the hostname of the current system in the Authentication-Results: header field after a message is verified. If you prefer to use a different host’s name, you can state that explicitly here instead. For more information, check out: http://tools.ietf.org/html/rfc7001#section-2.4.
Edit your MTA configuration
Now you’re ready to tell your MTA about OpenDMARC.
Postfix Users:
Telling Postfix about OpenDMARC is easy. Just add the following lines to your Postfix main.cf file:
smtpd_milters = inet:127.0.0.1:8893 non_smtpd_milters = $smtpd_milters milter_default_action = accept
However, if you already another milter running on your system (I recommend also running OpenDKIM), you’ll already have those lines in your Postfix configuration. In the example below, OpenDKIM is already configured on inet:127.0.0.1:8891. Simply add the socket for the OpenDMARC milter to the smtpd_milters line with a comma, in the order you want Postfix to process each milter, like this:
smtpd_milters = inet:127.0.0.1:8891, inet:127.0.0.1:8893 non_smtpd_milters = $smtpd_milters milter_default_action = accept
That configuration will run incoming messages through OpenDKIM first, then OpenDMARC.
It’s merely tradition to use 8891 for OpenDKIM and 8893 for OpenDMARC, you can technically use any port numbers you wish, as long as both the milter and Postfix are configured to use the same. The tradition dates back to when Murray S. Kucheraway (author of OpenDKIM and OpenDMARC) was working at Sendmail, Inc. In his words:
At Sendmail, Inc., for the first commercial milter I ever wrote (which was the first commercial milter ever sold), I used a number like 8885. I can’t remember how it was selected, possibly at random, probably by someone else, but that led to creation of an internal registry of invented port numbers we used for our products to interact. The next one I did was 8886, etc. By the time I wrote dkim-milter, 8891 was next. OpenDKIM inherited it from there, and I just continued the trend. I can’t remember which one got 8892, but 8893 went to OpenDMARC (which I started after leaving Sendmail, of course).
See http://www.postfix.org/MILTER_README.html#version for more info on milter configuration.
But don’t restart Postfix yet! You need to have OpenDMARC running first, or you’ll get errors in your maillog.
Sendmail Users:
Edit the .mc configuration file that was used to build your current sendmail.cf file. Add the following line:
INPUT_MAIL_FILTER(`opendmarc', `S=inet:[email protected]')
If you already have a similar line from OpenDKIM, just add this line below it. Now you can build and install a new sendmail.cf. If you don’t know how to build and install a sendmail.cf file, a quick Web search should shove you in the right direction. Explaining how to do that is beyond the scope of these instructions. I will, however, remind you that backing up your current sendmail.cf file is a good idea before you attempt any modifications.
Start OpenDMARC and restart your MTA
It’s time to fire things up! Assuming you’re using bash, do:
hash -r
to rehash your shell so you can find the init script.
Depending on whether your system uses SysV or systemd, start OpenDMARC with either:
service opendmarc start
or
systemctl start opendmarc
On SysV systems, you should get a message that says:
Starting OpenDMARC Milter: [ OK ]
However, if you get an error message such as:
Starting OpenDMARC Milter: opendmarc: /etc/opendmarc.conf: configuration error at line 6: unrecognized parameter
don’t freak out. You probably just mistyped something in one of the config files. Go to the line number of the file listed, and check your work against the example(s) in this article. Then try starting up OpenDMARC again.
On a systemd system, you can verify that OpenDMARC started properly with:
systemctl status opendmarc
Once you’ve confirmed OpenDMARC has started, restart your MTA. Postfix users should refresh Postfix with:
postfix reload
and Sendmail users should do:
service sendmail restart
If everything looks good, set OpenDMARC to auto-start on boot. SysV users should do:
chkconfig opendmarc on
and systemd users should do:
systemctl enable opendmarc
Testing OpenDMARC Verification
At this point, you’re ready to verify that incoming mail is being verified by taking a peek at your /var/log/maillog file. Do a:
tail -f /var/log/maillog
When OpenDMARC starts (or restarts), look for lines like these:
opendmarc[4737]: OpenDMARC Filter v1.3.1 starting (args: -c /etc/opendmarc.conf -P /var/run/opendmarc/opendmarc.pid) opendmarc[4737]: additional trusted authentication services: hostname.example.com
Send a test message from an external mail account to a valid address on your system. When the inbound message (from gmail.com in the following example) is checked and successfully passes DMARC verification, you’ll see:
opendmarc[2328]: implicit authentication service: hostname.example.com opendmarc[2328]: 52B68148064: gmail.com pass
The 52B68148064 in the above example is the Postfix queue ID, and will be different for every message.
Adding a Public Suffix List
Adding a public suffix list to your OpenDMARC configuration is an optional step, but one I recommend. Doing so will tell OpenDMARC to allow an SPF record for a fully qualified domain name such as “bounce.linkedin.com” to count as valid if the message’s From: domain is the top-level domain (“linkedin.com” in this example). Setting up a public suffix list requires three additional steps:
- Downloading a local copy of Mozilla’s Public Suffix List.
- Editing your /etc/opendmarc.conf file to enable the PublicSuffixList option.
- Scheduling a weekly download of the list to keep it up-to-date.
Download a local copy of Mozilla’s Public Suffix List
First, manually download a copy of Mozilla’s Public Suffix list to your /etc/opendmarc directory with:
/usr/bin/wget --no-check-certificate -q -N -P /etc/opendmarc https://publicsuffix.org/list/effective_tld_names.dat
Now change the ownership of the file to ensure that the opendmarc user can access it with:
chown opendmarc:opendmarc /etc/opendmarc/effective_tld_names.dat
Edit /etc/opendmarc.conf
Next, uncomment the PublicSuffixList option in your /etc/opendmarc.conf file and add the location of your local copy:
PublicSuffixList /etc/opendmarc/effective_tld_names.dat
Restart OpenDMARC to pick up the configuration change.
Schedule a Weekly download to keep the list up-to-date
The Public Suffix List usually changes a few times per month, so add the wget command you used earlier to your crontab to download the latest version every week:
@weekly /usr/bin/wget --no-check-certificate -q -N -P /etc/opendmarc https://publicsuffix.org/list/effective_tld_names.dat #Get latest effective_tld_names for OpenDMARC
Now OpenDMARC is set up to use the Public Suffix List.
Adding DMARC Reporting
Once you’re confident that OpenDMARC is running properly and verifying incoming mail, you have a few additional options for reporting DMARC failures to domain owners (if you choose to do so). The following steps will allow you to collect DMARC-specific data and send nightly reports to domain owners informing them of the DMARC status of messages claiming to be from their domain.
Setting up DMARC reporting requires three additional steps:
- Editing your /etc/opendmarc.conf file to enable a History File location.
- Setting up a MySQL DB to import data from the History File.
- Writing a script to import the data from your host’s the history file, erase the history file, and email the reports according to the domains DMARC TXT record.
Edit /etc/opendmarc.conf
Uncomment the following line in your /etc/opendmarc.conf file.
HistoryFile /var/run/opendmarc.dat
That option specifies a location of a text file to which records are written that can be used to generate DMARC aggregate reports. Be sure to restart OpenDMARC once you’ve made the changes.
Set up the MySQL database
Next, you’ll need a MySQL database that can import the data from the opendmarc.dat file and allow the scripts included with OpenDMARC to send failure reports to domain owners. The following commands will create a new database and user (both named opendmarc) to store the imported DMARC data:
# mysql -p mysql> CREATE DATABASE opendmarc; mysql> GRANT ALL PRIVILEGES ON opendmarc.* TO opendmarc IDENTIFIED BY 'secretpassword'; mysql> quit;
Now import the default schema provided by the OpenDMARC package with:
# mysql -h localhost -u opendmarc -p opendmarc < /usr/share/doc/opendmarc-1.3.1/schema.mysql
If you’re using a newer version of OpenDMARC than 1.3.1, use the appropriate directory name in the above command.
Create a processing script that runs daily
Finally, create a script in /usr/local/bin called something like opendmarc-send-reports.sh that will import the data from opendmarc.dat into your database, process and send the reports, then erase the contents of the opendmarc.dat file:
Edit your crontab and include a line like this to run the script daily:
@daily /usr/local/bin/opendmarc-send-reports.sh #Send nightly DMARC reports
Now you’ll be sending daily DMARC reports to domain owners who ask for them. But if you operate a mail server that receives lots mail, you may want to consider processing and sending the reports hourly, to prevent the opendmarc.dat file from growing too large.
For more advanced setups where there might be multiple mail servers running OpenDMARC with single MySQL host doing all the processing, the following script is a good starting point for processing multiple remote opendmarc.dat files, combining them, and sending out daily reports:
In addition to these reports, OpenDMARC supports a separate feature called FailureReports, which can generate an individual email report on every failure. However, I don’t recommend playing with this unless you really need it, and are an advanced user, since it can cause serious backscatter problems with your mail server if improperly configured.
lispf2 SPF Library Support
As of version 1.3.1-11, the opendmarc package available in the Fedora repositories is built against the libspf2 SPF library, so that OpenDMARC’s “internal” SPF checks are actually being performed by the libspf2 library.
Troubleshooting
If you’re having any trouble setting up or working with OpenDMARC, I highly recommend subscribing to the OpenDMARC-Users discussion list at http://www.trusteddomain.org/mailman/listinfo/opendmarc-users. It’s a low-traffic list with very helpful and friendly members (including me!) who are happy to nudge you in the right direction.
Further reading
- DMARC.org – the official site for DMARC
- dmarcian – The best suite of online DMARC tools I’ve found.
- Trusted Domain Project Site – the project responsible for bringing you OpenDMARC
- Hamzah Khan’s Blog – A helpful blog post about configuring OpenDMARC. It’s slightly outdated, but only because it’s relying on an older version of OpenDMARC with different config options. This post was also the starting point for the processing scripts used in this article.
- libspf2 Project Site – Source code and information about the libspf2 SPF Library
- My OpenDMARC GitHub repo – if you’d like to mess with the SPEC file or patches that I use to create the OpenDMARC package in the Fedora & EPEL repos, knock yourself out! Please fork the “develop” branch and submit your pull requests there, as the “master” is intended only for release versions.
Good luck! Please post in the comments with your successes, (non support) questions, or suggestions. Support should be directed to the OpenDMARC-Users discussion list.