Setting up multi-domain DKIM with exim + Debian

After spending a day wrestling with exim trying to set up DKIM and tearing my hair out working out why it wasn’t working, I thought I’d document my difficulties for future reference and maybe to help other people with the same problems. (And see the end for a shell script that automates creating future DKIM key pairs.)

Note that this is partially specific to Debian/Ubuntu, because it sets up exim 4 with configuration split between multiple files instead of all in one, and then also it’s specific to multi-domain virtual host installs.

Macro expansion woes

I started with the most straightforward result Google gave me and I recommend going to read it first before continuing reading this. It talks about how to set up exim using multiple hosts on the same mailserver. However, I had a problem where exim gave the error:

failed to expand dkim_private_key: missing or misplaced { or }

The problem was apparently between the two lines specifying DKIM_DOMAIN and DKIM_FILE:

DKIM_DOMAIN = ${sg{${lc:${domain:$h_from:}}}{^www\.}{}}
DKIM_FILE = /etc/exim4/dkim/{DKIM_DOMAIN}.pem

exim was choking on the {DKIM_DOMAIN} reference within DKIM_FILE. I tried various different things to get a working result, but the best I could manage was duplicating the value of DKIM_DOMAIN without the expansion, like so:

DKIM_FILE = /etc/exim4/dkim/${sg{${lc:${domain:$h_from:}}}{^www\.}{}}.pem

Removing the ‘www’ from the ‘From’ header is overkill most of the time, so simply lowercasing the From header’s host will do:

DKIM_DOMAIN = ${lc:${domain:$h_from:}}
DKIM_FILE = /etc/exim4/dkim/${lc:${domain:$h_from:}}-private.pem

Also, you don’t need to set DKIM_CANON to ‘relaxed’; this is its default value.

Permissions

Make sure that your permissions are correct. The keys inside the dkim/ directory should be chmod 640 (user read+write and group read), and owned by Debian-exim. The directory itself (/etc/exim4/dkim), however, shoud be 750, as this sets the execute, which is required to access the directory and the files in it.

If you get this wrong and you’re using the article linked to above’s DKIM_PRIVATE_KEY setting:

DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}

Then it will silently fail to load keys and you’ll spend ages trying to work out why.

Automate setting up new DKIM key pairs

This shell script quickly creates a new DKIM key pair and tells you what to put in your DNS record. It also fixes up permissions as noted above. You will have to run it using sudo as it modifies files in the /etc/exim4 directory.

Home

blog built using the cayman-theme by Jason Long. LICENSE