SPF and DKIM with Postfix

SPF (Sender Policy Framework) record specifies which hosts or IP addresses are allowed to send emails on behalf of a domain. You should allow only your own email server or your ISP’s server to send emails for your domain.

DKIM (DomainKeys Identified Mail) uses a private key to add a signature to emails sent from your domain. Receiving SMTP servers verify the signature by using the corresponding public key, which is published in your DNS manager.

Create SPF record in DNS zone

n your DNS management interface, create a new TXT record like below.

TXT  @   v=spf1 mx ~all

Some DNS managers require you to wrap the SPF record with quotes like below.

TXT  @   "v=spf1 mx ~all"

Keep in mind that it can take up to an hour for the new record to be available.

Configure Postfix for SPF

First, install required packages:

sudo apt install postfix-policyd-spf-python

Edit the Postfix master process configuration file located at /etc/postfix/ Add these lines to the end:

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

Now open up the configuration file at /etc/postfix/ Add these lines to the end of the file:

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

Now restart postfix

sudo systemctl restart postfix

Configure DKIM

sudo apt install opendkim opendkim-tools

Add the Postfix user to the OpenDKIM group

sudo gpasswd -a postfix opendkim

Now open the configuration of OpenDKIM and enable or add these lines:

Canonicalization   simple
Mode               sv
SubDomains         no
AutoRestart         yes
AutoRestartRate     10/1M
Background          yes
DNSTimeout          5
SignatureAlgorithm  rsa-sha256

Go to the end of the file and add these lines:

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

# Map domains in From addresses to keys used to sign messages
KeyTable           refile:/etc/opendkim/key.table
SigningTable       refile:/etc/opendkim/signing.table

# Hosts to ignore when verifying signatures
ExternalIgnoreList  /etc/opendkim/trusted.hosts

# A set of internal hosts whose mail should be signed
InternalHosts       /etc/opendkim/trusted.hosts

We will need to create the signing table, key table and the trusted hosts file.

sudo mkdir /etc/opendkim
sudo mkdir /etc/opendkim/keys
sudo chown -R opendkim:opendkim /etc/opendkim
sudo chmod go-rw /etc/opendkim/keys

Now create the signing table, using your domain. Open the file and add the second line in it:

sudo nano /etc/opendkim/signing.table

Now create the key table

sudo nano /etc/opendkim/key.table

Now create the trusted hosts file:

sudo nano /etc/opendkim/trusted.hosts


Generating DKIM Keypair

Create a separate folder for the domain.

sudo mkdir /etc/opendkim/keys/

Generate keys using opendkim-genkey tool.

sudo opendkim-genkey -b 2048 -d -D /etc/opendkim/keys/ -s default -v
sudo chown opendkim:opendkim /etc/opendkim/keys/

Display the public key that was generated:

sudo cat /etc/opendkim/keys/

This file contains the entire DNS record that should be published. Copy everything, startking with the v=DKIM1 and in your DNS record. After 15 minutes, test is the record has been successfully published:

sudo opendkim-testkey -d -s default -vvv


opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key ''
opendkim-testkey: key secure
opendkim-testkey: key OK

Connecting Postfix to OpenDKIM

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

Open the configuration file at /etc/opendkim.conf, replace the socket (if defined, or add it):

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

Open /etc/postfix/ and add the following to the end:

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

Now restart Postfix and OpenDKIM:

sudo systemctl restart opendkim postfix