At the receiving end, OpenDMARC requires two other services to work correctly before it works. One is OpenDKIM, another is SPF.

OpenDKIM is much more complicated than OpenDMARC, because both the sending and receiving sides need to setup OpenDKIM. The sending side should setup OpenDKIM to sign the outgoing messages by domain key, while the receiving side should have OpenDKIM to validate the signature for incoming messages.

OpenDMARC is working like SPF, it works only at the receiving end, following the sender domain's instruction in DNS on how to handle the messages.

For example, this is gmail's SPF record from DNS queries:

 gmail.com.		300	IN	TXT	"v=spf1 redirect=_spf.google.com"

And, this is gmail's DMARC record from DNS queries too:

 _dmarc.gmail.com.	600	IN	TXT	"v=DMARC1; p=none; sp=quarantine; rua=mailto:[email protected]"

When either SPF or DKIM passes, DMARC should pass the checks. If both SPF and DKIM fail for validation, DMARC should also fail.

Please note: DMARC requires the sender domain in header address to pass the SPF checks. Any rewrited domain handled by SRS has no helps to DMARC. That's saying, if the sender envelope address is rewrited by OpenSRS, though it passes the SPF checks at receiving end, but it doesn't match the requirement by OpenDMARC, because DMARC requires the header address to pass SPF as well.

So, if the provider issues DMARC in its DNS, it must setup correctly DKIM for outgoing messages, otherwise the messages (especially forwarded by others) should most probably be rejected by other MTAs.

How to setup OpenDMARC for Postfix? It's just simple as follows.

First, let's install OpenDMARC service in Ubuntu server,

 $ sudo apt install opendmarc

During the installation, you can choose not to use a database as storage for reports.

Then enable the service,

 $ sudo systemctl enable opendmarc

Next, let's edit the configuration for opendmarc, it's the file "/etc/opendmarc.conf", with the following new or modified items.

 AuthservID  OpenDMARC
TrustedAuthservIDs mail.hostname.com
RejectFailures true
IgnoreAuthenticatedClients true
Socket local:/var/spool/postfix/opendmarc/opendmarc.sock

Their comments,

  • AuthservID - the server ID for opendmarc identity.
  • TrustedAuthservIDs - hostname for this MTA, this is very important, you must use the same hostname from Postfix, because OpenDMARC will only trust the DKIM and SPF validation provided by this hostname.
  • RejectFailures - if DMARC fails, reject the message.
  • IgnoreAuthenticatedClients - SASL users (MUA etc) should always pass.
  • Socket - Must setup to the chroot path run by Postfix.

Also in the file "/etc/default/opendmarc" changes SOCKET location,

 SOCKET=local:/var/spool/postfix/opendmarc/opendmarc.sock

Next, create the dir and permissions for opendmarc.

 $ sudo mkdir -p /var/spool/postfix/opendmarc
$ sudo chown opendmarc:opendmarc /var/spool/postfix/opendmarc -R
$ sudo chmod 750 /var/spool/postfix/opendmarc/ -R
$ sudo adduser postfix opendmarc

Then restart opendmarc,

 $ sudo systemctl restart opendmarc

The next, we should connect postfix to opendmarc via milter. Edit the file "/etc/postfix/main.cf" and change the corresponding content as follows.

 milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock,local:opendmarc/opendmarc.sock
non_smtpd_milters = $smtpd_milters

We have two milters above, one is opendkim, another is opendmarc.

And SPF could already be working as a policyd service as the following items.

 smtpd_recipient_restrictions =
check_policy_service { unix:ratelimit/policy, default_action=DUNNO },
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service { unix:private/policyd-spf, default_action=DUNNO }

The last, restart postfix,

 $ sudo systemctl restart postfix

Now send a message from gmail to your domain email, you will see in the message header the following validation results.

 Authentication-Results: OpenDMARC; dmarc=pass (p=none dis=none) header.from=gmail.com
Authentication-Results: mailbox.net;
dkim=pass (2048-bit key; unprotected) header.d=gmail.com [email protected] header.a=rsa-sha256 header.s=20221208 header.b=MR8nkcIm;
dkim-atps=neutral
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=209.85.160.53; helo=mail-oa1-f53.google.com; [email protected]; receiver=<UNKNOWN>

As you see in the above header, all three validation have passed.

  • dmarc=pass
  • dkim=pass
  • Received-SPF: Pass

And a manual telnet for testing DMARC to the receiving MTA,

 $ telnet mailbox.net 25
Trying 38.45.64.218...
Connected to mailbox.net.
Escape character is '^]'.
220 mailbox.net ESMTP Postfix
helo nyc.hostcache.com
250 mailbox.net
mail from:<[email protected]>
250 2.1.0 Ok
rcpt to:<[email protected]>
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
from:<[email protected]>
to:<[email protected]>
subject: service notice

you must update your password for now.
.
550 5.7.1 rejected by DMARC policy for paypal.com
quit
221 2.0.0 Bye
Connection closed by foreign host.

Since Paypal's DMARC setting is to reject failed message,

 _dmarc.paypal.com.	3600	IN	TXT	"v=DMARC1; p=reject; rua=mailto:[email protected]; ruf=mailto:[email protected]"

So this fake email was rejected by our MTA.

Please also reference the following URLs.

Set Up OpenDMARC with Postfix on Ubuntu

How to Set up SPF and DKIM with Postfix on Ubuntu

Two policyd services I used for postfix

DKIM on Wikipedia

DMARC on Wikipedia

SPF on Wikipedia

SRS on Wikipedia