Wednesday, April 1, 2009

How to set DKIM signature in IndiMail

What is DKIM
DomainKeys Identified Mail (DKIM) lets an organization take responsibility for a message while it is in transit. DKIM has been approved as a Proposed Standard by IETF and published it as RFC 4871. There are number of vendors/software available which provide DKIM signing. IndiMail is one of them. You can see the full list here.
DKIM uses public-key cryptography to allow the sender to electronically sign legitimate emails in a way that can be verified by recipients. Prominent email service providers implementing DKIM (or its slightly different predecessor, DomainKeys) include Yahoo and Gmail. Any mail from these domains should carry a DKIM signature, and if the recipient knows this, they can discard mail that hasn't been signed, or has an invalid signature.

IndiMail from version 1.5 onwards, comes with a drop-in replacement for qmail-queue for DKIM signature signing and verification (see qmail-dkim(8) for more details). You need the following steps to enable DKIM. IndiMail from version 1.5.1 onwards comes with a filter dk-filter, which can be enabled before mail is handed over to qmail-local or qmail-remote (see spawn-filter(8) for more details).
You may want to look at an excellent setup instructions by Roberto Puzzanghera for configuring dkim for qmail at

Create your DKIM signature
% mkdir -p /etcindimail/control/domainkeys
% cd /etc/indimail/control/domainkeys
# openssl genrsa -out rsa.private 1024
# openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM
# mv rsa.private default
# chown indimail:qmail default (name of our selector)
# chmod 440 default
Create your DNS records
$ grep -v ^- rsa.public | perl -e 'while(<>){chop;$l.=$_;}print "t=y; p=$l;\n";'  IN TXT  "t=y; o=-;"  IN TXT  "DNS-public-key"

choose the selector (some_name) and publish this into DNS TXT record for: (e.g. selector can be named 'default')

Wait until it's on all DNS servers and that's it.

Set SMTP to sign with DKIM signatures
qmail-dkim uses openssl libraries and there is some amount of memory allocation that happens. You may want to increase your softlimit (if any) in your qmail-smtpd run script.
# cd /service/qmail-smtpd.25/variables
# echo "/usr/bin/qmail-dkim" > QMAILQUEUE
# echo "/etc/indimail/control/domainkeys/default" > DKIMSIGN
# svc -d /service/qmail-smtpd.25; svc -u /service/qmail-smtpd.25

Set SMTP to verify DKIM signatures

You can setup qmail-stmpd for verification by setting
DKIMIVERIFY environment variable instead of DKIMSIGN environment variable.

# cd /service/qmail-smtpd.25/variables
# echo "/usr/bin/qmail-dkim" > QMAILQUEUE
# echo "" > DKIMVERIFY
# svc -d /service/qmail.smtpd.25; svc -u /service/qmail-smtpd.25

DKIM Author Domain Signing Practices
IndiMail supports ADSP. A DKIM Author Signing Practice lookup is done by the verifier to determine whether it should expect email with the From: address to be signed.
The Sender Signing Practice is published with a DNS TXT record as follows: IN TXT "dkim=unknown"
The dkim tag denotes the outbound signing Practice. unknown means that the domain may sign some emails. You can have the values "discardable" or "all" as other values for dkim tag. discardable means that any unsigned email from is recommended for rejection. all means that signs all emails with dkim.
You may decide to consider ADSP as optional until the specifications are formalised. To set ADSP you need to set the environment variable SIGN_PRACTICE=adsp. i.e
# echo adsp > /service/smtpd.25/variables/SIGN_PRACTICE
You may not want to do DKIM signing/verificaton by SMTP. In that case, you have the choice of using the QMAILREMOTE, QMAILLOCAL environment variables which allows IndiMail to run any script before it gets passed to qmail-remote, qmail-local respectively.

Setting qmail-remote to sign with DKIM signatures
On your host which sends out outgoing mails,
it only make sense to do DKIM signing and not verification.

# cd /service/qmail-send.25/variables
# echo "/usr/bin/spawn-filter" > QMAILREMOTE
# echo "/usr/bin/dk-filter" > FILTERARGS
# echo "/etc/indimail/control/domainkeys/default" > DKIMSIGN
# echo "-h" > DKSIGNOPTIONS
# svc -d /service/qmail-send.25; svc -u /service/qmail-send.25

Setting qmail-local to verify DKIM signatures

On your host which serves as your incoming gateway
for your local domains, it only makes sense to do
DKIM verification with qmail-local

# cd /service/qmail-send.25/variables
# echo "/usr/bin/spawn-filter" > QMAILLOCAL
# echo "/usr/bin/dk-filter" > FILTERARGS
# echo "/etc/indimail/control/domainkeys/default" > DKIMVERIFY
# svc -d /service/qmail-send.25; svc -u /service/qmail-send.25

Testing outbound signatures
Once you have installed your private key file and added your public key to your DNS data, you should test the server and make sure that your outbound message are having the proper signatures added to them. You can test it by sending an email to sa-test (at) sendmail dot net. This reflector will reply (within seconds) to the envelope sender with a status of the DomainKeys and DKIM signatures.
If you experience problems, consult the qmail-dkim man page or post a comment below and I’ll try to help.
You can also use the following for testing.
  •, is Yahoo!'s testing server. When you send a message to this address, it will send you back a message telling you whether or not the domainkeys signature was valid.
  • is a free service from the sendmail people. It's very similar to the Yahoo! address, but it also shows you the results of an SPF check as well.
All the above was quite easy. If you don't think so, you can always use the magic options --dkverify (for verification) or --dksign --private_key=domain_key_private_key_file to svctool (svctool --help for all options) to create supervice run script for qmail-smtpd, qmail-send.

IndiMail Queue Mechanism

Indimail has the ability of configuring multiple local and remote queues. A queue is a location on your hard disk where email are deposited ...