How to Setup DomainKeys Identified Mail (DKIM) with Postfix and Ubuntu Server

If your mail is always ending up in the "Junk" folder (Yahoo is well known for this), take a look at DomainKeys Identified Mail (DKIM). Your email server will sign every outgoing message with a cryptographic private key. Your DNS server is setup with TXT record in the email's domain that contains a matching public key. The receiving end will take the two keys, and determine if they are a match, thus authenticating your email server.

The implementation is very straight forward with Ubuntu Server.

Requirements

  • Tested with Ubuntu Server LTS 8.04.3 or later
  • Postfix 2.5 or later installed and running
  • BIND 9.0 or later installed and running
  • Webmin 1.500 or later
  • Remote login to the root account is enabled (using PKI or password)
  • Your Domain, Email, and DNS are working properly

The setup was done remotely and graphically on a Windows Machine using WinSCP and PuTTY

Install The Software

Sign on to your Ubuntu server through Webmin and go to the "Software Packages" section under "System". Select the "Package from Apt" radio option and type in "dkim-filter" into the box. Then click "Install".

It should take a few minutes to download and install the software. Due to a small bug in the package, it's safe to ignore the installation error at the end of the process.

Configure dkim-milter

Log into your Ubuntu server (as root) using WinSCP (a Windows based SFTP and SSH program), navigate to and open the file named "/etc/dkim-filter.conf".

Un-Comment the "KeyList" option at around line 38 so that it looks like this:

KeyList		/etc/dkim-keys.conf

Save and close the file.

The "/etc/dkim-keys.conf" file is where we will specify the domains we want to sign, the selector used, and the private keys used to sign them with.

Next, take a peek at the "/etc/default/dkim-filter" and note the default port number used for the INET socket.

SOCKET="inet:8891@localhost" # Ubuntu default - listen on loopback on port 8891

No changes need to be made to this file.

Generate Domain Keys

The next step is to generate the private and public key pairs for your domain(s). We will store these keys in the "/etc/mail/dkim/keys/domain.tld/" folder as "default" for the private key and "default.txt" for the public key that gets used in the DNS server. To generate the keys we will use the handy-dandy "dkim-genkey" program.

Replace "domain.tld" with your email domain name. If you host multiple domains, repeat these commands for each domain you wish to enable the feature on.

Sign on to your Ubuntu server through SSH with PuTTY (as root) and execute the following commands:

mkdir -p /etc/mail/dkim/keys/domain.tld
cd /etc/mail/dkim/keys/domain.tld
dkim-genkey -r -d domain.tld
mv default.private default

Go back to WinSCP and create a new file "/etc/dkim-keys.conf".

Each line of the file follows a simple format, "pattern:domain:selector". The "pattern" is almost always going to be "*@domain.tld", the "domain" field is self explanatory. However, the "selector" can be elusive as this field sets up 2 options.

DKIM allows you to have multiple keys for a domain, the selector "chooses" which one to sign outgoing mails with. The "selector" field acts as both the path to the key file and the name of the selected key (which is used later on in DNS). We created all our initial keys in a file named "default" for each domain. You could have named it anything, and you could create additional keys/files for each domain under a different file name. Each file name is the name of the "selector".

For our example, add the following line to "/etc/dkim-keys.conf". Remember to replace "domain.tld" with your domain. If you have multiple domains add one line for each domain.

*@domain.tld:domain.tld:/etc/mail/dkim/keys/domain.tld/default

The line above tells dkim-milter to sign all emails for the domain.tld domain with the private key located in "/etc/mail/dkim/keys/domain.tld/default" using the selector named "default".

Save and close this file when done.

Configure Postfix

Here we link dkim-milter to Postfix, it's done with a few lines.

Open your "/etc/postfix/main.cf" in WinSCP or use the Postfix module in Webmin to edit the configuration file and add the lines as shown below.

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

Save and close the file.

Enable and Start the Software

Using Webmin, go to the "Bootup and Shutdown" configuration under "System. Locate the "dkim-filter" line and place a check in it's box. Scroll down to the bottom and click on the "Start Now and On Boot" button. Next, locate the "postfix" line, check the box and click the "Restart" button at the bottom.

Their should be no start up errors on either.

Take a quick look at the system log (File /var/log/syslog) by using the "Systems Logs" module under "System" and verify that their are no errors.

Add DNS Records

This last step assumes you are using BIND on your Ubuntu Server. If you use alternate DNS management software (provided by your ISP or hosting), please consult it's documentation on how to add a TXT record to your domain.

This is the glue that ties it all together. Without a DNS record, your DKIM setup is completely non-functional.

The TXT record that you will add is conveniently pre-generated for you in "/etc/mail/dkim/keys/domain.tld/default.txt". Open this file with WinSCP, copy the entire contents of that file, and paste it at the end of your zone records file. Use the "BIND DNS Server" module under "Servers" in Webmin. Open your DNS zone and click "Edit Records File".

You should have something similar to the following:

domain.tld.	IN	SOA	ns.domain.tld. root.domain.tld. (
1125170171
10800
3600
604800
38400 )
domain.tld.         IN NS ns.domain.tld.
mail.domain.tld. IN A 123.156.189.123
ns.domain.tld.         IN A 123.156.189.124

default._domainkey IN TXT "v=DKIM1; g=*; k=rsa; p=000000000EBAQUAA4GNADCBiQKXXXXXXXX..." ; ----- DKIM default for domain.tld

Save the records file and reload your zone information by clicking on the "Apply Zone" link at the top right.

Notice the name of the selector in the TXT record "default._domainkey...". For each key file (aka "selector") located in "/etc/mail/dkim/keys/domain.tld/" and "/etc/dkim-keys.conf", you will have a corresponding DNS TXT record. Having the ability to use multiple keys and "select" one, improves security.

Send an Email

You're all set!

Send your self a test email then look at the message source code. You'll see a header named "DKIM-Signature:" that verifies everything is working properly on the mail server's end.

Send your self a test email to a gmail account, open the message in gmail and view the message details. Look for the field "signed-by domain.tld" where "domain.tld" is your domain name. This verifies that everything is functional.