msgbartop
MAC OS X, Linux, Windows and other IT Tips and Tricks
msgbarbottom

15 Mar 13 Installing OpenDKIM in Debian Squeeze/Wheezy

Introduction
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.

Principle
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.

References
These instructions are inspired from the helpful site //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 //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
Content:
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:
127.0.0.1
localhost
x.253.204.64
x.253.204.32/27

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:127.0.0.1:12345
non_smtpd_milters = inet:127.0.0.1:12345

Note: In the above configuration I use 127.0.0.1 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.
127.0.0.1:10025 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.
Principle:
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)
eg.
add_domains_opendkim example.com example.de example2.com

Script: /root/bin/add_domains_opendkim
Content:
#!/bin/bash
# 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
fi
#
# 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
else
mkdir -p /etc/opendkim/keys
fi
#
# 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
else
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 *** ---------------------------"
result=true
fi
done
#
# 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(//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’
Command:
dig default._domainkey.itmatrix.eu TXT
Result:
.......
;; ANSWER SECTION:
default._domainkey.itmatrix.eu. 600 IN TXT "v=DKIM1\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/H98o5XmzkUtnvvtZ0+T64xsKNYsWXOXLi0xkQdqK0tq18CV0rZT1+uCqQmov/uoS/RgxE5omvNuzFJR8zt4WPHORGe+UeZr9h0q/eEntmIhx9Sg1vWREKeZcDw0sUMzZRMN0/GrjVdZYKH89vfJeL0awtqkQ4h8Sbonbwh3u2QIDAQAB"
.......

Reader's Comments

  1.    

    For squeeze, you really want to use the opendkim version in backports.

    Reply to this comment
  2.    

    This works perfect, some of the best OPENDKIM setup posts I’ve found. Thousands of tanks for that 🙂

    Reply to this comment
  3.    

    Great article. Thanks a lot for that

    Reply to this comment
  4.    

    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 [209.85.212.171] not internal

    Reply to this comment
  5.    

    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.

    Reply to this comment
    •    

      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)
      dig
      In the section
      ;; AUTHORITY SECTION:
      is where you would find the DNSs that are Authoritative of your domain.
      or the command
      whois

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

      Reply to this comment
      •    

        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.

        Reply to this comment
        •    

          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.

          Reply to this comment
          •    

            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.

          •    

            Very welcome.

  6.    

    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

    Reply to this comment
  7.    

    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!

    Reply to this comment
    •    

      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.

      Reply to this comment

Leave a Reply to admin Cancel reply

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

%d bloggers like this: