DomainKeys is an e-mail authentication system designed to verify the DNS domain of an e-mail sender and the message integrity. The DomainKeys specification has adopted aspects of Identified Internet Mail to create an enhanced protocol called DomainKeys Identified Mail (DKIM). This merged specification became the basis for an IETF Working Group which guided the specification toward becoming an IETF standard.  This blog will guide you step by step on how to implement DomainKeys using Qmail.

1. install qmail as per our guide (skip this if you have an existing/compatible qmail installation).
any qmail install based off LWQ should be compatible – including netqmail, qmail-isp, and even qmail-aio.

2. install OpenSSL as per the INSTALL file of the latest stable tarball (skip if you already have an existing/compatible OpenSSL)

3. Set it all up

  cd /usr/local/src/
  wget http://cr.yp.to/software/qmail-1.03.tar.gz
  wget http://superb-east.dl.sourceforge.net/sourceforge/domainkeys/libdomainkeys-0.68.tar.gz
  wget http://www.qmail.org/qmail-1.03-dk-0.54.patch
  wget http://jeremy.kister.net/code/qmail-dk-0.54-auth.patch # optional, for smtp-auth
  tar -zxvf libdomainkeys-0.68.tar.gz
  cd libdomainkeys-0.68
  make
  tar -zxvf /usr/local/src/qmail-1.03.tar.gz
  echo 'gcc -O2 -include /usr/include/errno.h' > qmail-1.03/conf-cc
  patch -d qmail-1.03/ < ../qmail-1.03-dk-0.54.patch
  patch -d qmail-1.03/ < ../qmail-dk-0.54-auth.patch   # optional, for smtp-auth
  cd qmail-1.03
  make qmail-dk
  cp qmail-dk /var/qmail/bin/
  cp qmail-dk.8 /var/qmail/man/man8/
  chown qmailq /var/qmail/bin/qmail-dk
  chmod 4711 /var/qmail/bin/qmail-dk

4. Next, we set up a RSA key pair, as according to http://domainkeys.sourceforge.net/keygen.html.

  mkdir -p /etc/domainkeys/example.com/
  cd /etc/domainkeys/example.com/
  /usr/local/ssl/bin/openssl genrsa -out rsa.private 768
  /usr/local/ssl/bin/openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM
  mv rsa.private default
  chown -R qmailq /etc/domainkeys
  chmod 0600 default

5. Make your public DomainKey:

  grep -v ^- rsa.public | perl -e 'while(<>){chop;$l.=$_;}print "k=rsa; t=y; p=$l;n";'

6. Create a TXT record in your DNS as per http://domainkeys.sourceforge.net/dist.html:

For tinydns (djbdns):
'_domainkey.example.com.:k=rsa; t=y; o=-;
'default._domainkey.example.com.:DomainKey_from_step_5

or for BIND:
_domainkey.example.com. IN TXT "k=rsa; t=y; o=-;"
default._domainkey.example.com. IN TXT "DomainKey_from_step_5"

7. Next, modify your /etc/tcp.smtp:

  • If you control who relays through your machine via RELAYCLIENT:

10.0.0.2:allow,RELAYCLIENT=””,DKSIGN=”/etc/domainkeys/example.com/default“,QMAILQUEUE=”bin/qmail-dk”
:allow,DKVERIFY=”DEGIJKfh”,QMAILQUEUE=”bin/qmail-dk”

  • Or, if you use SMTP AUTH to control who relays through your machine,
    and you’ve patched with the above qmail-0.54-dk-auth.patch,
    you don’t have to worry about setting DKSIGN:

:allow,DKVERIFY=”DEGIJKfh”,QMAILQUEUE=”bin/qmail-dk”

8. Rebuild your cdb file:

  qmailctl cdb

9. Be sure to watch your /var/log/qmail/smtpd/current for problems involving
not having enough memory. You may need to increase the softlimit memory
size in /service/qmail-smtpd/run.

10. If you want qmail-dk to sign messages that you send from the command line,
you have to set up some environment variables.

You can choose to modify your .profile:
QMAILQUEUE=/var/qmail/bin/qmail-dk
DKSIGN=/etc/domainkeys/example.com/default
export QMAILQUEUE DKSIGN

Or, as Kyle Wheeler suggested, you can put a wrapper around sendmail:
#!/bin/sh
export QMAILQUEUE=/var/qmail/bin/qmail-dk
export DKSIGN=/etc/domainkeys/example.com/default
exec /var/qmail/bin/sendmail “$@”

11. And finally, test your installation:
send mail to dktest@temporary.com. You should get a reply within a few minutes.

When you’re satisfied with your installation:
change the “t=y” in your DNS TXT RRs to “t=n”: this takes your DomainKey out of “test mode”.
To be a bit more aggressive, add a “B” to your DKVERIFY string. man qmail-dk for more info.