DKIM Setup on Postfix Mail Server Using OpenDKIM – CentOS 6/7
Introduction
Email deliverability is one of the major challenges when setting up a new mail server. Emails sent from an untrusted or unauthenticated mail server may be delivered to spam folders or rejected by popular email providers.
DomainKeys Identified Mail (DKIM) is an email authentication mechanism that allows an outgoing mail server to digitally sign emails. The receiving mail server can use the public key published in the sender’s DNS records to verify that the email was authorized by the sending domain and that the signed message has not been modified during transmission.
In this guide, we will configure OpenDKIM as the DKIM signing service and integrate it with Postfix. OpenDKIM will digitally sign outgoing emails, while Postfix will pass the messages to OpenDKIM through a Milter interface.
The guide covers:
- Installing OpenDKIM
- Configuring OpenDKIM
- Generating DKIM keys
- Configuring KeyTable and SigningTable
- Configuring trusted hosts
- Publishing the DKIM public key in DNS
- Integrating OpenDKIM with Postfix
- Starting and enabling the services
- Verifying DKIM signatures
Prerequisites
Before starting the configuration, ensure the following requirements are available.
1. CentOS Server
A CentOS 6 or CentOS 7 server with root or sudo access.
2. Postfix
Postfix must already be installed and configured as the mail transfer agent.
Verify the installation:
postconf mail_version
Check the Postfix service:
service postfix status
3. Domain Name
You should have a valid domain that will be used to send emails.
For this example, we will use:
domain.tld
Replace domain.tld with your actual domain throughout the configuration.
4. DNS Access
You must have access to the DNS management panel for the domain because the DKIM public key needs to be published as a TXT record.
5. EPEL Repository
The EPEL repository should be enabled because OpenDKIM can be installed from EPEL on CentOS 6/7.
6. SMTP Connectivity
The server should have working outbound SMTP connectivity and Postfix should already be able to send emails.
Technical Implementation
Step 1: Install the EPEL Repository
First, enable the EPEL repository.
CentOS 6
wget http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm rpm -ivh epel-release-6-8.noarch.rpm
CentOS 7
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm rpm -ivh epel-release-latest-7.noarch.rpm
Alternatively:
yum install epel-release
Verify the repository:
yum repolist
Step 2: Install OpenDKIM
Install OpenDKIM and its required packages:
yum install opendkim
Verify that OpenDKIM was installed:
rpm -qa | grep opendkim
Check the installed binary:
which opendkim
Step 3: Configure OpenDKIM
Back up the existing configuration before making changes:
cp /etc/opendkim.conf /etc/opendkim.conf.bak
Open the configuration file:
vi /etc/opendkim.conf
Configure the required parameters:
AutoRestart Yes AutoRestartRate 10/1h LogWhy Yes Syslog Yes SyslogSuccess Yes Mode sv Canonicalization relaxed/simple ExternalIgnoreList refile:/etc/opendkim/TrustedHosts InternalHosts refile:/etc/opendkim/TrustedHosts KeyTable refile:/etc/opendkim/KeyTable SigningTable refile:/etc/opendkim/SigningTable SignatureAlgorithm rsa-sha256 Socket inet:8892@localhost PidFile /var/run/opendkim/opendkim.pid UMask 022 UserID opendkim:opendkim TemporaryDirectory /var/tmp
The important configuration files used by OpenDKIM are:
/etc/opendkim.conf /etc/opendkim/KeyTable /etc/opendkim/SigningTable /etc/opendkim/TrustedHosts
The Milter socket is configured to listen on:
127.0.0.1:8892
Step 4: Generate DKIM Keys
Create a directory for the domain:
mkdir -p /etc/opendkim/keys/domain.tld
Generate the DKIM key pair:
opendkim-genkey -D /etc/opendkim/keys/domain.tld/ -d domain.tld -s default
This will generate two files:
default.private default.txt
The files contain:
default.private— Private DKIM key used by OpenDKIM to sign emails.default.txt— Public DKIM key that must be published in DNS.
Set the appropriate ownership:
chown -R opendkim:opendkim /etc/opendkim/keys/domain.tld
Rename the private key to match the configuration:
mv /etc/opendkim/keys/domain.tld/default.private \ /etc/opendkim/keys/domain.tld/default
Set secure permissions on the private key:
chmod 600 /etc/opendkim/keys/domain.tld/default
Verify:
ls -l /etc/opendkim/keys/domain.tld/
Step 5: Configure KeyTable
Open the KeyTable:
vi /etc/opendkim/KeyTable
Add:
default._domainkey.domain.tld domain.tld:default:/etc/opendkim/keys/domain.tld/default
The configuration follows this format:
key_name domain:selector:key_file
Here:
domain.tldis the sending domain.defaultis the DKIM selector./etc/opendkim/keys/domain.tld/defaultis the private key.
Step 6: Configure SigningTable
Open:
vi /etc/opendkim/SigningTable
Add:
*@domain.tld default._domainkey.domain.tld
The * means that emails sent from any address belonging to domain.tld will use the configured DKIM key.
For example:
admin@domain.tld support@domain.tld sales@domain.tld
will all be signed using:
default._domainkey.domain.tld
Step 7: Configure TrustedHosts
Open:
vi /etc/opendkim/TrustedHosts
Add the mail server’s trusted hosts.
For example:
127.0.0.1 localhost domain.tld
If required, the server’s IP address can also be included:
192.0.2.10
Do not add arbitrary external IP addresses to this file. Only trusted systems that are authorized to submit mail through the DKIM signer should be included.
Step 8: Configure DNS DKIM Record
The public DKIM key generated earlier can be viewed with:
cat /etc/opendkim/keys/domain.tld/default.txt
You will see a record similar to:
default._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..." )
Create a DNS TXT record for:
default._domainkey.domain.tld
with the generated public key as the value.
For example:
Type: TXT Name: default._domainkey Value: v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBg...
Do not copy the example key above. Always use the public key generated on your own server.
Important
The private key must never be published in DNS.
Only the public key from default.txt should be added to DNS.
DNS propagation time depends on the DNS provider and TTL. It may become available quickly, but cached records can take longer to update.
Step 9: Verify the DNS Record
After adding the DNS record, verify it using:
host -t txt default._domainkey.domain.tld
You can also use:
dig TXT default._domainkey.domain.tld
For a shorter output:
dig TXT default._domainkey.domain.tld +short
The response should contain something similar to:
"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBg..."
If the TXT record is not returned, verify the DNS record name, value, and DNS provider configuration.
Configure Postfix
Step 10: Integrate OpenDKIM with Postfix
Open the Postfix configuration:
vi /etc/postfix/main.cf
Add the following:
smtpd_milters = inet:127.0.0.1:8892 non_smtpd_milters = $smtpd_milters milter_default_action = accept milter_protocol = 2
The configuration tells Postfix to send mail through the OpenDKIM Milter service running on:
127.0.0.1:8892
Validate the Postfix configuration
Run:
postfix check
You can also verify the configured Milter parameters:
postconf | grep milter
Expected output should include:
milter_default_action = accept milter_protocol = 2 non_smtpd_milters = $smtpd_milters smtpd_milters = inet:127.0.0.1:8892
Step 11: Start and Enable OpenDKIM
Start OpenDKIM:
service opendkim start
Enable it at boot:
chkconfig opendkim on
Check the service:
service opendkim status
Verify that OpenDKIM is listening on port 8892:
netstat -lntp | grep 8892
Expected output should show OpenDKIM listening on localhost.
Step 12: Restart Postfix
Restart Postfix:
service postfix restart
Check the status:
service postfix status
If Postfix fails to start, check the configuration:
postfix check
and review the mail logs.
On CentOS systems, the Postfix mail log is commonly:
/var/log/maillog
Verification
Step 13: Check OpenDKIM Logs
Monitor the mail log:
tail -f /var/log/maillog
When an outgoing message is successfully signed, you should see an entry similar to:
opendkim[5644]: 5FF7E161215: DKIM-Signature field added (s=default, d=domain.tld)
This confirms that OpenDKIM added a DKIM signature to the outgoing message.
Step 14: Verify the Email Headers
Send an email from:
user@domain.tld
to an external mailbox such as Gmail.
Open the received email and inspect the message headers.
A successful authentication result may look similar to:
DKIM-Signature: v=1; a=rsa-sha256; d=domain.tld; s=default; ...
The receiving mail server may also show:
DKIM: PASS
The exact header format and authentication results depend on the receiving mail provider.
Step 15: Test Using an Email Authentication Verifier
You can also send an email to an email authentication testing service such as:
check-auth@verifier.port25.com
The service can return authentication results for the submitted message, including DKIM, SPF, and other mail authentication information.
Configuring DKIM for Multiple Domains
If the same Postfix server sends emails for multiple domains, each domain can have its own DKIM key.
For example:
/etc/opendkim/keys/domain1.tld/ /etc/opendkim/keys/domain2.tld/ /etc/opendkim/keys/domain3.tld/
Each domain should have its own entry in the KeyTable:
default._domainkey.domain1.tld domain1.tld:default:/etc/opendkim/keys/domain1.tld/default default._domainkey.domain2.tld domain2.tld:default:/etc/opendkim/keys/domain2.tld/default default._domainkey.domain3.tld domain3.tld:default:/etc/opendkim/keys/domain3.tld/default
The SigningTable can then contain:
*@domain1.tld default._domainkey.domain1.tld *@domain2.tld default._domainkey.domain2.tld *@domain3.tld default._domainkey.domain3.tld
Each domain must also have its corresponding DKIM public key published in DNS.
Troubleshooting
OpenDKIM is not running
Check the service:
service opendkim status
Check the logs:
tail -100 /var/log/maillog
Check whether port 8892 is listening:
netstat -lntp | grep 8892
Postfix cannot connect to OpenDKIM
Verify the Postfix configuration:
postconf | grep milter
Verify OpenDKIM is listening:
netstat -lntp | grep 8892
Make sure both configurations use the same address and port:
Postfix: inet:127.0.0.1:8892 OpenDKIM: inet:8892@localhost
DKIM signature is not being added
Check the OpenDKIM logs:
grep -i opendkim /var/log/maillog
Verify:
/etc/opendkim/KeyTable /etc/opendkim/SigningTable /etc/opendkim/TrustedHosts
Also verify the private key permissions:
ls -l /etc/opendkim/keys/domain.tld/default
The key should be readable by the opendkim user.
DNS DKIM record is not found
Run:
dig TXT default._domainkey.domain.tld +short
If there is no response:
- Verify the DNS record name.
- Verify the TXT record value.
- Confirm that the DNS change was saved.
- Check the DNS provider’s propagation status.
- Confirm that the selector is
default.
Security Recommendations
The DKIM private key is highly sensitive and must be protected.
Recommended permissions:
chown opendkim:opendkim /etc/opendkim/keys/domain.tld/default chmod 600 /etc/opendkim/keys/domain.tld/default
Do not:
- Publish the private key in DNS.
- Share the private key with external users.
- Store the private key in publicly accessible directories.
- Commit the private key to Git repositories.
- Expose the OpenDKIM Milter port publicly.
Since the Milter is configured to listen on localhost, it should not normally be exposed to external networks.
Conclusion
Configuring DKIM with OpenDKIM and Postfix adds an important layer of authentication to outgoing email. OpenDKIM generates a cryptographic signature using the private DKIM key, while receiving mail servers use the corresponding public key published in DNS to verify the signature.
The complete process consists of installing OpenDKIM, generating a domain-specific key pair, configuring the KeyTable and SigningTable, defining trusted hosts, publishing the public key in DNS, and integrating OpenDKIM with Postfix through the Milter interface.
After completing the configuration, always verify the setup using the mail server logs and the headers of a received email. A successful configuration should show a valid DKIM-Signature and, on the receiving server, a DKIM PASS result.
DKIM should also be used together with SPF and DMARC to provide a more complete email authentication and anti-spoofing strategy.
With Postfix, OpenDKIM, DNS, SPF, and DMARC correctly configured, organizations can improve the authenticity, security, and deliverability of their outgoing emails.
