Tag Archives: dkim

Configuring DKIM for Postfix

Fighting spam can be tricky. In addition to SPF records, DKIM is nearly mandatory to help prevent sent emails from being classified as spam. Beginning February of 2024, both Google and Yahoo will require DMARC, which require either SPF or DKIM; and in some cases for a high volume of emails (5,000+), both.

In this tutorial, we will look at signed outbound messages with DKIM via use of the open source project OpenDKIM. If you followed my previous tutorial on Postfix + Dovecot + Mysql/MaraiDB, you may have multiple domain names, so this guide will assume you will want to configure separate DKIM keys for each domain name you are hosting.

Step 1: Install OpenDKIM

First, update packages for your distribution.

sudo apt-get update && sudo apt-get upgrade

Install OpenDKIM and OpenDKIM tools. OpenDKIM-tools has a utility to generate the keys we will use.

sudo apt-get install opendkim opendkim-tools

Step 2: Created trusted hosts configuration file for OpenDKIM

First, create a file that OpenDKIM will use that defines the trusted hosts that can send messages.

sudo mkdir /etc/opendkim
sudo vi /etc/opendkim/TrustedHosts

Add the IP addresses and fqdn of the server sending messages by typing i to change into insert mode in vi.

Type :wq to commit the changes in vi.

Step 3: Modify OpenDKIM configuration file

Modify the opendkim.conf configuration file

sudo vi /etc/opendkim.conf

Search for #Canonicalization simple and uncomment the line by removing the # symbol.

Search for #Mode and remove the # symbol to uncomment the line. Ensure the line is configured with s for signing outbound emails or sv for verifying dkim keys on sent and received emails.

If you have subdomains, search for #SubDomains and remove the # and change to yes. For example:

SubDomains              yes

Search for Socket local:/var/run/opendkim/opendkim.sock and comment the line by adding a # in front of the line.

Search for #Socket inet:8891t@localhost and uncomment the line. If the line does not exist in your document, then add the following at the end of your document.

Socket inet:8891@localhost

Next, add the following lines to reference our DKIM configurations for each domain:

KeyTable /etc/opendkim/KeyTable
SigningTable /etc/opendkim/SigningTable
ExternalIgnoreList /etc/opendkim/TrustedHosts
InternalHosts /etc/opendkim/TrustedHosts

Type :wq to save the change and close the file

Step 4: Configure Postfix

sudo vi /etc/postfix/main.cf

Add the following lines to the end of the file:

milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Type :wq to save the changes and close the file.

Step 5: Restart services to use the changes (optional)

Execute the following to apply the changes if you wish to add domain names at a later time. If not, you can skip this step.

sudo /etc/init.d/opendkim restart
sudo /etc/init.d/postfix reload
sudo /etc/init.d/postfix restart

Step 5/6: Create a DKIM key for a domain

Run the following command to create a new folder and change directory to it for where we will generate our key used to sign the outgoing emails.

sudo mkdir -p /etc/opendkim/keys/mydomain.com
cd /etc/opendkim/keys/mydomain.com

Execute the following command to generate the key:

sudo opendkim-genkey -r -d mydomain.com

Delegate access to the opendkim user and group to access the key (note, if you modified the user in your opendkim.conf file, you will want to use that instead)

sudo chown opendkim:opendkim default.private

Step 7: Reference the key via OpenDKIM KeyTable

Modify the Keytable with vi

sudo vi /etc/opendkim/KeyTable

Add the following line to the file to define your selector. In this example, we will call the selector default, but if your domain requires multiple DKIM keys, ensure you make this unique. You can modify the file by pressing i to enter insert mode in vi:

default._domainkey.mydomain.com mydomain.com:default:/etc/opendkim/keys/mydomain.com/default.private

Type :wq to write and quite vi

Step 8: Specify the domain in your OpenDKIM SigningTable

Open the SigningTable file via vi

sudo vi /etc/opendkim/SigningTable

Add the following line to the file by pressing i to enter insert mode (changing default if specified a different selector earlier on):

mydomain.com default._domainkey.mydomain.com

Type :wq to write and quite vi

Step 8: Update your services to apply the changes

Restart your services to begin signing your messages:

sudo /etc/init.d/opendkim restart
sudo /etc/init.d/postfix reload
sudo /etc/init.d/postfix restart

Step 9: Update DNS

Get the DNS record values we need to publish by executing the following command:

sudo cat /etc/opendkim/keys/mydomain.com/default.txt

Create a new TXT record within your nameservers and specify the value between the quotes (don't include the quotes). I.e.:

v=DKIM1; h=sha256; k=rsa; s=email; p=ABCDEFG.....

Note: I choose to update DNS last as once you update DNS, any servers that would receive mail before you apply the previous configuration may discard your emails. Then again, you didn't have DKIM before, so you were probably going to junk mail anyways ;^)


Shoutout to Diego on stackoverflow, edoceo, and suenotek for consolidating a lot of these steps:
postfix - Using DKIM in my server for multiple domains (websites) - Ask Ubuntu

How To: Installing and Configuring OpenDKIM for multiple domains with Postfix on Linux | Edoceo

Roundcube mail app and SPF, DKIM & DMARC on Ubuntu 20.04 (suenotek.com)