I'm running Ubuntu 12.04 with Postfix and Mailman. I want to set up DKIM. DomainKeys Identified Mail, or DKIM, is the successor to Yahoo's "DomainKeys". It incorporates Cisco's Identified Mail.

What are the steps for setting this up?

Is opendkim recommended?

The only reference I have is HowToForge, but I prefer to get help here (even if it is just a confirmation of the steps at that link). Actually, I think the info at HowToForge is outdated because it mentions dkim-filter instead of opendkim.


openDKIM and Postfix on Ubuntu Server 12.04LTS

I'll try to come back and format this better. But since there was a request to post my answer, I wanted to post it now rather than wait until I had time to format it properly. Due to lack of time, I wrapped my entire answer in a blockquote. I hope this solution is helpful.

These are my references:

and Wikipedia has a good entry on the subject

At a minimum you will need:

  • Root access to your mail server
  • Access to update the dns records for your domain

Install opendkim from the repositories:

# sudo apt-get install opendkim opendkim-tools

You must decide on what “selector” you wish to use. The selector is essentially a word to describe the key you wish to use. Here I am going to use the selector 201205 as the key became valid in May 2012 (cunning eh?). I give two examples for variety, which will hopefully add clarity. You only need to generate ONE key. However, I am giving both examples so you can compare them.

  • 201205 (1st key)
  • my_selector (2nd key)

My domain will be example.com, but I'll use a subdomain for my second example:

  • example.com (1st key)
  • mail.example.com (2nd key)

I decided to work in the following directory:

# mkdir /etc/opendkim/
# cd /etc/opendkim

Generate the keys in the current directory, using your chosen selector and domain.

# opendkim-genkey -s 201205 -d example.com

You may or may not need to change ownership. See details in my example for the 2nd key below for what ownership and permissions should be.

First you should check if there is a opendkim user (your user/group IDs may be different):

# grep opendkim /etc/passwd

And you probably need to do this:

# chmod 700 /var/run/opendkim

NOTE: These next two commands are NOT needed on Ubuntu 12.04. But if the command above didn't show that user opendkim was set up properly, do it similarly to this:

# useradd -r -g opendkim -G mail -s /sbin/nologin -d /var/run/opendkim -c "OpenDKIM" opendkim
# chown opendkim:opendkim 201205.private   
# cat 201205.private 
ABCCXQ...[long string]...SdQaZw9

Now check the public key and notice that there is a bug (in openDKIM 2.5.2 on Ubuntu 12.04)! Where is contains, ;=rsa;, it should contain ;k=rsa;. The k is missing. Please insert it.

# cat 201205.txt
201205._domainkey IN TXT "v=DKIM1;=rsa; p=WIGfM..[snip]..QIDIAB" ; ----- DKIM 201205 for example.com

After being fixed, it will look like this:

201205._domainkey IN TXT "v=DKIM1;k=rsa; p=WIGfM..[snip]..QIDIAB" ; ----- DKIM 201205 for example.com

Furthermore, you probably need to escape the semicolons like this. If you don't want the ending comment, just delete it. Also note that you should add the t=y flag to indicate to receiving servers that you are testing DKIM but not actively using it yet. You are left with a viable resource record:

201205._domainkey IN TXT "v=DKIM1\;k=rsa\;t=y\;p=WIGfM..[snip]..QIDIAB"

You must publish the content of the above public key to your authoritative DNS server. I recommend using a TXT record. There seems to be a bit of controversy on whether to use an SPF record or both types. After a bit of reading, I elected to stick with the TXT record type exclusively, although I don't believe this is the final word on this topic.

You should use a short TTL (time to live) so that you can change the key without waiting ages for it to propagate though DNS. I used 180 seconds.

The second example of generating a key pair was a bit trickier for me. I'll describe what I did. The first element is that I used the domain value "example.com" even though the key will be used for "mail.example.com". I arrived at this via trial and error. It works, while using "mail.example.com" did not work. Unfortunately, I am not aware of the reasons behind this. This is really the only difference I encountered, but it was troubling enough that I felt I should document my experiences with using subdomains. None of the other beginning level tutorials I found did this. Generate a second key:

opendkim-genkey -s my_selector -d example.com

check ownership and permissions of the private key, as above. Here's what they should look like:

# ls -la /etc/opendkim
-rw-------  1 opendkim opendkim  891 May 10 07:44 my_selector.private

After publishing the DNS record, check it with dig. It should return exactly what you entered in the resource record (RR).

$ dig 201205._domainkey.example.com txt +short

Now, test the key. The commands below assume you are in the directory where the key resides (/etc/opendkim for me).

# opendkim-testkey -d example.com -s 201205 -k 201205.private -vvv
opendkim-testkey: key loaded from /etc/opendkim/201205.private
opendkim-testkey: checking key '201205._domainkey.example.com'
opendkim-testkey: key not secure
opendkim-testkey: key OK

These results are expected. The "key not secure" does not indicate an error. It is an expected consequence of not using DNSSSEC. DNSSEC is coming, but it isn't ready for prime time yet, according to my reading.

Example with 2nd key:

# opendkim-testkey -d example.com -s my_selector -k /etc/opendkim/my_selector.private -vvvv
opendkim-testkey: key loaded from /etc/opendkim/my_selector.private
opendkim-testkey: checking key 'my_selector._domainkey.example.com'
opendkim-testkey: key not secure
opendkim-testkey: key OK

Note that opendkim is reporting that the key is not secure. This relates to the fact that DNSSEC is not implemented on my DNS server and theoretically somebody could intercept the DNS lookup and replace it with their own key.

Edit the OpenDKIM config file:

# nano /etc/opendkim.conf
# cat /etc/opendkim.conf
# This is a basic configuration that can easily be adapted to suit a standard
# installation. For more advanced options, see opendkim.conf(5) and/or
# /usr/share/doc/opendkim/examples/opendkim.conf.sample.
Domain                  example.com
KeyFile                 /etc/opendkim/201205.private
Selector                201205
# Commonly-used options
Canonicalization        relaxed/simple
Mode                    sv
SubDomains              yes
# Log to syslog
Syslog                  yes
LogWhy                  yes
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
UMask                   022
UserID                  opendkim:opendkim
KeyTable                /etc/opendkim/KeyTable
SigningTable            /etc/opendkim/SigningTable
ExternalIgnoreList      /etc/opendkim/TrustedHosts
InternalHosts           /etc/opendkim/TrustedHosts
Socket                  inet:8891@localhost

If you are using my 2nd key example, with the targeted domain “mail.example.com” the entry would still only reference the main domain:

Domain                  example.com
KeyFile                 /etc/dkim/my_selector.private
Selector                my_selector 

Note from one of my sources: If you run multiple instances of Postfix you need to add this to the opendkim.conf for each instance (or the ones you want to use opendkim)

Create a file with your text editor /etc/opendkim/TrustedHosts:

Add domains, hostnames and/or ip’s that should be handled by OpenDKIM. Don’t forget localhost.
mail.example.com #(IP address of your server, if applicable)

(the last line above probably won't be needed. If you do have an IP address to add, make sure you use your own, not the example above.)

Edit /etc/default/opendkim:

Uncomment this row and use port 8891:

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

Make sure your firewall (iptables) allows loopback on localhost:

sudo iptables -A INPUT -i lo -j ACCEPT

Next, Create a file with your text editor /etc/opendkim/KeyTable and add the domain to the KeyTable

Add line:

#EXAMPLE showing my 2nd key:
my_selector._domainkey.example.com example.com:my_selector:/etc/opendkim/my_selector.private

Next Create a file with your text editor /etc/opendkim/SigningTable and add the domain to the SigningTable

I show both examples. Note that for my 2nd key, I now have to use the full domain name "mail.example.com":

example.com 201205._domainkey.example.com
mail.example.com my_selector._domainkey.example.com

Note that in OpenDKIM 2.0.1 domain names are case sensitive. In this example we're using a newer version of OpenDKIM and this does not appear to be a problem.

Configure postfix. Edit /etc/postfix/main.cf and add the lines to the end

milter_default_action = accept
milter_protocol = 2

Also change the hostname:

#myhostname = localhost         #original
myhostname = mail.example.com

You should also change the corresponding entry in /etc/hosts. These changes are effective after a reboot (although you can set it immediately with the command: hostname NEW_NAME).

Restart postfix and opendkim if you didn't reboot:

# service opendkim restart
Restarting OpenDKIM: opendkim.
# service postfix restart
 * Stopping Postfix Mail Transport Agent postfix   [ OK ]
 * Starting Postfix Mail Transport Agent postfix   [ OK ] 


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. I used these:

  • Brandon Checketts Email Validator - http://www.brandonchecketts.com/emailtest.php (my favorite)
  • Send a signed email to: check-auth@verifier.port25.com (my favorite also)
  • Send a signed email to: sa-test@sendmail.net (you can put all of the test email addresses in the To: field of a single outgoing message to test)

  • Send a signed email to: autorespond+dkim@dk.elandsys.com <--- BROKEN!!! Don't use this one.

Each of these will tell you if things are working properly, and give you some pointers on troubleshooting if needed.

If you have a Gmail account, you can also send a signed message there for a quick and easy test.

Once you are happy that all is well, you can remove the testing flag in the DNS TXT record and increase TTL.


  • Works perfectly on precise. Good walkthrough thanks.
    – Aki
    Oct 9 '13 at 10:35
  • Use -b 1024 to generate keys of 1024 bits. Its a must for getting signed my gmail ! Apr 16 '14 at 12:07
  • 1
    Please note in opendkim.conf the three parameters "Domain", "KeyFile" and "Selector" are ignored when using the "SigningTable" and "KeyTable". Not sure if this changed at some point but it's worth mentioning (opendkim.org/opendkim.conf.5.html)
    – billynoah
    Jul 2 '14 at 5:48

This is a good guide.

It explains that opendkim is indeed recommended and that the steps to implement your dkim signing are the same as with dkim-filter.

dkim-milter is no longer being developed. It's original author has forked the source and is now developing opendkim. For Lucid and later releases, opendkim is preferred over dkim-filter. The instructions on this page should be the same (just with adjusted package names as needed).

BTW Domainkeys is the deprecated predecessor of DKIM. Add TXT records to your DNS Zone for SPF and DKIM but it's no longer necessary to bother with Domainkeys.

  • That article you linked is out of date. opendkim is the package to use now. I'm working through setting it up...
    – MountainX
    May 12 '12 at 19:04
  • I'd value an update from your experiences as I am about to switch a server from Exim4 over to Postfix-Dovecot and will be looking for up-to-date guidance.
    – iainH
    May 13 '12 at 13:50
  • I posted my solution but I didn't have time to format it. You (or anyone else) is welcome to format it. But my notes are very extensive, so I wanted you to have access to them without delay. I hope they are helpful.
    – MountainX
    May 13 '12 at 18:56


I always make sure to cross ref a few guides on anything. This tut on set-up works, I just verified it and it validates this one. But, you might want to display an example TXT for the domain record to be detailed. People might get confused and explicitly put everything of the key itself into the p value, which I am not entirely sure is correct. ie...including -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- . That may lead some to be confused. Just make sure to put just the encryption part and not the markers.

  • 3
    Welcome to Ask Ubuntu! Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.
    – Braiam
    Oct 2 '13 at 13:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.