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

Version 1.0
Author: Eladio Martinez <[email protected]>

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 -U -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:[email protected]
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. "

Share this page:

Suggested articles

14 Comment(s)

Add comment


By: Jay

The command

useradd -r -g -s /sbin/nologin opendkim

generates the error:

useradd: group '-s' does not exist

on centOS 6.4


By: Daniel S

Use -U instead of -g

By: Steven

If you get an error while configuring like "configure: error: no strlcpy/strlcat found" then you will need to install the libbsd packages.

yum install libbsd.x86_64 libbsd-devel.x86_64

By: Angel

Hey there, how can I install Dkim in my server, I setup my server using this tutorial:


Thanks in advance

By: Me

Thanks for this guide, worked like a charm.

I got an error regarding de compiler which was solved by installing the development package:

yum groupinstall "Development Tools"



Thank you. It helps us a lot setting this up.

By: Vali

This command:

/usr/local/bin/opendkim-genkey -D /etc/opendkim/keys/ -d -s default

generates the error (with the -- currently -- latest version of OpenDKIM - 2.10.3 and CentOS 6.7 Final):

bash: /usr/local/bin/opendkim-genkey: No such file or directory


The correct command should be:

/usr/local/sbin/opendkim-genkey -D /etc/opendkim/keys/ -d -s default  (the binary is in sbin, not bin)


Thanks for the guide. Really useful.

By: j

i have tried your recommendation and i still get the no such file error. I have opened up filezilla and looked for the folder/file as will and there is nothing


did i miss a step?

By: mb

Excellent tutorial - worked fine for me with CentOS7.  However, I do have selinux enabled so there are few things one needs to do to make opendkim work from step 10 (Start opendkim and restart postfix).

The standard SELinux expected location for the binaries (see is /usr/sbin, whereas here the binaries are built to /usr/local/sbin. So you need

semanage fcontext -a -t dkim_milter_exec_t "/usr/local/sbin/opendkim"

restorecon -v /usr/local/sbin/opendkim 

Otherwise, the opendkim process doesn't have the correct process type and thus the correct selinux "profile" to access the files it needs to, as well as to become a listener on its correct port 8891.

I also had to:

mkdir /var/run/opendkim

restorecon -Rv /var/run/opendkim

You may also find you have to "allow" port access (I think this depends on the history of the server, so I accept some may not need this):

semanage port -a -t milter_port_t -p tcp 8891

Hope this helps (2016-04-08)


By: joe

Is it any special reason to compile opendkim 2.4.2 from source instead of using opendkim 2.10.3 from epel library? I'm hoping it's just that this article is old (don't see any date, only hint is rhel6.3)


By: till

The article is for RHEL / CentOS 6.3 as mentioned in the text. If you use CentOS 7, then better use the EPEL package.

By: Kade

Thanks for the step-by-step tutorial. Thanks also to those who posted update comments for later versions.

By: christian

I run the commands from Jay, and copy the default.private key to /etc/opendkim/keys/ (mv /etc/opendkim/keys/ /etc/opendkim/keys/ doesn´t work properly), and add milter_protocol 2 to from postfix (i´m using centos 6.9); and after that it works.

By: ashwin

./configure --sysconfdir=/etc --prefix=/usr/local --localstatedir=/var line doesn't works, it shows error as :


checking for library containing ERR_peek_error... none required

checking for library containing SSL_library_init... none required

checking whether SHA256_DIGEST_LENGTH is declared... yes


checking for milter library and includes... configure: error: milter not found

please let me how can i install