I have just installed Domain Key Identified Mail (DKIM) [1] on my mail server. In summary the purpose is to allow public-key signing of all mail that goes out from your domain so that the recipient can verify it’s authenticity (and optionally reject forgeries). It also means that you can verify inbound mail. A weakness of DKIM is that it is based on the DNS system (which has many issues and will continue to have them until DNSSEC becomes widely adopted). But it’s better than nothing and it’s not overly difficult to install.
The first thing to do before installing DKIM is to get a Gmail account. Gmail gives free accounts and does DKIM checks. If you use Iceweasel or another well supported browser then you can click on “Show Details” from the message view which then gives fields “mailed-by” and “signed-by” which indicate the DKIM status. If you use a less supported browser such as Konqueror then you have to click on the “Show Original” link to see the headers and inspect the DKIM status there (you want to see dkim=pass in the Authentication-Results header). Also Gmail signs outbound mail so it can be used to test verification of received mail.
The next thing to do is to install the DKIM Milter. To make things exciting this is packaged for Debian under the name dkim-filter so that reasonable searches for such functionality (such as a search for milter or dkim-milter – the upstream project name) will fail.
After installing the package you must generate a key, I used the command “dkim-genkey -d coker.com.au -s 2008” to generate a key for my domain. It seems that the domain is currently only used as a comment but I prefer to use all reasonable parameters for such things. The -s option is for a selector, which is a way of specifying multiple valid signing keys. It’s apparently fairly common to use a different key every year. But other options include having multiple mail servers for a domain and giving each one a selector. The dkim-genkey command produces two files, one is named 2008.txt and can be copied into a BIND zone file. The other is named 2008.private and is used by the DKIM signing server.
Here is a sample of the most relevant parts of the config file /etc/dkim-filter.conf for signing mail for a single domain:
Domain coker.com.au
KeyFile /etc/dkim/2008.private
Selector 2008
The file /etc/default/dkim-filter needs to be modified to specify how it will listen for connections from the MTA, I uncommented the line SOCKET=”local:/var/run/dkim-filter/dkim-filter.sock”.
One issue is that the Unix domain socket file will by default not be accessible to Postfix, I devised a work-around for this and documented it in Debian bug report #499364 [2] (I’ve hacked a chgrp command into the init script, ideally the GID would be an option in a config file).
A basic configuration of dkim-milter will sign mail for one domain. If you want to sign mail for more than one domain you have to comment out the configuration for a single domain in /etc/dkim-filter.conf and instead use the option KeyList file to specify a file with a list of domains (the dkim-filter.conf(5) man page documents this). The one confusing issue is that the selector is taken to be the basename of the file which contains the secret key (they really should have added an extra field). This means that if you have an obvious naming scheme for selectors (such as the current year) then you need a different directory for each domain to contain the key.
As an example here is the line from the KeyList file for my domain:
*@coker.com.au:coker.com.au:/etc/dkim/coker.com.au/2008
Now one problem that we have is that list servers will usually append text to the body of a message and thus break the signature. The correct way of solving this is to have the list server sign the mail it sends out and have a header indicating the signature status of the original message. But there are a lot of list servers that won’t be updated for a long time.
The work-around is to put the following line in /etc/dkim-filter.conf:
BodyLengths yes
This means that the signature will cover a specified number of bytes of body data, and any extra which is appended will be ignored when it comes time to verify the message. This means of course that a hostile third party could append some bogus data without breaking the signature. In the case of plain text this isn’t so bad, but when the recipient defaults to having HTML email it could have some interesting possibilities. I wonder whether it would be prudent to configure my MUA to always send both HTML and plain-text versions of my mail so that an attacker can’t append hostile HTML.
It’s a pity that Gmail (which appears to have the most popular implementation of DKIM) doesn’t allow setting that option. So far the only message I have received that failed DKIM checks was sent from a Gmail account to a Debian mailing list.
Ideally it would be possible to have the messages sent to mailing lists not be signed or have the length field used. That would require a signing practice based on recipient which is functionality is not available in dkim-milter (but which possibly could be implemented as Postfix configuration although I don’t know how). Implementing this would not necessarily require knowing all the lists that mail might be sent to, it seems that a large portion of the world’s list traffic is sent to addresses that match the string “@lists.” which can be easily recognised. For a service such as Gmail it would be easy to recognise list traffic from the headers of received messages and then treat messages sent to those domains differently.
As the signature status is based on the sending address it would be possible for me to use different addresses for sending to mailing lists to avoid the signatures (the number of email addresses in use in my domain is small enough that having a line for each address to sign will not be a great inconvenience). Most MUAs have some sort of functionality to automatically choose a sender address that is in some way based on the recipient address. I’ll probably do this eventually, but for the moment I’ll just use the BodyLengths option, while it does reduce the security a bit it’s still a lot better than having no DKIM checks.
The .deb probably isnt the best way here. I ‘make’d my dksign from source (Jason Long’s if memory serves) and the associated perl modules.
I sign mail for four domains so you imagine the use of ports to and from postfix is quite a plumbing feat.
If you want to see a goodly number of DKIM failures, checkout Linux Kernel Mailing List… It seems like every post from gmail through that route fails both DKIM and DK :(
I’ve tried to find out why, with little success – and I see that my recent (signed) message to it also exhibits the same failures… maybe time to re-evaluate signed headers again; I think the likely ones to try are the content-*
DKIM seems to require a type of email centralisation (all mail from a domain sharing a common private key) and does nothing to reduce the amount of spam being sent. With the overhead of crypto computations, isn’t it a bigger waste of power than the spam it’s trying to stop?
DKIM is better thought of as an anti-phishing and anti-spoofing measure.
Now that PayPal signs everything, why wouldn’t you discard spam purporting to be from PayPal that isn’t signed?
s j west: What are the benefits of not using the .deb? When you use a .deb you get security updates for the life of the distribution and a better way of managing the files. Of course you can use the source to build your own .deb but you still have the issue of security updates.
Rick: You will see the same failures for any list that appends footers, doesn’t remove signatures or re-sign messages, and has users writing messages with DKIM signing services that don’t support the length field (such as gmail).
MJ Ray: Compared to the CPU overhead of running SpamAssassin and ClamAV, DKIM is lost in the noise. One of the things I’m doing is running a mail server that has CPU power equivalent to 1.5 Opteron cores used 24*7 for running SA and ClamAV, I haven’t noticed the CPU power used for DKIM signing (it’s just nothing by comparison).
Tim: Yes, discarding messages claiming to be from PayPal that fail DKIM checks (or have no DKIM signature) is the right thing to do. The problem is that the dkim-milter doesn’t support this.
I plan to get SA running after DKIM and implementing such policy.
etbe: indeed, I had hoped that my adding the length would prevent those failure on my mails… but it didn’t – there is still more afoot :(
not to mention that dk-filter doesn’t seem to support the notion of length (unlike dkim)… but dk-filter’s life will hopefully be a short one.
wrt discarding obviously bad messages – I haven’t peeked to see if PayPal has implimented a signing policy, but if they have, ASPDiscard should fit the bill nicely… Otherwise, we’re left with either quaranteen (a nightmare in many ways), or spamassassin rules – which are partway there now; just needs the logic to handle policy (if it doesn’t already)
dkim is not well supported out there, yahoo did not even bother to check it at times in there webmail (idiots) , so i consider dkim a bit of a dead end.
Anyhow it does work and we have it if anybody wishes to check for it, but its ‘complexity’ seems to mean its a not a popular thing out in the wild.
I’d rather update dkim myself being theres dns,keys,inbound and outbound plumbing issues so theres plenty of scope to ‘frack it up’.