Updated : Mar 15, 2013 in Linux

Installing OpenDKIM in Debian Squeeze/Wheezy

Lately my mail server started to get refusals of emails from large mailing systems like AOL, Yahoo etc.
I can’t blame them for trying to minimize the SPAMS to their clients.
Although using an approved relay service is a good solution,
if you want to take care of it yourself here is OpenDKIM at the rescue.

The mail server sends an email with an individual domain key in the mail header. The receiving server checks the key in the header against the one in the DNS record of the sender’s domain. If they match the email is seen as legitimate email.

These instructions are inspired from the helpful site http://blog.tjitjing.com/index.php/2012/03/guide-to-install-opendkim-for-multiple-domains-with-postfix-and-debian.html and expanded with a script. They relate only to the installation of the standard Debian Squeeze version.

Installation of DKIM
The standard Debian Squeeze version of openDKIM is about 2 years old but works well. If you want to install the latest version though you could get it from compile it yourself at http://packages.debian.org/source/squeeze/opendkim.

1.Install the Debian Squeeze openDKIM package
apt-get install opendkim
or if in Debian Wheezy
1.Install the Debian Wheezy openDKIM and its tools package
apt-get install opendkim opendkim-tools

2. Edit /etc/opendkim.conf
KeyTable /etc/opendkim/KeyTable
SigningTable /etc/opendkim/SigningTable
ExternalIgnoreList /etc/opendkim/TrustedHosts
InternalHosts /etc/opendkim/TrustedHosts
# Optional - To show more information in logs
LogWhy yes

3. Create the config directories and files
mkdir -p /etc/opendkim/keys
touch /etc/opendkim/KeyTable
touch /etc/opendkim/SigningTable
touch /etc/opendkim/TrustedHosts

4. Edit /etc/opendkim/TrustedHosts
Note: Here you enter all domains, hostnames and/or ip’s / Subnets that should be handled by OpenDKIM.
Don’t forget localhost.
Content example:

5. Edit /etc/default/opendkim
Uncomment this line:
SOCKET="inet:12345@localhost" # listen on loopback on port 12345

6. Edit /etc/postfix/main.cf
Add the following lines
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:
non_smtpd_milters = inet:

Note: In the above configuration I use instead of ‘localhost’ to prevent the following warning in the logs.
warning: connect to Milter service inet:localhost:12345: Connection refused
The reason being that in Wheezy Postfix sees the IPv4 and IPv6 of ‘localhost’ and tries 2 times in which the try at IPv6 fails with this warning.

6. Edit /etc/postfix/master.cf
Add the following option ‘,no_milters‘ at the end of the line: eg. inet n - n - - smtpd
# .... Here I didn't show all the options which are irrelevant for this issue.....
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters

7. Generating individual domain keys and configuring OpenDKIM for per domain.
I order for Postfix/OpenDKIM to send/verify a key in each email’s header for which DKIM should be used, the following needs to be done per domain:
– Create a domain private key and configure OpenDKIM so it adds(outgoing) or verify the key(incoming) in the email’s header.
– Generate a domain key and add it to the Free-Text DNS record of the domain.

Here you have 2 choices:
– The easy method(using a script like the one below)
– The hard method(Manually)

The easy method

1. Run this script which generates the DKIM Key and configures OpenDKIM for each domain given.
Command: add_domains_opendkim <DomainName> [DomainName] [DomainName] …..
DomainName should be the root domain (without the www)
add_domains_opendkim example.com example.de example2.com

Script: /root/bin/add_domains_opendkim
# Authors: Pierre Burri-Wittke/Michel Bisson
# 9. March 2013
# Purpose: Generates DNS-Txt keys and configures OpenDKIM for one or multiple domains
# Verifying the entries
if [ "$#" -lt 1 ]; then
echo "ERROR: Wrong number of parameters"
echo "Usage: add_domains_opendkim [DomainName] ....."
echo "eg. add_domains_opendkim example.com example.de example2.com"
exit 1
# Checking if OpenDKIM is installed and if yes creating the necessary data directory
if ! [ -d /etc/opendkim ]; then
echo "ERROR: The package OpenDKIM is not installed. Install it and rerun this command."
exit 2
mkdir -p /etc/opendkim/keys
# Verifying the given domains and skip them if errors or already configured
for domain ; do
# Check the mail handling resolving
if ! (host $domain | grep -q 'is handled by'); then
echo "Domain $domain doesn't resolve well. Skipping"
echo "Output:"
host $domain
# Check if the domain is already configured in openDKIM
elif (grep -q "$domain default._domainkey.$domain" /etc/opendkim/SigningTable); then
echo "Domain $domain is already configured in /etc/opendkim/SigningTable. Skipping"
elif (grep -q "$domain default._domainkey.$domain" /etc/opendkim/KeyTable); then
echo "Domain $domain is already configured in /etc/opendkim/KeyTable. Skipping"
# All ok, then generate the key and configure OpenDKIM
mkdir /etc/opendkim/keys/$domain
echo " "
echo "Generate the keys..."
cd /etc/opendkim/keys/$domain
opendkim-genkey -r -d $domain
chown opendkim:opendkim default.private
ls -l /etc/opendkim/keys/$domain
echo " "
echo "Adding following lines in /etc/opendkim/KeyTable & /etc/opendkim/SigningTable"
echo " default._domainkey.$domain $domain:default:/etc/opendkim/keys/$domain/default.private"
echo "default._domainkey.$domain $domain:default:/etc/opendkim/keys/$domain/default.private" >> /etc/opendkim/KeyTable
echo " $domain default._domainkey.$domain"
echo "$domain default._domainkey.$domain" >> /etc/opendkim/SigningTable
echo " "
echo "-------------------- TODO ----------------------"
echo "Now copy the record below in your DNS (until the end of the domain! Do not include lines with '***')"
echo "DNS: Free Text Entries/freier Textentraege of domain "
echo " "
echo "*** $domain *** ---------------------------"
cat /etc/opendkim/keys/$domain/default.txt
echo "*** $domain *** ---------------------------"
# Restart OpenDKIM if at least one new domain was registered in OpenDKIM
echo " "
if $result ; then /etc/init.d/opendkim restart ; fi

