How to enable Domain Keys (DKIM) in Qmail toaster
based mail server install on Debian Linux
Recently the Emails sent by one of the
Qmail mail servers
running on a Debian host started suddenly delivering in Spam
folder in both
Gmail.com and
yahoo.com public mail
services.
This is pretty nasty as many of the websites which used the local
qmail server to deliver emails concerning subscriptions and other
kind of services provided by the websites started ending in
Span and thus many of the users who used their
Yahoo
Mail account and
Google Mail - gmail accounts was unable
to read emails mailed by the various websites forms and scripts
which were sending emails.
You can imagine the negative effect all this "minor" mail issues
had on website visitors count and the overall websites
functionality.
To come up with some kind of solution to this mail issues, I did
quite a lot of research to understand if
Yahoo and Google Mail
services has some kind of
mail server delist form or
some reporting service where one can delist a specific mail
server as a spammer one or get some kind of help, but unfortunately
it seems neither google nor yahoo has any kind of web based way to
remove hosts or ip addresses of legit mail servers who has
mistakenly been recognized as spam servers.
During my efforts to find a solution to the situation I red a lot
of posts and forums online as well as
Google's Bulk Sender
Guidelines, none if it was too helpful though.
The QMAIL server had a proper:
1. MX Record
2. TXT SPF records
3. PTR Record
4. There are proper correct mail message headers
5. Proper mails charset and encoding
6. The mail server IP is not listed anywhere in any mail
blacklists
(e.g. www.mxtoolbox.com/blacklists.aspx / spamhaus.org)
7. A correct SMTP greeting which matched the mail server domain
name
The only thing which was missing on the mail server (checked
against Google's Bulk Sender Guidelines) was a properly configured
DKIM and Domainkeys.
Thus in order to get around the situation I went the way and
configured the qmail server to include and send in the mail header
also
Domain Keys
In this article I will briefly explain step by step how I
configured
Domain keys (DKIM) signing of my mails:
There are few ways
domain keys signing can be implemented
with
Qmail.
1. By patching qmail binaries to support domain keys
signing
I wanted to omit any interventions concerning the well running
qmail install so I decided not to go this way.
Plus there are plenty of add-ons for qmail and as I have no time to
test them the idea not to temper the existing qmail installation
looked wise to me.
2. Use a wrapprer script around qmail-remote that invokes
externally domainkeys binaries
This kind of solution was fitting me better and therefore I took
this route to enable my qmail DKIM signing.
There are few approaches one can take described online:
I tried using the
qmail-dkim-0.2.pl wrapper script following
the exact steps described to be fulfilled to enable my outgoing
mails dkim signature, however for some reason after substituting
the qmail-remote with qmail-dkim.pl and setting the proper
permissions, my outgoing mails failed completely and each mail I
sent was returned back by the
qmail MAILER-DAEMON
-
Use a bash shell script wrapper in
combination with
libdomainkeys's with a
Mail-DKIM-0.39
.
- I gave a try to this approach and
thanksfully it worked after a bit of struggle to tune it up.
Here is what exactly I had to do to in order to have the domain
keys signing to work using the above described qmail-remote.sh
shell script wrapper
1. Install openssl related required debian packages
debian:~# apt-get install openssl libcrypt-openssl-rsa-perl
libcrypt-openssl-bignum-perl \
libmail-dkim-perl
...
2. Create necessery directories and RSA key pairs for
DomainKeys
debian:~# mkdir -p /etc/domainkeys/mydomain.com
debian:~# cd /etc/domainkeys/mydomain.com
debian:/etc/domainkeys/mydomain.com# openssl genrsa -out
rsa.private_default 768
debian:/etc/domainkeys/mydomain.com# openssl rsa -in
rsa.private_default \
-out rsa.public_default -pubout -outform PEM
debian:/etc/domainkeys/mydomain.com# ln -sf
/etc/domainkeys/soccerfame.com/rsa.private_default default
debian:/etc/domainkeys/mydomain.com# touch selector
debian:/etc/domainkeys/mydomain.com# echo 'default' >>
selector
Where mydomain.com is the mail domain I need the DKIM
signatures for.
3. Set proper permissions and owner to /etc/domainkeys
directory
debian:~# chmod -R 0600 /etc/domainkeys
debian:~# chown -R qmailr:qmail /etc/domainkeys
4. Generate public domain key for DNS TXT records
debian:/etc/domainkeys/mydomain.com# grep -v ^-
rsa.public_default | perl -e 'while(<>){chop;$l.=$_;}print
"k=rsa; t=y; p=$l;\n";'
k=rsa; t=y;
p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhAMlDcYMrpWP9ouQOlFVtCHcFY+gxrSQ6SegYeP4eeG7NECT/3jBqDtxANIVhaS9ASkEO4yNisGu4yX/DRclTmnPWknoDtCDiD7IFEzT37qn1JLzcuknTncmFBFMDRUJq6wIDAQAB;
5. Create the DNS records in Name server
With BIND DNS server you need to place a records like:
_domainkey.example.com. IN TXT "k=rsa; t=y; o=-;"
default._domainkey.example.com. IN TXT k=rsa; t=y;
p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhAMlDcYMrpWP9ouQOlFVtCHcFY+gxrSQ6SegYeP4eeG7NECT/3jBqDtxANIVhaS9ASkEO4yNisGu4yX/DRclTmnPWknoDtCDiD7IFEzT37qn1JLzcuknTncmFBFMDRUJq6wIDAQAB;
6. Download and compile & install Mail-DKIM-0.39
's perl extension
As of time of writting latest Mail-DKIM is ver. 0.39, however it's
a good idea to check and install the latest available version
available on http://www.cpan.org
a) Download Mail-DKIM
debian:~# cd /usr/local/src
debian:/usr/local/src# wget
http://pc-freak.net/files/Mail-DKIM-0.39.tar.gz
...
2011-05-25 15:09:37 (264 KB/s) - `Mail-DKIM-0.39.tar.gz' saved
[87375/87375]
...
b) Compile & Install Mail-DKIM
debian:/usr/local/src# chown -R hipo:hipo
Mail-DKIM-0.39
debian:/usr/local/src# cd Mail-DKIM-0.39
debian:/usr/local/src/Mail-DKIM-0.39# su hipo
debian:/usr/local/src/Mail-DKIM-0.39$ perl Makefile.PL
debian:/usr/local/src/Mail-DKIM-0.39$ make
...
debian:/usr/local/src/Mail-DKIM-0.39$ exit
debian:/usr/local/src/Mail-DKIM-0.39# make install
debian:/usr/local/src/Mail-DKIM-0.39# cd script
debian:/usr/local/src/Mail-DKIM-0.39/script# cp -rpf *
/usr/local/bin; cd /usr/local/src
In above command lines I use my unprivileged username hipo
to compile, here use any non-root user is appropriate.
For instance it's possible that the cpan user is used as a
compile time user, I was lazy to configure CPAN thus I choose to
use my normal unprivileged user.
7. Download and install libdomainkeys
a) Download libdomainkeys
For latest version of libdomainkeys make sure you check on
http://domainkeys.sourceforge.net/
debian:/usr/local/src# wget
http://pc-freak.net/files/libdomainkeys-0.69.tar.gz
debian:/usr/local/src# tar -zxvvf libdomainkeys-0.69.tar.gz
...
debian:/usr/local/src# chown -R hipo:hipo libdomainkeys-0.69
debian:/usr/local/src# cd libdomainkeys-0.69; su
hipo
b) Compile and install libdomainkeys binaries
debian:/usr/local/src/libdomainkeys-0.69$ make clean &
& make
debian:/usr/local/src/libdomainkeys-0.69$ exit
debian:/usr/local/src/libdomainkeys-0.69# cp -rpf dktest dknewkey
expected makeheader /usr/local/bin/
There is a note to make here, one of the programs part of
libdomainkeys called dnstest is not compiled while doing
make for unknown reasons?!
I was not able to compile manually dnstest either using gcc like
so:
debian:/usr/local/src/libdomainkeys-0.69$ gcc -o dnstest
dnstest.c dnstest.c: In function 'main':
dnstest.c:11: warning: incompatible implicit declaration of
built-in function 'strle'
/tmp/ccH78KZ1.o: In function 'main':
dnstest.c:(.text+0x2b): undefined reference to 'dns_text'
collect2: ld returned 1 exit status
I have absolutely no clue why it fails o_O, but it doesn't matter
since I figured out that domainkeys header signature is properly
set even without dnstest.
8. Install libdkim (source of the libdkimtest binary later used
by qmail-remote wrapper script)
debian:/usr/local/src# su hipo
debian:/usr/local/src$ wget
http://pc-freak.net/files/qmail/libdkim-1.0.19.zip
debian:/usr/local/src$ wget
http://pc-freak.net/files/qmail/libdkim-1.0.19-linux.patch
debian:/usr/local/src$ wget
http://pc-freak.net/files/qmail/libdkim-1.0.19-extra-options.patch
debian:/usr/local/src$ unzip libdkim-1.0.19.zip
debian:/usr/local/src$ cd libdkim/src
debian:/usr/local/src/libdkim/src$ patch -p2 <
../../libdkim-1.0.19-linux.patch
debian:/usr/local/src/libdkim/src$ patch -p2 <
../../libdkim-1.0.19-extra-options.patch
debian:/usr/local/src/libdkim/src$ make && exit
debian:/usr/local/src/libdkim/src# make install
The above install will install libdkimtest binary, used by
the wrapper script to do the actual DKIM-Signature, the binary gets
installed in /usr/local/bin/libdkimtest.
9. Download qmail-remote.sh (qmail-remote wrapper shell script)
and set it to wrap qmail-remote
a) Copy original qmail-remote to qmail-remote.orig
debian:~# cd /var/qmail/bin
debian:/var/qmail/bin# cp -rpf qmail-remote
qmail-remote.orig
b) Download qmail-remote.wrapper script
Here is the qmail-remote.sh
wrapper script that worked for me
Originally the wrapper script is taken from
http://www.memoryhole.net/qmail/, big thanks to Russ
Nelson for writting the awesome wrapper script.
debian:~# cd /var/qmail/bin/
debian:/var/qmail/bin# wget
http://pc-freak.net/files/qmail-remote.wrapper
Saving to: `qmail-remote.wrapper'
100%[============================>] 1,164 --.-K/s in 0s
2011-05-25 15:46:54 (142 MB/s) - `qmail-remote.wrapper' saved
[1164/1164]
c) Set proper permissions to the qmail-remote.wrapper script
The permissions of qmail-remote should look like so:
-rwxr-xr-x 1 root qmail 1164 2011-05-25 11:05
/var/qmail/bin/qmail-remote*
To set this permissions I used:
debian:/var/qqmail/bin# chmod 755
qmail-remote.wrapper
d) Create /var/domainkeys directory (necessery for proper qmail
remote wrapper script operations)
debian:~# mkdir /var/domainkeys
debian:~# chown -R qmailr:qmail
debian:~# chmod 700 -R /var/domainkeys
f) Substitute original qmail-remote binary with the wrapper
script:
debian:~# qmailctl stop
Stopping qmail...
qmail-send
qmail-smtpd
debian:/var/qmail/bin# cp -rpf qmail-remote.wrapper
qmail-remote
debian:/var/qmail/bin# qmailctl start
Starting qmail
10. Send test email to @gmail.com or @yahoo.com to test if
DKIM-Signature is included in the mail header
I used my installed webmail interface squirrelmail and send
a test email to my home mail server and as well as to
yahoo.com
The headers of the email looked fine, here is how my DKIM signed
mail headers looked like:
From - Wed May 25 13:13:32 2011
X-Account-Key: account11
X-UIDL: 1306318471.48009.pcfreak,S=1958
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
X-Mozilla-Keys:
Return-Path: <hipo@mydomain.com>
Delivered-To: hipo@pc-freak.net
Received: (qmail 48006 invoked by uid 1048); 25 May 2011 10:14:30
-0000
Received: from mail.mydomain.com (83.170.105.141)
by mail.pc-freak.net with SMTP; 25 May 2011 10:14:30 -0000
DKIM-Signature: a=rsa-sha1; c=relaxed; d=mydomain.com;
s=default; t=1306318395; x=1307182395; h=Received:From;
b=k/hvkL
zPXS4xwYaptsg9M8r3esJzQz71q7lK4uYV29VE35qghbmlXD2ShvwwwmElGK2mLR
sFt/0b38dxjNZeu++R0UJ7jK3BJLqhbb/H3BeqdYgjnVloF693fxrwQOFxhSXk06
KTuTrFwF+sVmFvdYIRDDLcsFJo7qBVuN8LPxI=
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=mydomain.com;
s=default; t=1306318395; x=1307182395; h=Received:From;
bh=uoq1o
CgLlTqpdDX/iUbLy7J1Wic=;
b=VLw/fJAMQzI2Ba9e5EEsGcjmsDxzhmvYWuAGM
SgKmwpdfG1DXknYWs1aX1ia25dHINhPlCixhoGWBiQTHSL7hHXNaOHsFNp5wUifu
0piuBkMvsOWjZt3tf3yhdBxoQEvE2tz2f7MWSkA6QOtGznBiI4A9zjyq8/Q3FcZR
hYKSp0=
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=mydomain.com;
s=default; t=1306318395; x=1307182395; h=Received:From;
bh=frcCV
1k9oG9oKj3dpUqdJg1PxRT2RSN/XKdLCPjaYaY=;
b=Cozq+28r4hnpZ+9IfM6pt
l7vJSvRE5jsRfwMr/PyE3ubaII+LPDzcvBp4Do8UPvzQln31DM2Hkdu9uvxvh2po
Qgi+eHWN6kW2bcH2HuqnIeFdURdJMVGA946I/eFKH5AB/1bcGXEumeKC0n84H+a7
1596ArTCsGX3jRznvg/t6k=
Received: (qmail 32713 invoked by uid 89); 25 May 2011 10:13:15
-0000
Received: from unknown (HELO webmail.mydomain.com)
(127.0.0.1)
by 0 with SMTP; 25 May 2011 10:13:15 -0000
Received: from 83.228.93.76
(SquirrelMail authenticated user hipo@mydomain.com)
by webmail.mydomain.com with HTTP;
Wed, 25 May 2011 11:13:15 +0100 (BST)
Message-ID:
<59494.83.228.93.76.1306318395.squirrel@webmail.mydomain.com>
Date: Wed, 25 May 2011 11:13:15 +0100 (BST)
Subject: baklava
From: hipo@mydomain.com
To: hipo@pc-freak.net
User-Agent: SquirrelMail/1.4.9a
MIME-Version: 1.0
Content-Type: text/plain;charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Priority: 3 (Normal)
Importance: Normal
Notice the three DKIM-Signature sections in the header, this
obviously means the DKIM-Signature of my outgoing mails is
fine.
What is weird is that the email gets a DKIM-Signature 3
times?
I'm still investigating why is that asap as I have found why it's
like that I'll explain it here.
The idea for writting this small guide on configuring Domainkeys
with Qmail and Linux is seriously inspired by
Mariuz's Blog post dkim wrapper that works using dk Hope this
is helpful to somebody, it took me quite a while until I come up
with the exact steps of a workable install of Domain Keys, there
are so many tutorials and ways to implement this that at a certain
point it's a hell.
Like always with Qmail, even simple things are so complex, the only
good thing about qmail is once you make it work well it works
forever, until the next time you will have to spend few days trying
to figure it out.