Sunday, November 18, 2012

Set Up DKIM (DomainKeys Identified Mail) Working With Postfix On CentOS Using OpenDKIM

  This tutorial shows how to get DKIM working on a CentOS box running Postfix using OpenDKIM, I'll also cover some simple trouble shooting tips and advice for future upgrade on your OpenDKIM installation.

1 Requirements

This tutorial assumes that you have a full functional CentOS installation running the following services:
- Postfix 2.3.3 or better currently working.
- Sendmail is turned off.

2 Preliminary Notes

I'm running all the steps in this tutorial with root privileges, I'm currently running CentOS 6.3 with OpenDKIM version 2.4.2 and I will be using as the primary domain for this tutorial.

3 Download and install OpenDKIM

You'll also need to install the OpenSSL and Sendmail development packages, because they contain some "libraries" you need to get OpenDKIM working.
yum install sendmail-devel openssl-devel
Download OpenDKIM to the /usr/local/src directory:
cd /usr/local/src
Extract, configure, compile, and install OpenDKIM with:
tar zxvf opendkim-2.4.2.tar.gz
cd opendkim-2.4.2
./configure --sysconfdir=/etc --prefix=/usr/local --localstatedir=/var
make install
Note that the ./configure command includes a few very important flags, which will be passed into the startup script that's created when the configure command runs. The first tells the system where OpenDKIM's conf file will be located, the second sets the preferred prefix for some other important file locations, and the final one controls the directory where the PID file for OpenDKIM will be stored.

4 Create a new user

Add a new user for DKIM called opendkim with the following options:
useradd -r -g -s /sbin/nologin opendkim
This command will create a new system account (-r) and group (-g) called opendkim and assign no shell access to this user (-s).

5 Create working directories

Make some new directories for OpenDKIM and give them the proper ownership and permissions with:
mkdir -p /etc/opendkim/keys
chown -R opendkim:opendkim /etc/opendkim
chmod -R go-wrx /etc/opendkim/keys

6 Copy the startup script to /etc/init.d/

OpenDKIM's source package includes a contrib directory that contains a custom init script to be use with all RedHat-compatible systems, including Fedora and CentOS. You can copy it to your /etc/init.d/ directory to make starting, stopping, restarting, and reloading OpenDKIM easy:
cp /usr/local/src/opendkim-2.4.2/contrib/init/redhat/opendkim /etc/init.d/
Now set the correct permissions for the init script:
chmod 755 /etc/init.d/opendkim

7 Generate keys for signing

You need to generate a private and a public key for each of the domains for which you wish to sign mail. The private key is stored away on your server, while the public key gets published in your domain's DNS records so that receiving mail servers can verify your DKIM-signed mail.
You need decide now what the name of your selector is going to be. A selector is a unique keyword that is associated with both keys (public and private), included in all the signatures, and published in your DNS records. For simplicity, I use the word default as my default selector. Feel free to choose something different, but if you do, you'll need to use it consistently throughout your setup. Also, while this should go without saying, you should use your mail domain instead of throughout the following steps.
Create your keys:
mkdir /etc/opendkim/keys/
/usr/local/bin/opendkim-genkey -D /etc/opendkim/keys/ -d -s default
chown -R opendkim:opendkim /etc/opendkim/keys/
mv /etc/opendkim/keys/ /etc/opendkim/keys/
In this example, I used the -D (directory) option, the -d (domain) option, and the -s (selector) options. That's all you need to get this going.

8 Edit configuration files