Now the hard Method…Manual

1. Generate key
(example here with domain: domain.com)
mkdir -p /etc/opendkim/keys/mydomain.com
cd /etc/opendkim/keys/mydomain.com
opendkim-genkey -r -d mydomain.com
chown opendkim:opendkim default.private

2. Add domain to KeyTable /etc/opendkim/KeyTable
nano /etc/opendkim/KeyTable
Add line:
default._domainkey.mydomain.com mydomain.com:default:/etc/opendkim/keys/mydomain.com/default.private
3. Add domain to SigningTable /etc/opendkim/SigningTable
nano /etc/opendkim/SigningTable
Add line:
mydomain.com default._domainkey.mydomain.com
4. Display the DNS key
cat /etc/opendkim/keys/mydomain.com/default.txt

Restarting OpenDKIM:
/etc/init.d/opendkim restart

Note: In OpenDKIM 2.0.1 domain names are case sensitive (supposed to be fixed from 2.3.1 but I have not tested).
This means that in the above example an email from info@mydomain.com will be signed, but an email from info@MyDomain.com will not be signed.
The workaround is to add one extra entry for MyDomain.com to SigningTable.

The DNS entry

Whether you are using the easy way (script) or the manual way you still have to enter the key in DNS manually for each domain.
This key, displayed by the above script or by the step 4 in manual mode, is a single line and looks like this:
default._domainkey IN TXT "v=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4....long hash.......PBODxsDCEJwHEyFpQIDAQAB" ; ----- DKIM default for mydomain.comYou need to enter the full line in a Free Text record of the domains DNS.

Note 1: Together with SPF authentication(http://www.openspf.org/SPF_Record_Syntax) this should present a very good email authentication method.

Note 2: Although the OpenDKIM configuration file offers the possibility of authenticating sub domains senders(SubDomains yes), in this version it doesn’t seem to work at all. For example, when a mail is sent from a system user in the mail server, it will be identified as user@mail.server.com and not user@server.com for which DKIM is configured. I don’t know if this feature is working in the newer versions though.

Verifying the DKIM DNS record

Example for the domain ‘itmatrix.eu’
dig default._domainkey.itmatrix.eu TXT
default._domainkey.itmatrix.eu. 600 IN TXT "v=DKIM1\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/H98o5XmzkUtnvvtZ0+T64xsKNYsWXOXLi0xkQdqK0tq18CV0rZT1+uCqQmov/uoS/RgxE5omvNuzFJR8zt4WPHORGe+UeZr9h0q/eEntmIhx9Sg1vWREKeZcDw0sUMzZRMN0/GrjVdZYKH89vfJeL0awtqkQ4h8Sbonbwh3u2QIDAQAB"


    1. I don’t know why this could be so, but definitely with newer versions of the package more likely it will perform better.
      Thanks for the info.

  • After installing and configuring OpenDKIM whenever the server is receiving an email it throws this message in the log.

    opendkim[25102]: 92829D80435: mail-wi0-f171.google.com [] not internal

  • Great tutorial. Thanks for that. I am stuck&lost at “You need to enter the full line in a Free Text record of the domains DNS.” I have no clue which Domains DNS *could it be where i bought my domain name? or is it somewhere on my own server? Thanks for helping out.

    1. Hi Franky
      The DNS is a/are separate server(s). Most likely run by the provider where you registered your domain, unless you took over the Authority of your domain and running your own DNSs (very unlikely since you are asking about it). To find out which company/DNS is Authoritative of your domain, you can issue the following command in a linux terminal:(eg. on your server)
      In the section
      is where you would find the DNSs that are Authoritative of your domain.
      or the command

      That can maybe give you a hint of the registrar where your domain was registered.
      Good luck. Michel

      1. Hi Michel,
        Thank you for your reply. I am currently using Domainnameshop’s name servers and i cannot figure out where to enter the full line key in the Free Text Record of the domain DNS. Where is that “Free Text Record”? I cannot see any such options to enter text when logged in my account at the name server’s options- Domainnameshop.

        1. Hi Franky,
          well I don’t have an account at this domain provider and each web interface for DNS editing have their own format and methods for making DNS changes, but basically if you can enter a ‘TXT’ type DNS recird for your domain that’s it. You might need to add quotes before and after your entry, but its a standard ‘TXT’ type record in DNS. Good luck.

          1. Hi Michel.
            I think i managed to do it, but im not sure if its correct though. Anyhow, my DNS records now show a TXT with the pasted values from my DNS key, with a TTL of 1 week!!

            Many thanks for your help.

  • hello

    i installed with your tuto
    now my emai ldon’t send
    i have this message in mail.err
    opendkim[26489]: 059401A6609: no signature data

    can you help me

  • Hi!

    I got an error. Until this point everything looked good ( I use manual hard method) and Ive used this tutorial in the past and it work without any problem. What should I do?

    root@mail:/etc/opendkim/keys/sample.tld# opendkim-genkey -r -d sample.tld
    -bash: opendkim-genkey: command not found

    Thank you!

    1. I got it, I didnt use the Debian Wheezy apt-get install opendkim opendkim-tools

      So I removed opendkim and installed both opendkim opendkim-tools, now it works.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: