Set Up OpenDMARC with Postfix on Ubuntu to Block Email Spoofing/Spam

In previous articles, we discussed how you can quickly set up your own mail server by using iRedMail or Modoboa, and also several effective tips to block email spam. This tutorial will be showing you how to set up OpenDMARC with Postfix SMTP server on Ubuntu to block email spoofing and spam. OpenDMARC is an open source DMARC email policy filter for MTAs (Message Transport Agent, aka SMTP server).

What is DMARC

DMARC (Domain-based Message Authentication, Reporting and Conformance) is an Internet standard (RFC 7489) that allows domain owners to prevent their domain names from being used by email spoofers. Before DMARC is invented, it is very easy for bad actors to use other people’s domain name in the From address.

If a domain owner created DMARC DNS record for his/her domain name and a receiving email server implemented DMARC check, then bad actors need to pass SPF alignment or DKIM alignment in order to pass DMARC check. If DMARC check fails, the spoofed email could be rejected. Never to be seen by end users. It’s difficult for the bad actor to pass SPF or DKIM, unless the domain owner’s email server is compromised.

OpenDMARC Postfix Ubuntu

Email Spoofing Example

A spammer sent me a ransom email using winsaaluminyumankara.com in the From address. The whois information of winsaaluminyumankara.com is public. Clearly the spammer is not a person responsible for this domain name.

dmarc setup

winsaaluminyumankara.com has a DMARC record.

opendmarc postfix ubuntu

Then I checked the email headers, which shows SPF failed. There’s no DKIM signature. So DMARC check fails. This is a spoofed email.

opendmarc postfix

This goes to show that not only big brands are being used by email spoofers, any domain names on the Internet could be impersonated by bad actors. Unfortunately the DMARC policy for this domain name is p=none, which tells receiving email server to do nothing special if DMARC check fails. If the policy is to p=reject, then my Postfix SMTP server would reject this email with OpenDMARC.

Paypal and Facebook have created a reject DMARC policy for their domain name.

opendmarc configuration

So if a bad actor tries to spoof Paypal or Facebook, my email server can reject the spoofed email with OpenDMARC. There are many other well-known domain names that deployed a reject DMARC policy, as can be seen in the table below.

  • bankofamerica.com
  • yahoo.com
  • chase.com
  • wellsfargo.com
  • facebook.com
  • google.com
  • youtube.com
  • twitter.com
  • reddit.com
  • instagram.com
  • linkedin.com
  • medium.com
  • pinterest.com
  • dropbox.com
  • microsoft.com
  • whatsapp.com

The secure mailbox provider Protonmail is using Postfix and OpenDMARC to perform DMARC checks on inbound emails and I will show you how to do the same on your own Postfix SMTP server.

Prerequisites

This tutorial is for mailbox providers and anyone who run their own mail server, to protect their users from being scammed by email spoofing. If you are a domain name owner and want to prevent your domain name from being used by email spoofers, please read this article to create DMARC record and analyze DMARC report. I also recommend you to read that article if you don’t fully understand DMARC.

To follow this tutorial, you need to get SPF and DKIM verification working first, because DMARC depends on the SPF and DKIM verification results to make a final decision.

Setting up OpenDMARC with Postfix SMTP Server on Ubuntu 16.04, Ubuntu 18.04 or 19.04

OpenDMARC is an open source software that can perform DMARC check and reporting. It’s already in Ubuntu repository, so you can run the following command to install it.

sudo apt install opendmarc

Once installed, it will be automatically started. Check its status with:

systemctl status opendmarc

