Linux Uptime

Installing OpenDMARC RPM via Yum with Postfix or Sendmail (for RHEL / CentOS / Fedora) 13

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 For more information about the OpenDMARC project, check out

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:


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:

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 file:

smtpd_milters           = inet:
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: 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:, inet:
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 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 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 If you don’t know how to build and install a 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 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


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[4737]: additional trusted authentication services:

Send a test message from an external mail account to a valid address on your system. When the inbound message (from in the following example) is checked and successfully passes DMARC verification, you’ll see:

opendmarc[2328]: implicit authentication service:
opendmarc[2328]: 52B68148064: 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 “” to count as valid if the message’s From: domain is the top-level domain (“” in this example). Setting up a public suffix list requires three additional steps:

  1. Downloading a local copy of Mozilla’s Public Suffix List.
  2. Editing your /etc/opendmarc.conf file to enable the PublicSuffixList option.
  3. 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

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 #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:

  1. Editing your /etc/opendmarc.conf file to enable a History File location.
  2. Setting up a MySQL DB to import data from the History File.
  3. 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 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/ #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.


If you’re having any trouble setting up or working with OpenDMARC, I highly recommend subscribing to the OpenDMARC-Users discussion list at 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

  • – 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.

  • Pingback: Securing Your Postfix Mail Server with Greylisting, SPF, DKIM and DMARC and TLS - Hamzah Khan's Blog()

  • Andy

    Hi Steve,

    Thanks for the informative post. I have a few questions.

    Regarding the postfix configuration — what’s the benefit of including opendmarc in non_smtpd_milters?

    Regarding FailureReports: I have found that certain malformed dmarc records have ruf=mailto: where is an invalid email address. This can result in an infinite loop if the email is rejected, and the reject also appears to have a dmarc error. As a result, I have this set to false. Have you not encountered any problems like this? The aggregate reports are also sometimes undeliverable, but the consequences of such a failure are not severe.

    Regarding SPF: the builtin capability in opendmarc is nice, but it is less configurable than a standalone filter such as smf-spf. Some email forwarding services to not work properly with SPF, and I have found the smf-spf whitelisting features to be useful. Is there any plan to add such SPF whitelisting features to opendmarc?


    • Hi, Andy. No benefit re:non_smtpd_milters beyond that it lets me remain lazy about only having to update one config line. 🙂 OpenDKIM needs to be there, because it has to act on mail that comes in via the pipe rather than SMTP, but OpenDMARC only verifies arriving mail. There’s no adverse affect to it being in there, so it’s just me being lazy in the config file. 🙂

      I was mistaken with the FailureReports. They are separate from the nightly script- and MySQL-based processing and notification to domain owners. So I’ve actually removed that recommendation from the article, as it can lead to backscatter issues.

      I can see how SPF whitelisting could be useful. I recommend adding that request to the OpenDMARC tracker:

  • Wouter de Jong

    Thanks for the excellent blog post

    I installed openDMARC (next to openDKIM, thanks for maintaining the EPEL packages) just to verify incoming messages at this point with Postfix 2.11.5 on CentOS 6

    I guess my issue is more appropriate on the OpenDMARC tracker, but maybe you have some hints first 🙂

    Whenever I sent a test mail to my mailserver, with :

    HELO http://www.domain.tld

    where domain.tld has an “v=spf1 -all” SPF policy, openDMARC _always_ marks it with :

    spf=pass [email protected]

    Whereas it should mark it with spf=fail I believe.
    Same holds true for domain with a softfail …. that also get’s an spf=pass

    If I add a _dmarc.domain.tld TXT record with a “p=reject” in it, then it does fail dmarc
    But I still get an spf=pass header

    Authentication-Results: mail.server.tld; dmarc=fail header.from=domain.tld
    Authentication-Results: mail.server.tld; spf=pass [email protected]
    Authentication-Results: mail.server.tld; dkim=none

    This doesn’t look right to me…

    I’ve even rebuild the openDMARC package with your updated .spec so it links to libspf2,
    but there’s no difference in behavior it seems.

    But maybe I’m doing something terribly wrong 🙂

    • Steve Wardle

      I’m seeing the same thing.
      Authentication-Results: mail.server.tld; spf=pass [email protected]
      Did you find the problem?

      I’ve installed pypolicyd-spf-1.3.2 and that correctly reports SPF fail.

      Steve Wardle

  • Pingback: Configure a Centos 7 postfix mail server with virtual users | La Fabulosa Vida de un IT()

  • Hi, Ben. I’m not sure I understand your question. But I’ll take a stab at what I think you’re asking.

    The RHEL version of the OpenDMARC package is built “against” the lib2spf library at compile time, so you shouldn’t have to install it separately. But if you want to for other reasons… you certainly can, as it’s also in the repos (I know because I co-maintain the lib2spf package, too).

    I just peeked at the OpenDMARC SPEC file to confirm — the libspf2-devel package is only invoked on the Build, and therefore is not required for the package to run and do internal SPF checking. 🙂

  • 🙂

  • Thanks! FYI – this is a previously reported issue ( and I believe the source has already been patched to fix the issue. It should show up in the next release! 🙂

    • 🙂 I saw that too late I guess. Thank you for pointing me to previously reportes issue.

  • Christian B


    Any way to make it work whit Exim? i use cPanel

  • Pingback: Blog Links: DMARC (Domain-based Message Authentication, Reporting & Conformance) –


    On CentOS 7 the nightly script “” fails with the error
    opendmarc-import: unable to connect to database: Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’
    if you call it with
    So you must use

    Also, if you copy/paste the code directly from this article or even by pressing “View Raw” link – in both cases double dashes for the options are getting stripped to single dash.