Setting up OpenDKIM + Postfix on Ubuntu

Adding DKIM signing to improve email deliverability.

DKIM (DomainKeys Identified Mail) is an email authentication method that lets receiving servers verify that messages really came from your domain and weren’t tampered with in transit. Having a valid DKIM signature dramatically improves the chances that your emails land in the inbox instead of spam folders at Gmail, Yandex, Outlook, Mail.ru, and other providers.

This guide shows how to set up OpenDKIM with Postfix on Ubuntu — the standard and most reliable way to sign outgoing mail from a VPS or dedicated server.

Installing OpenDKIM

sudo apt update
sudo apt install opendkim opendkim-tools -y

Generating DKIM keys

  1. Create a directory for the keys:
sudo mkdir -p /etc/opendkim/keys
  1. Generate the key pair (replace example.com with your actual domain and mail with any selector you like — dkim, 2025, selector1, etc.):
sudo opendkim-genkey -D /etc/opendkim/keys/ -d example.com -s mail

After running this, you’ll find two files in /etc/opendkim/keys/:

  • mail.txt — the DNS TXT record you’ll publish
  • mail.private — the private key (keep this secret)
  1. Set correct permissions:
sudo chown opendkim:opendkim /etc/opendkim/keys/*
sudo chmod 600 /etc/opendkim/keys/*

Publishing the DNS txt record

Show the TXT record:

cat /etc/opendkim/keys/mail.txt

Example output:

mail._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM+aKFwMV4FHLhghuhQs4vEIIIigO0KzRwQojURHI8QV0m/aHt6AqO2JDhXpl54d3uXJj7QWE9653McQZxPQZa6Hu34RY70ap9OZQ664fWeVuyUAZ+VeQ7gGXQBCxPF6nAlnBIsYak+KV/s1HtaUuySVMiwIDAQAB" )

Go to your DNS provider’s control panel and add a new TXT record:

  • Name / Host: mail._domainkey
  • Type: TXT
  • Value: everything inside the parentheses (remove the quotes and line breaks)

It usually takes 5–60 minutes for DNS to propagate.

Configuring OpenDKIM

  1. Edit the main config file:
sudo nano /etc/opendkim.conf

Make sure it contains (or add) these lines:

AutoRestart             Yes
AutoRestartRate         10/1h
Umask                   002
Syslog                  Yes
SyslogSuccess           Yes
LogWhy                  Yes
Canonicalization        relaxed/simple
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
KeyTable                refile:/etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable
Mode                    sv
PidFile                 /var/run/opendkim/opendkim.pid
SignatureAlgorithm      rsa-sha256
UserID                  opendkim:opendkim
Socket                  inet:8891@localhost

(The port 8891 is arbitrary — you can change it as long as it matches Postfix later.)

  1. Create the TrustedHosts file (hosts allowed to send mail through OpenDKIM):
sudo nano /etc/opendkim/TrustedHosts

Add:

127.0.0.1
localhost
example.com
*.example.com
  1. Create the KeyTable (maps domain/selector to private key):
sudo nano /etc/opendkim/KeyTable

Add:

mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/mail.private
  1. Create the SigningTable (tells which selector to use for which addresses):
sudo nano /etc/opendkim/SigningTable

Add:

*@example.com mail._domainkey.example.com

Connecting OpenDKIM to Postfix

Edit Postfix main config:

sudo nano /etc/postfix/main.cf

Add (or append to existing milter lines):

# OpenDKIM integration
milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Starting and testing

  1. Restart services:
sudo systemctl restart opendkim
sudo systemctl restart postfix
  1. Check that both are running:
sudo systemctl status opendkim
sudo systemctl status postfix
  1. Send a test email from the server:
echo "DKIM test message" | mail -s "DKIM Test" your@gmail.com
  1. Open the received email → “Show original” (in Gmail) and look for:
Authentication-Results: ... dkim=pass header.d=example.com ...

If you see dkim=pass, everything is working correctly.

Useful notes

  • For multiple domains, just add more lines to KeyTable and SigningTable following the same pattern.
  • For best deliverability, also set up SPF and DMARC records.
  • Logs for debugging: /var/log/mail.log or /var/log/syslog (look for opendkim entries).

Help

If you have any questions or need assistance, please contact us through the ticket system — we're always here to help!

Need help?Our engineers will help you free of charge with any question in minutesContact us