Output:

 opendmarc.service - OpenDMARC Milter
   Loaded: loaded (/lib/systemd/system/opendmarc.service; disabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-10-30 19:49:52 CST; 23s ago
     Docs: man:opendmarc(8)
           man:opendmarc.conf(5)
 Main PID: 14858 (opendmarc)
    Tasks: 6 (limit: 1110)
   CGroup: /system.slice/opendmarc.service
           └─14858 /usr/sbin/opendmarc

Note that auto-start at system boot time is disabled. We can enable it by:

sudo systemctl enable opendmarc

Then edit the main configuration file with your text editor.

sudo nano /etc/opendmarc.conf

Find the following line:

# AuthservID name

It’s better to use a different name for the authentication service, because Amavisd-new will overwrite the authentication results header added by OpenDMARC. You can change it to the following.

AuthservID OpenDMARC

Then find this line:

# RejectFailures false

By default, OpenDMARC won’t reject emails that fail DMARC check, even if the domain’s policy is set to p=reject. If you prefer to reject emails that fail DMARC check when the domain’s policy is set to p=reject, then uncomment this line and change false to true.

RejectFailures true

You may want OpenDMARC to ignore SMTP clients that are successfully authenticated via SMTP AUTH. For example, I have a Postfix SMTP server running on my blog web server that uses my main mail server as a relay to send notification emails, so I want openDMARC to ignore emails that are submitted from my blog web server. This also applies to desktop/mobile mail clients that submit outgoing emails over port 587. In this case, add the following line at the end of this file.

IgnoreAuthenticatedClients true

OpenDMARC is implemented as a milter (mail filter). Postfix can talk to milter applications via Unix socket. The default socket file used by OpenDMARC is /var/run/opendmarc/opendmarc.sock. But the Postfix SMTP daemon shipped with Ubuntu runs in chroot jail, which means the SMTP daemon resolves all filenames relative to the Postfix queue directory (/var/spool/postfix). So we need to change the socket file used by OpenDMARC.

Find the following line.

Socket local:/var/run/opendmarc/opendmarc.sock

Change it to:

Socket local:/var/spool/postfix/opendmarc/opendmarc.sock

Save and close the file. On Ubuntu 16.04, there’s no Socket defined in this file, you just need to add the above line in the file.

Note: The /etc/default/opendmarc file can also set the socket file location, but the opendmarc package on Ubuntu 18.04, 19.04 doesn’t read this file, so we need to do this in /etc/opendmarc.conf file.

Create a directory to hold the OpenDMARC socket file and change the ownership so that  opendmarc user and opendmarc group can access it.

sudo mkdir -p /var/spool/postfix/opendmarc

sudo chown opendmarc:opendmarc /var/spool/postfix/opendmarc -R

Change permission to 750 to restrict access, so users not in group opendmarc can’t access this directory.

sudo chmod 750 /var/spool/postfix/opendmarc/ -R

Add user postfix to group opendmarc.

sudo adduser postfix opendmarc

Then restart OpenDMARC.

sudo systemctl restart opendmarc

Configure Postfix SMTP Server

Edit the main configuration file.

sudo nano /etc/postfix/main.cf

If you have already configure OpenDKIM, then you should have lines in this file like below.

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Now you just need to add the OpenDMARC socket file so that Postfix can talk to OpenDMARC. (Make sure it’s after the OpenDKIM socket.)

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

Save and close the file. Then restart Postfix for the change to take effect.

sudo systemctl restart postfix

If you use iRedMail

If you used iRedMail to set up your mail server, then you don’t have SPF verification and OpenDKIM. iRedMail uses Amavis to do DKIM signing and verification, but OpenDMARC can’t read the DKIM verification reuslts from Amavis, which will result in DMARC check failure. So, we need to setup SPF verification and DKIM verification as follows.

First, install the SPF package:

sudo apt install postfix-policyd-spf-python

Then edit the Postfix master process configuration file.

sudo nano /etc/postfix/master.cf

Add the following lines at the end of the file, which tells Postfix to start the SPF policy daemon when it’s starting itself.

policyd-spf  unix  -       n       n       -       0       spawn
    user=policyd-spf argv=/usr/bin/policyd-spf

Save and close the file. Next, edit Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Find the following line,

smtpd_recipient_restrictions =

Then add the following line above it. This line specifies the Postfix policy agent timeout.

policyd-spf_time_limit = 3600

Next, add the following line to perform SPF verification.

check_policy_service unix:private/policyd-spf

So it will look like this:

policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    ...
    ...
   check_policy_service unix:private/policyd-spf

iredmail opendmarc

Note that you should always put permit_mynetworks and permit_sasl_authenticated at the top, so your mail server won’t perform unneeded SPF verification on clients of your own network or authenticated users. Save and close the file. Then restart Postfix.

sudo systemctl restart postfix

Now run the following command to install OpenDKIM.

sudo apt install opendkim

Edit OpenDKIM main configuration file.

sudo nano /etc/opendkim.conf

Find the following line

#Mode        sv

By default, OpenDKIM will act as both a signer (s) and a verifier (v). Since iRedMail already uses Amavis to do DKIM signing, we just need OpenDKIM to act as a verifier, so OpenDMARC can read the verification result. Remove the # symbol and change the mode to verifier.

Mode         v

Then add the following lines at the end of this file.

#OpenDKIM user
# Remember to add user postfix to group opendkim
UserID             opendkim

# Hosts to ignore when verifying signatures
ExternalIgnoreList  /etc/opendkim/trusted.hosts
InternalHosts       /etc/opendkim/trusted.hosts
Socket              local:/var/spool/postfix/opendkim/opendkim.sock

Save and close the file. Add postfix user to opendkim group.

sudo adduser postfix opendkim

Create the trusted hosts file.

sudo mkdir /etc/opendkim/
sudo nano /etc/opendkim/trusted.hosts

Add the following lines to the newly created file.

127.0.0.1
localhost

*.your-domain.com

The above means that messages coming from the above IP addresses and domains will be trusted. Save and close the file. Then change ownership.

sudo chown -R opendkim:opendkim /etc/opendkim

Next, create a directory to hold the OpenDKIM socket file and only allow opendkim user and group to access it.

sudo mkdir /var/spool/postfix/opendkim

sudo chown opendkim:opendkim /var/spool/postfix/opendkim

If you can find the following line in /etc/default/opendkim file.

SOCKET="local:/var/run/opendkim/opendkim.sock"

Change it to

SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"

After that, we need to edit Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following lines at the end of this file to connect Postfix with OpenDKIM and OpenDMARC.

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

Save and close the file. Restart OpenDKIM, OpenDMARC and Postfix.

sudo systemctl restart opendkim opendmarc postfix

Testing OpenDMARC Verification

Now send an email from your other email address to your domain address. After that, check the email headers. If OpenDMARC is working correctly, you can see the DMARC verification results like below.

Authentication-Results: email.linuxbabe.com; dmarc=pass (p=none dis=none) header.from=gmail.com

I sent an email from my Gmail account to my domain email address and it passed DMARC verification. If you don’t see this email header, then check your mail logs.

sudo nano /var/log/mail.log

You will see something like below:

opendmarc[26495]: implicit authentication service: mail.linuxbabe.com
opendmarc[26495]: 61DAA3EA44: gmail.com pass

Testing OpenDMARC with Telnet

You can use telnet to spoof another domain name, such as paypal.com. First, run the following command to connect to port 25 of your mail server.

telnet mail.yourdomain.com 25

Then use the following steps to send a spoof email. (You type in the bold texts.)

HELO mail.paypal.com
250 mail.yourdomain.com
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:  Please update your password.

Click this link to update your password.
.
550 5.7.1 rejected by DMARC policy for paypal.com
quit

As you can see, my mail server rejected this email because it didn’t pass DMARC check and Paypal deployed a p=reject policy.

Update: If a domain’s DMARC policy is set to p=quarantine, in theory OpenDMARC should put the spoofed email into spam folder. But I found that the OpenDMARC milter put the spoofed email into the Postifx hold queue indefinitely. The postmaster can list all messages in the queue with postqueue -p command and use the postsuper command line utility to release messages in hold queue.

Conclusion

I hope this tutorial helped you set up OpenDMARC with Postfix SMTP server on Ubuntu to block email spoofing and spam. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial
[Total: 4 Average: 4.3]

3 Responses to “Set Up OpenDMARC with Postfix on Ubuntu to Block Email Spoofing/Spam

  • Very important. And a thorough discussion. But way too complex. You can set up DMARC with minimal coding using Cloudflare. iRedMail already enables DKIM and SPF.

    Despite all of this you can still be subject to spoofing. And what if you have 10 domain names.

    • OpenDMARC can’t read the iRedMail SPF and DKIM verification results, which means the DMARC check will always fail. So I use the method described in this article on my iRedMail server.

      Sorry, but I don’t know how to perform DMARC check using Cloudflare. This article is about DMARC check on inbound emails. You can have 10 domain names on the mail server. You just need to set up OpenDMARC once and it will check every inbound email.

      Protecting your own domain name from being used by spoofers is another subject, you can learn it here.

      DMARC can only protect the exact domain name. It does not prevent spoofing with lookalike domain names (paypal.com vs paypa1.com)

      Email server is complex.

  • It’s the best tutorial that I have ever seen till now on the subject

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • If you ask me more than 5 questions, I expect you to make a donation, or I would stop answering your questions.