OpenDKIM and Postfix on Ubuntu server

About DKIM

DKIM is an Internet Standard that enables a person or organization to associate a domain name with an email message, as such, claiming responsibility for the message. At its core, DKIM is powered by asymmetric cryptography. The sender's Mail Transfer Agent (MTA) signs every outgoing message with a private key. The recipient retrieves the public key from the sender's DNS records and verifies if the message body and some of the header fields were not altered since the message signing took place.

Install OpenDKIM

Before starting the installation, a system update is recommended:

sudo apt-get update

sudo apt-get upgrade

Install OpenDKIM and it's dependencies

sudo apt-get install opendkim opendkim-tools

Configure OpenDKIM

Important: replace every instance of example.com with your own domain in all commands and configuration files. Don't forget to save your files after editing.

Let's start with the main configuration file

sudo nano /etc/opendkim.conf

You will find main configurations items in comments. Finally, your file should look like this:

# This is a basic configuration that can easily be adapted to suit a standard

# installation. For more advanced options, see opendkim.conf(5) and/or

# /usr/share/doc/opendkim/examples/opendkim.conf.sample.

# Log to syslog Syslog yes

# Required to use local socket with MTAs that access the socket as a non-

# privileged user (e.g. Postfix) UMask 002 UserID opendkim

# Sign for example.com with key in /etc/mail/dkim.key using

# selector '2007' (e.g. 2007._domainkey.example.com)

#Domain example.com

#KeyFile /etc/mail/dkim.key

#Selector 2007

KeyTable refile:/etc/opendkim/key.table

SigningTable refile:/etc/opendkim/signing.table

ExternalIgnoreList refile:/etc/opendkim/trusted.hosts

InternalHosts refile:/etc/opendkim/trusted.hosts

# Commonly-used options; the commented-out versions show the defaults.

Canonicalization relaxed/simple

Mode sv

#SubDomains no

#ADSPAction continue

AutoRestart yes

AutoRestartRate 10/1h

SignatureAlgorithm rsa-sha256

#Background yes

#DNSTimeout 5

# Always oversign From (sign using actual From and a null From to prevent

# malicious signatures header fields (From and/or others) between the signer

# and the verifier. From is oversigned by default in the Debian pacakge

# because it is often the identity key used by reputation systems and thus

# somewhat security sensitive. OversignHeaders From

#Socket inet:8891@localhost

# List domains to use for RFC 6541 DKIM Authorized Third-Party Signatures

# (ATPS) (experimental)

#ATPSDomains example.com

This simple configuration is meant to allow message signing for one or more domains, to learn about other options please go to the opendkim.conf man page http://opendkim.org/opendkim.conf.5.html .

Configure the milter (mail filter) in Postfix

sudo nano /etc/default/opendkim

# Command-line options specified here will override the contents of

# /etc/opendkim.conf. See opendkim(8) for a complete list of options.

#DAEMON_OPTS=""

#

# Uncomment to specify an alternate socket

# Note that setting this will override any Socket value in opendkim.conf

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

#SOCKET="inet:54321"

# listen on all interfaces on port 54321

#SOCKET="inet:12345@localhost"

# listen on loopback on port 12345

#SOCKET="inet:12345@192.0.2.1"

# listen on 192.0.2.1 on port 12345

#SOCKET="inet:8891@localhost"

Edit /etc/postfix/main.cf and add a DKIM section

sudo nano /etc/postfix/main.cf

#DKIM

#----------------------

milter_default_action=accept

# Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2

milter_protocol=6

smtpd_milters=local:/opendkim/opendkim.sock

non_smtpd_milters=local:/opendkim/opendkim.sock

It is likely that a filter (SpamAssasin, Clamav etc.) is already used by Postfix; if the following parameters are present, just append the opendkim milter to them (milters are separated by a comma):

smtpd_milters = unix:/spamass/spamass.sock, local:/opendkim/opendkim.sock

non_smtpd_milters = unix:/spamass/spamass.sock, local:/opendkim/opendkim.sock

Create a directory structure that will hold the trusted hosts, key tables, signing tables, crypto keys and socket diectory

sudo mkdir /etc/opendkim

sudo mkdir /etc/opendkim/key

Create the opendkim socket directory

sudo mkdir /var/spool/postfix/opendkim

Specify trusted hosts, signing table and key table

sudo nano /etc/opendkim/trusted.hosts

127.0.0.1 ::1

localhost

mail.example.com

example.com

sudo nano /etc/opendkim/signing.table

*@exampe.com key1 # The signing key reference

sudo nano /etc/opendkim/key.table

key1 example.com:key1:/etc/opendkim/key/example-dkim.key

Generate the public and private keys; change to the keys directory

cd /etc/opendkim/key

Generate the keys

sudo opendkim-genkey -s mail -d example.com opendkim-genkey -b 2048 -h rsa-sha256 -r -s key1 -d example.com -v

-s specifies the selector and -d the domain, this command will create two files, key1.private is our private key and key1.txt contains the public key. Adapt the private key file name

mv key1.private /etc/opendkim/key/example-dkim.key

Add the public key to the domain's DNS records.

Connect to your DNS management console, and ad the following record:

key1._domainkey TXT "v=DKIM1\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ….

Where the p= is the public key from key1.txt file. Please note that the DNS changes may take a couple of hours to propagate.

Set ownership of the directory structure

sudo chown -R opendkim:opendkim /etc/opendkim

sudo chmod -R go-rw /etc/opendkim/keys

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

Add postfix system user to opendkim group in order to be able to use the socket

sudo useradd -g opendkim postfix

Restart Postfix and OpenDKIM

sudo service postfix restart

sudo service opendkim restart

Test the DKIM

First, test DNS records

dig key1._domainkey.example.com txt opendkim-testkey -d example.com -s key1 -v -v -v

Congratulations! You have successfully configured DKIM for your mail server! The configuration can be tested by sending an empty email to check-auth@verifier.port25.com and a reply will be received. If everything works correctly you should see

The Port25 Solutions, Inc. team

==========================================================

 Summary of Results

==========================================================

 SPF check:          pass

 "iprev" check:      pass

 DKIM check:         pass

 SpamAssassin check: ham

Alternatively, you can send a message to a Gmail address that you control, view the received email's headers in your Gmail inbox, dkim=pass should be present in the Authentication-Results header field. Authentication-Results: mx.google.com;

spf=pass (google.com: domain of contact@example.com designates --- as permitted sender) smtp.mail=contact@example.com;

dkim=pass header.i=@example.com;

Attention: Use Thunderbird to send test e-mails. Outlook may not send DKIM in the headers.