You need to create or edit four files:
- 1 /etc/opendkim.conf –- OpenDKIM's main configuration file
- 2 /etc/opendkim/KeyTable –- a list of keys available for signing
- 3 /etc/opendkim/SigningTable -- a list of domains and accounts allowed to sign
- 4 /etc/opendkim/TrustedHosts –- a list of servers to "trust" when signing or verifying
Create the file /etc/opendkim.conf:
vi /etc/opendkim.conf
Make sure your file that looks like this:
## opendkim.conf -- configuration file for OpenDKIM filter
AutoRestart             Yes
AutoRestartRate         10/1h
Canonicalization        relaxed/simple
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
KeyTable                refile:/etc/opendkim/KeyTable
LogWhy                  Yes
Mode                    sv
PidFile                 /var/run/opendkim/
SignatureAlgorithm      rsa-sha256
SigningTable            refile:/etc/opendkim/SigningTable
Socket                  inet:8891@localhost
Syslog                  Yes
SyslogSuccess           Yes
TemporaryDirectory      /var/tmp
UMask                   022
UserID                  opendkim:opendkim
Create the file /etc/opendkim/KeyTable:
vi /etc/opendkim/KeyTable
Make sure your file that looks like this:
The KeyTable file tells OpenDKIM where to find your keys. Each entry in the KeyTable file is a single line for each key location (for example, all of the text in the above example should be on a single line in your file). If you're going to use multiple keys (to sign mail for virtual domains with different keys), you'll need to create a separate line in the KeyTable file for each domain.
Create the file /etc/opendkim/SigningTable:
vi /etc/opendkim/SigningTable
Make sure your file that looks like this:
The SigningTable file tells OpenDKIM how to use your keys, as in which senders should use which selectors for their signatures. In the above example, I'm saying that everyone (*) sending mail from the server "" should use the selector named "default." It's important to note that the * wildcard symbol will only work if the SigningTable option uses the refile: prefix before the filename.
Create the file /etc/opendkim/TrustedHosts:
vi /etc/opendkim/TrustedHosts
Make sure your file that looks like this:
The TrustedHosts file tells OpenDKIM who to let use your keys. Because it's referenced by the ExternalIgnoreList directive in your conf file, OpenDKIM will ignore this list of hosts when verifying incoming mail and because it's also referenced by the InternalHosts directive, this same list of hosts will be considered "internal," and OpenDKIM will sign their outgoing mail.
IMPORTANT: Make sure you list the IP address for localhost ( in the TrustedHosts file or OpenDKIM won't sign mail sent from this server. If you have multiple servers on the same network that relay mail through this server and you want to sign their mail as well, they must be listed in the TrustedHosts file. Put each entry on its own line. An entry can be a hostname, domain name (e.g. ""), IP address, an IPv6 address (including an IPv4 mapped address), or a CIDR-style IP specification (e.g. "

9 Edit your Postfix configuration

Add the following lines at the end of your Postfix file, which will make Postfix aware of OpenDKIM and allow it to sign and verify mail:
vi /etc/postfix/
smtpd_milters           = inet:
non_smtpd_milters       = $smtpd_milters
milter_default_action   = accept
milter_protocol  = 2

10 Start OpenDKIM and restart Postfix

Assuming you're using bash, do:
hash -r
to rehash your shell so you can find the init script.
Now let's to stop sendmail from starting on CentOS:
chkconfig --del sendmail
Start OpenDKIM:
service opendkim start
You should get a message that says:
Starting OpenDKIM Milter: [ OK ]
However, if you get an error message such as:
Starting OpenDKIM Milter: opendkim: /etc/opendkim.conf: configuration error at line 5: unrecognized parameter
You probably just mistyped something in one of the config files. Go to the line number of the file listed, and check your work against the example(s) in this HowTo. Then try starting up OpenDKIM again.
Once it starts, restart Postfix with:
/etc/init.d/postfix restart
If everything looks good, let's run chkconfig on OpenDKIM to make sure it starts when you boot your server:
chkconfig --level 2345 opendkim on
If you get some errors, try some of these startup troubleshooting tips before moving on.

11 Startup troubleshooting tips

Tip 1: The best place to start troubleshooting any mail issues (including OpenDKIM) is to check your maillog file:
tail -f /var/log/maillog
while you're starting, stopping, and/or restarting OpenDKIM and Postfix. This allows you to see more details about any errors in your configuration.
Tip 2: To get the most verbose information from OpenDKIM, make sure the LogWhy option in your /etc/opendkim.conf file is uncommented and set to Yes. If your outgoing mail isn't getting signed and you want to know why, this should tell you.

12 Adding DNS Records

Now that your mail server is signing outgoing mail and verifying incoming mail, you'll need to put some information in your DNS records to tell other mail servers how your keys are set up, and provide the public key for them to check that your mail is properly signed.
cat /etc/opendkim/keys/
The output should look something like this:
default._domainkey IN TXT "v=DKIM1; g=*; k=rsa; p=7k45u5i2T1AlEBeurUbdKh7Nypq4lLMXC2FHhezK33BuYR+3L7jxVj7FATylhwIDAQABMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHY7Zl+n3SUldTYRUEU1BErHkKN0Ya52gazp1R7FA7vN5RddPxW/sO9JVRLiWg6iAE4hxBp42YKfxOwEnxPADbBuiELKZ2ddxo2aDFAb9U/lp4" ; ----- DKIM default for
Now create a DNS record for your domain and paste the entire contents of the /etc/opendkim/keys/ file at the bottom of your domain's zone file, the TXT Name would default._domainkey and the TXT Value would be everything inside the quotes (starting with v=). You can ignore the semi-colon and comments at the end.
Make sure you follow the instructions of your DNS provider for adding a new TXT Record to your domain.
Now might be a good time to ensure that you already have a valid SPF Record in place. Having both DKIM and SPF in place will increase your chances of having your outgoing mail successfully delivered.

13 Testing your setup

The best way to see that everything is working on the server side is to keep an eye on your /var/log/maillog file.
tail -f /var/log/maillog
When OpenDKIM starts (or restarts), you should see lines like:
opendkim[4397]: OpenDKIM Filter: mi_stop=1
opendkim[4397]: OpenDKIM Filter v2.4.2 terminating with status 0, errno = 0
opendkim[27444]: OpenDKIM Filter v2.4.2 starting (args: -x /etc/opendkim.conf)

When you send a mail that gets successfully signed, you should see:
opendkim[22254]: 53D0314803B: DKIM-Signature header added
The best way to check that your signed mail is being authenticated and that your DNS records are properly set up is to use one of the free testing services:
- Send a signed email to:
- Send a signed email to:
Each of these services will return an email telling you if things are working properly, and give you some pointers on troubleshooting if needed.

14 Upgrading OpenDKIM

If you would like to upgrade to a newer version of OpenDKIM, simply download the updated version and follow the guide to compile and install OpenDKIM with these steps:
tar zxvf opendkim-2.4.2.tar.gz
cd opendkim-2.4.2
./configure --sysconfdir=/etc --prefix=/usr/local --localstatedir=/var
make install
This will upgrade your OpenDKIM and keep your existing configuration intact. Remember to restart OpenDKIM after your upgrade with:
/etc/init.d/opendkim restart
Then verify that the newer version started up with no problems:
tail -f /var/log/maillog

15 Links -- The official site for DomainKeys Identified Mail. -- OpenDKIM Project Site. -- A very good spam-fighting technique that you should be using if you're sending email.

No comments:

Post a Comment