Exim4 does not add DKIM signature

Solution 1:

Verify that that you are using the remote_smtp transport. This should be listed after T= in /var/log/exim4/mainlog on the lines containing =>. Checking DKIM on locally delivered email will not work as this transport is not used. Use a verification service to check whether your mail is signed such as http://dkimvalidator.com

If you are using the remote_smtp_smarthost transport you must modify it to include DKIM signing. On a Debian/Ubuntu machine with split config append the below to the 30_exim4-config_remote_smtp_smarthost file:

# DKIM setup copied from `30_exim4-config_remove_smtp`
# see: https://serverfault.com/a/782069/117087
.ifdef DKIM_DOMAIN
dkim_domain = DKIM_DOMAIN
.endif
.ifdef DKIM_SELECTOR
dkim_selector = DKIM_SELECTOR
.endif
.ifdef DKIM_PRIVATE_KEY
dkim_private_key = DKIM_PRIVATE_KEY
.endif
.ifdef DKIM_CANON
dkim_canon = DKIM_CANON
.endif
.ifdef DKIM_STRICT
dkim_strict = DKIM_STRICT
.endif
.ifdef DKIM_SIGN_HEADERS
dkim_sign_headers = DKIM_SIGN_HEADERS
.endif

Verify the permissions on your private key. It must be readable by the use Exim runs as which Debian-exim for Debian and Ubuntu installations. If your transport is to dkim_strict, it will requeue messages if it cannot sign the message. It will log the failure causes to the mainlog and the paniclog. It may be easier to find the message in the paniclog.

These are the setting that are required to get DKIM working. You seem to be missing some. (I sign for multiple domains with the same key. Try getting signing with a single key working before trying to get fancy and use seperate keys for different domains.) This configuration should prevent unsigned email from being sent by the remote_smtp transport.

DKIM_CANON = relaxed
DKIM_DOMAIN = ${sender_address_domain}
DKIM_PRIVATE_KEY = CONFDIR/dkim.private.20160604
DKIM_SELECTOR = ${extract{-1}{.}{DKIM_PRIVATE_KEY}}
DKIM_STRICT = true # optional - causes signing failures to defer (requeue)
#DKIM_SIGN_HEADERS = # Use default

Once you have signing with a static key working. You could try these changes

DKIM_PRIVATE_KEY = CONFDIR/${sender_address_domain}.private.201604
DKIM_SELECTOR = 20160604
DKIM_STRICT = false # optional - pass if no key available

You may want to review:

  • My notes on implementing DKIM - includes the settings for other transports
  • My notes on detecting forged servers - particularly the list of verification services
  • The Exim documentation on DKIM

Solution 2:

This works for me:

DKIM_CANON = relaxed
DKIM_SELECTOR = 20160604
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
DKIM_PRIVATE_KEY=${if exists{/etc/exim4/dkim/${dkim_domain}-private.pem} {/etc/exim4/dkim/${dkim_domain}-private.pem}}

These settings must be placed in exim4.conf.template file if you use single file Exim configuration and not in 00_local_macros or other files as said in many howtos.

Setting DKIM signatures in Exim is a problem (I spent 3 days) and Exim developers should fix it.

Solution 3:

Exim version 4.84_2 #2 built 25-Jul-2016 18:59:44

Here's what worked for me, I was in the exact situation, exim4 was not adding the dkim signature.

I edited the file /etc/exim4/update-exim4.conf.conf and I found that even when I was using the split config, the config file was wrong, so I had to change this line:

dc_use_split_config='true'

And then I edited the 10_exim4-config_transport-macros file and added the following lines at the end:

DKIM_DOMAIN = ${lc:${domain:$h_from:}}
DKIM_FILE = /etc/exim4/dkim/${lc:${domain:$h_from:}}.private.key
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
DKIM_SELECTOR = exim

The previous work was generating the private key file and adding the TXT DNS record, etc.