DKIM and Request-Tracker Headers

dkimeximrequest-tracker

I have a domain that sends two different types of emails: ones that are created via automated processes like notifications that go out to users, and ones that are generated from Request Tracker (the ticket system).

We set up DKIM awhile back and I made the mistake of never verifying that both types of emails were working, so I never checked the RT emails. More recently we realized that occasionally RT-generated messages are hitting spam filters, and it feels like failed DKIM checks may have a hand in it.

RT adds some headers to each message, for example:

X-RT-Loop-Prevention: Support
RT-Ticket: Support #3165
Managed-by: RT 3.8.2 (http://www.bestpractical.com/rt/)
RT-Originator: xxx@xxx.com
X-RT-Original-Encoding: utf-8 

However, those headers do not appear in the DKIM signature. For example, here is a hardfail string from Gmail this morning:

Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of www-data@mx1.xxx.com designates xxx.xxx.xxx.xxx as permitted sender) smtp.mail=www-data@mx1.xxx.com; dkim=hardfail header.i=@xxx.com
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xxx.com; s=mta;
    h=Date:Content-Type:Content-Transfer-Encoding:MIME-Version:To:Message-ID:References:In-Reply-To:Reply-To:From:Subject; bh=GDIpYEyFTXB3RPUtFDKxW+iBpkOYngdUELnMw316Ohk=;
    b=A6iZYrFUZ68gszu/KeTyMoUUE0jbGlZ+yxcz72gq7Bdxe+jAkcgFoExN+duxLPIZqJm87Gz+XCB9IwnQbKC5lsVKK8cwUzQTHZx6E8ZPyynkv0NvC8MStDgOswFnjdcy;

As you can see, the RT headers are not included in the DKIM signature. When a mail is sent from the site outside of RT, Gmail validates the signature properly.

My understanding was that "custom" headers (X-xxxxxxxx) are ignored by DKIM but others are not, for example the RT-Ticket, Managed-by, and RT-Originator above.

Does anybody have any detailed experience with this or know where I might look to get DKIM to include those headers in the signature? I have searched through the RT support a bit and cannot find much. I am using exim as the MTA, and the system is Debian Lenny.

edit: I may be barking up the wrong tree here with the header fields, I am not sure. I modified the exim configuration to explicitly tell it which headers to look at, by taking the list of headers from RFC4871 (https://www.rfc-editor.org/rfc/rfc4871) and adding the extra headers that RT is adding, like so:

  dkim_sign_headers = From:Sender:Reply-To:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:Precedence:X-RT-Loop-Prevention:RT-Ticket:Managed-by:RT-Originator:X-RT-Original-Encoding

That resulted in all of the RT headers being properly added to the signature, however, Gmail still reported a hardfail on the signature when it came via RT. As far as I can tell RT is using exim in the same way as any other external program, so I am at a loss to explain why those messages are failing.

Best Answer

Going to post a semi-answer here in case anybody ever runs into a similar issue and finds this via search.

I was not able to solve this problem while using the relaxed header canonicalization for DKIM signing within exim. I took example messages that were being generated by my RT and whose signatures were failing at both Gmail and Yahoo mail, and then tested them like this:

  1. I used PHP to implement the DKIM signing algorithm as specified in the docs (http://www.dkim.org/specs/rfc4871-dkimbase.html). When I ran my message through it with relaxed/relaxed I produced the same body hash but a different message signature than my exim was producing.

  2. I used PHP to implement the DKIM verification algorithm, then took the source of the messages as received by Gmail and Yahoo Mail and ran it through, producing identical results. I also ran messages through that had not been generated by my Request Tracker but had gone through my exim, and they were correctly passed in my verify test, just as they had on Gmail and Yahoo Mail (the purpose of this was to prove that my keys and other configuration were working properly outside of the context of RT, which they seem to be).

  3. At this point I figured that there is either a bug or misconfiguration in the way my exim is handling DKIM signing in relaxed/relaxed. I downloaded the source for the PDKIM library that exim uses ([https://github.com/duncanthrax/pdkim]), compiled it, and then modified the testing examples to match my keys, settings, and test messages. After running the tests, I produced the same results as my PHP implementation: same hashes, same signatures.

That left me with one last option, which was to mess with the source of exim to try to determine what specific scenario was causing the message signature to change. However, I'd kind of hit my limit on how much time I wanted to spend on this.

The simple solution was to change my exim config back to simple canonicalization, which resulted in both Gmail and Yahoo Mail passing the dkim verify for messages generated by my Request Tracker. Not what I wanted, but good enough for now.