Exim's options for how to DKIM sign various email headers

November 5, 2023

Recently, I became aware that Exim has a relatively aggressive list of message headers to sign with DKIM, and as a result we somewhat reduced the list of headers to sign in our environment. As it happens, Exim has several options for how it signs headers, which are briefly covered in the documentation for the dkim_sign_headers setting in (DKIM) Signing outgoing messages. The effects of these options aren't really clear until we understand the various meanings of DKIM signing message headers.

When you list a header name in the dkim_sign_headers setting, you can list it just by name or with either a '+' or an '=' character in front of it. Listing a header with no prefix has the same meaning as listing that header in the 'h=' list of the DKIM-Signature header; each time you list it, it signs one instance of the header in the message. If the header isn't there (or you've listed it more times than there are copies in the message), you're oversigning, which prevents adding an extra copy. So if dkim_sign_headers includes 'from' once, you're signing the first instance of From: in the message.

A prefix character of '=' means to sign as many copies of the header as are present in the message. If you specify '=from' and the message has two From: headers, you're signing against both. I believe it also means that if a particular header isn't present, you won't include it at all in the DKIM-Signature headers, so that it can be added later by another party without breaking the DKIM signature. If you want to sign things like the List-* family or the Reset-* family of headers if they're present but allow them to be added later, '=' would be one way.

(Since dkim_sign_headers is subject to Exim string expansion, another way is to only conditionally include headers based on whether or not the message has them.)

Finally, a prefix character of '+' means to oversign the header; Exim will sign as many copies of the header as are present plus one extra, so that no new additional copies can be added later (without breaking the DKIM signature). In the common case this will generate two mentions of the header in DKIM-Signature:, because the header will only occur once in the message being signed. If you use '+' on headers that aren't present in the message, one mention of them will appear in DKIM-Signature, signing that they're not present.

Exim has no prefix character option to sign only the first instance of a header if it's present at all, although you can do that with conditional inclusion of a plain header name. In my view this wouldn't be a useful option; if multiple copies of a particular header are already present, you should either sign them all, which is covered by '=<header>', or reject the message as too suspicious (or at least not DKIM sign it, or perhaps have Exim remove the additional instances of the header).

Exim also has no prefix character option to oversign existing headers but not sign non-present headers at all (although you can do this with conditional inclusion of a '+' prefixed header name). This would let you seal List-* or Resent-* headers if they were present, but allow them to be added by someone else later if they weren't. I think this is a sensible thing to do with headers and DKIM signatures, but I could be wrong.

You can get the default value of dkim_sign_headers with 'exim4 -bP macro _DKIM_SIGN_HEADERS'; this (currently) uses the plain header name format and lists each header once, meaning that Exim by default signs the first instance of headers that are present and the absence of headers that aren't present. There's also a _DKIM_OVERSIGN_HEADERS variant that puts a '+' in front of every header name, which signs all present instances of each header name and makes it so that no new ones can be added.

As a general thing, if you're presented with a message to sign that has multiple From:, Subject:, or whatever headers, I don't know if it's better to sign all of the instances of these headers, which might look suspicious to receivers, or sign only the DKIM first instance and let receivers assume the extra instances were added later, outside of your control. Possibly the best answer is to have Exim remove the extra instances.

Written on 05 November 2023.
« The various meanings of DKIM signing message headers
What client host keys OpenSSH ssh uses for host based authentication »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Nov 5 22:29:53 2023
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.