Signing Email with Domainkeys and DKIM

I am the administrator of several high volume email servers.
All of these servers use Domainkeys and DKIM to sign outgoing emails. I have put together this HOWTO in an effort to make your life a little easier. If you can’t do it, for some reason, hire me, and I’ll set it up for you.

Why do we need Domainkeys and DKIM?

DomainKeys Identified Mail (DKIM) lets an organization take responsibility for a message while it is in transit. The organization is a handler of the message, either as its originator or as an intermediary. Their reputation is the basis for evaluating whether to trust the message for delivery. Technically DKIM provides a method for validating a domain name identity that is associated with a message through cryptographic authentication.

What Operating System Will we be using?

Any Linux Distribution (Ubuntu, Gentoo, RedHat, Centos)

What software will we be using?

dkim-milter
dk-filter
postfix
openssh

Let’s begin,

First we need to install our Postfix server. This you should already have done.

Install dkim-filter

sudo aptitude install dkim-filter

Simply accept the defaults when the installation process asks questions. The configuration will be done in greater detail in the next stage.

Configure dkim-milter

dkim-milter configuration consists of two files:

/etc/dkim-filter.conf
/etc/default/dkim-filter

Use your favorite editor to edit those files. Here’s an example of /etc/dkim-filter.conf file already edited to suit my needs:

# Log to syslog
Syslog                  yes
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
UMask                   105 # 'id postfix' in your sheel

# Sign for example.com with key in /etc/mail/dkim.key using
# selector '2007' (e.g. 2007._domainkey.example.com)
Domain                  ubuntu.ro
KeyFile                 /etc/mail/dkim.key # See bellow how to generate and set up the key
Selector                mail

# Common settings. See dkim-filter.conf(5) for more information.
AutoRestart             yes
Background              yes
Canonicalization        simple
DNSTimeout              5
Mode                    sv
SignatureAlgorithm      rsa-sha256
SubDomains              no
#UseASPDiscard          no
#Version                rfc4871
X-Header                no

###############################################
# Other (less-standard) configuration options #
###############################################
#
# If enabled, log verification stats here
Statistics              /var/log/dkim-filter/dkim-stats
#
# KeyList is a file containing tuples of key information. Requires
# KeyFile to be unset. Each line of the file should be of the format:
#    sender glob:signing domain:signing key file
# Blank lines and lines beginning with # are ignored. Selector will be
# derived from the key's filename.
#KeyList                /etc/dkim-keys.conf
#
# If enabled, will generate verification failure reports for any messages
# that fail signature verification. These will be sent to the r= address
# in the policy record, if any.
#ReportInfo             yes
#
# If enabled, will issue a Sendmail QUARANTINE for any messages that fail
# signature verification, allowing them to be inspected later.
#Quarantine             yes
#
# If enabled, will check for required headers when processing messages.
# At a minimum, that means From: and Date: will be required. Messages not
# containing the required headers will not be signed or verified, but will
# be passed through
#RequiredHeaders        yes

Actually /etc/dkim-filter.conf is the most important file. It provides our milter with required information about selector (used for DNS requests and email verifications) and used signing key (the key is used for signing the outgoing emails).

Here’s an example of /etc/default/dkim-filter. This file is used to literally connect the milter to MTA:

# Command-line options specified here will override the contents of
# /etc/dkim-filter.conf. See dkim-filter(8) for a complete list of options.
#DAEMON_OPTS=""
#
# Uncomment to specify an alternate socket
# Note that setting this will override any Socket value in dkim-filter.conf
#SOCKET="local:/var/run/dkim-filter/dkim-filter.sock" # Debian default
#SOCKET="inet:54321" # listen on all interfaces on port 54321
SOCKET="inet:8891@localhost" # Ubuntu default - listen on loopback on port 8891
#SOCKET="inet:12345@192.0.2.1" # listen on 192.0.2.1 on port 12345

In my case, this file needs no additional editing.

Now, to tell the Postfix about the existing milter, and where to connect with it, edit your Postfix main.cf file /etc/postfix/main.cf, and append to it’s content the following data:

# DKIM
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891,inet:localhost:8892
non_smtpd_milters = inet:localhost:8891,inet:localhost:8892

Key generation for dkim-milter and it’s setup with DNS

Actually it’s not big deal. Generate an OpenSSL RSA key as you do it always, then move it private part to the location you indicated in your /etc/dkim-filter.conf:

openssl genrsa -out private.key 1024
openssl rsa -in private.key -out public.key -pubout -outform PEM
cp private.key /etc/mail/dkim.key

The DNS record should look like this:

mail._domainkey.ubuntu.ro. IN TXT "k=rsa; t=y; p=PpYHdE2tevfEpvL1Tk2dDYv0pF28/f 5MxU83x/0bsn4R4p7waPaz1IbOGs/6bm5QIDAQAB"

Where everything after p= is actually the content of the public key we generated above, public.key. To use it, strip out the comments inside it, this:

-----BEGIN PUBLIC KEY-----

and this:

-----END PUBLIC KEY-------

Startup and testing

Once configuration above was done, the daemon can be started with:

sudo /etc/init.d/dkim-filter start

If it doesn’t start, search the logs for problems and see what it requires more:

grep -i dkim /var/log/mail.log

Also you can test your config file:

dkim-filter -x /etc/dkim-filter.conf

If you get the error like: dkim-filter: milter socket must be specified Then try manually specifing the socket, in our case it is local:

dkim-filter -x /etc/dkim-filter.conf -p local

Now restart the Postfix MTA, and check for email signing:

/etc/init.d/postfix restart
/etc/init.d/postfix restart

For testing purposes, I recommend you tools like:

* http://www.sendmail.org/dkim/tools
* or just send an email to autorespond+dkim[at]dk.elandsys.com

Tags: , , , , , ,

Leave a Reply