#pragma page-filename DEV/versions/826
= DomainKey Identified Mail (DKIM) =
[[http://www.dkim.org|DKIM]] is a specification (
[[http://www.ietf.org/rfc/rfc6376.txt?number=6376|RFC 6376]])for cryptographically signing certain parts of an email message. Signing using DKIM allows for domain name holders to vouch for the integrity of headers and/or body text. The public keys for the signatures are available through DNS so only the DNS administrators corresponding to claimed domains in the signed components will be able to produce valid signatures.
DKIM affects Mailman in several ways. Most importantly, the transformations that Mailman can inflict on original postings can break DKIM signatures. Mailman can remove headers, add headers, concatenate header or footer text, add or remove MIME parts, completely reorganize the MIME structure of a message, perform character set transformations, and more. Any one of these things can break a DKIM signature.
Other ways in which Mailman and DKIM interact include whether Mailman should validate DKIM signatures on incoming messages and whether Mailman should sign outgoing list copies with its DKIM signature. (Note that when I say ''Mailman'' above, I really mean Mailman proper or any assistive mail component Mailman relies upon, such as the incoming or outgoing MTA.)
It is important to note, as per the IETF charter, that DKIM is an '''anti-spoofing''' mechanism, '''not an anti-spam''' mechanism.
== Signature breakage ==
Mailman's transformations can break DKIM signatures. The official DKIM specifications about best common practices in the face of message transforming mailing list remailers are still in [[http://www.dkim.org/specs/draft-ietf-dkim-deployment-12.html|draft form - dkim deployment RFC]] (link is not resolving). Of larger importance than DKIM signatures is the effect of [[http://tools.ietf.org/html/rfc5617|RFC5617 Author Domain Signing Practices]]which defines which domains are DKIM signing all email. [[http://www.faqs.org/rfcs/rfc6377.html|RFC 6377]] directly addresses issues involving DKIM and MLMs.
The question then is, are these best common practices for mailing lists generally acceptable to the administrators that run them? Make no mistake, though, DKIM cannot be ignored; the big players such as Y! and G, Cisco, government departments, banks etc. are already signing messages, and sites are already using DKIM signature validity as part of their mail filtering processes.
Once upon a time this topic was briefly [[http://mail.python.org/pipermail/mailman-developers/2007-February/thread.html|being hotly debated]] on the mailman-developers mailing list. In September 2009 Daniel Black asked for solutions from the [[http://mipassoc.org/pipermail/dkim-dev/2009-September/000202.html|DKIM developers email list]]. Several opinions were mentioned though without concensus.
There are several options for dealing with DKIM signature breakage. They are not necessarily mutually exclusive.
{{{#!table
'''Option'''
|| '''Pros'''
|| '''Cons'''
==
Ignore the problem
|| This is the simplest solution because it means we don't have to change Mailman at all. If the original message has
`DKIM-Signature`headers, we just leave them in there even if Mailman's transformations break the signature. We do no parsing or verification of the signature, nor do we limit any Mailman transformations we would otherwise apply to the message because of the signature.
|| The effects of this are that recipients of list copies of the message may fail to verify the signature, potentially treating the message as spammy. <
> Ignoring the problem limits the ability of recipients to filter based on DKIM signatures (not just for email lists)
==
Parse the `DKIM-Signature` header in order to adjust the effects of Mailman transformations on it.
|| Allows recipients to validate and filter based on DKIM
|| will end up lots of exception handling code and inconstant emails to the subscriber that may not meet the list owner's policy
==
Remove all original `DKIM-Signature` headers if after parsing the `DKIM-Signature` header we've broken the signature.
|| Simple. Solves DKIM validation.
|| ADSP tells the recipient that a signature should exist where a From address contains the author's domain. Removing DKIM-Signatures is just as bad as invalidating them in the and will result in ADSP rejections.
==
sign list-ID headers and ask verifiers to check for list-id tags in a spamminess way
|| simple
|| complicates verification provides spoofing loophole as DKIM is antispoofing more that antispam
==
remove DKIM-Signature always
|| as per other similar option (up 2)
|| as per other similar option (up 2). This solution seems to be strongly disfavored by DKIM proponents.
==
rewrite From: email header field to contain the list domain in the From header field. e.g. mailman-users-relay+daniel=cacert.org@python.org
|| simple - few code changes required
<
> <
> Although all modifications of DKIM email signature still occur, it is not as critical as the email is no longer the author domain (based on the from address). <
> As the From: address is now belonging to the list operator, DKIM signing by mailman will be able to be cleanly validated by recipients without having to manage as many whitelists of DKIM-signature invalidating intermediaries. <
> Doing this by default will enable DKIM validation to occur easier. <
> <
>
|| Fiddling with From: email header could bring up unknown behaviors.<
> <
> If a reply-to address doesn't exist in the email headers add the from address here to preserve MUA behavior. <
> <
> Desirable is a remap from the From address back to the user validated in a way that it cannot be used as an arbitrary spam address. e.g. validating against the list subscribers.
}}}
== Mailman verifying headers ==
As a remailer, the mailman is in a unique position where there are unlikely to be email lists chained together. The upshot of this is that there is unlikely to be email invalidated before reaching mailman's input. Applying a strong filtering policy on mailman's input is easy - invalid signatures, drop/reject, ADSP failures (dkim=all and dkim=discard) - drop/reject.
As mentioned on the dkim-dev email list dropping emails from subscribers with a ADSP policy of dkim=discardable is recommended on lists that will break DKIM signatures. DKIM discardable ADSP policies are inherently incompatible with current lists.
== Mailman signing headers ==
Signing headers and content provides a mechanism for the recipient to determine if any modification occurred after the mailing list server processed the message. There is no explicit or implicit meaning beyond this. List operators are free to place more assertion here at their peril.
A misconception is that when Mailman (or its downstream components) signs list copies, it means that the list server system is vouching for the validity of the message. Answer no - the RFCs talk in terms of email integrity and not validity - this is mentioned explicitly in [[http://tools.ietf.org/html/draft-ietf-dkim-deployment-08#section-2.4|draft-ietf-dkim-deployment rfc]]
Because Mailman is a remailer, such resigning could open an attack vector where spoofed email is sent through the list suddenly gets relayed without verification. This could potentially legitimatize otherwise illegitimate messages. Thus, if Mailman were to add its own DKIM signatures, you'd want to make sure Mailman were also checking the DKIM signatures of messages it receives, and potentially putting a hold (or rejecting or dropping) on messages that had a broken or non-existent signature. You probably also want to do more aggressive spam filtering on the message before it even hits Mailman (disputed - recipients shouldn't be using DKIM as a spam bias score - doing so will just ensure spammers DKIM sign emails. Aggressive spam filtering before mailman will not gain anything DKIM wise).
Spam directly mailed to the list isn't the only problem, though; a much more likely scenario for some lists are that messages gated from Usenet come from a totally unverifiable source. Of course, Usenet gating is a pretty rare use case these days, but still, we shouldn't ignore it. Already `python.org` occasionally gets labeled as a spam source because of its gating of spam messages from `comp.lang.python`. It probably makes the most sense to simply not sign gated messages.
== Proposal ==
Because we're in feature freeze for Mailman 2.1, we can't add any new functionality. However, in Mailman 2.1.9, we explicitly began stripping `DKIM-Signature` headers from incoming messages. This is what sparked the above-mentioned developers thread. The original impetus for this change was a broken DKIM [[http://www.sendmail.org/doc/sendmail-current/libmilter/docs/|Sendmail milter]] which refused to sign outgoing messages that already contained a signature.
The proposal for Mailman 2.1.10 then is to add a variable to `Defaults.py.in` (configurable via `mm_cfg.py`) that controls whether `DKIM-Signature` headers are removed or not in outgoing list copies, e.g.:
{{{
# Controls whether all existing DKIM-Signature headers in posted messages
# get stripped in the outgoing list copies. In general, you should leave
# this disabled so that original DKIM signatures will be retained for
# forensic purposes, even if broken. Enable this feature only if your site
# has specific problems with outgoing pre-signed (broken or unbroken) messages.
STRIP_DKIM_SIGNATURE = No
}}}
The default is `No` in order to restore the behavior that came to be expected before the 2.1.9 release.
For Mailman 2.2/3.0 then, we should explore adding DKIM signing code as a handler module, such that definitely `List-ID`, possibly `Sender` and potentially other Mailman added headers get valid signatures. However, if we do this, we'll need to have a way to tell the outgoing MTA not to sign certain messages (e.g. Usenet posts). That might require an MTA-specific solution.
We should also encourage the site's incoming MTA to check the validity of any `DKIM-Signature` header on posted messages. We'd like to see something like a [[http://tools.ietf.org/html/draft-kucherawy-sender-auth-header-14|''DKIM'']]''[[http://tools.ietf.org/html/rfc5451|DKIM validity status header (RFC5451)]]'' ''validity status'' header added to the message Mailman sees. Then Mailman can put a hold on messages that its upstream MTA tells it has a bad DKIM signature.
We should enable our user's to configure their Mailman system to not break any `DKIM-Signature`. Perhaps by offering a dkimfriendly=true global option.
Finally, we should encourage the DKIM working group to include language in the spec specifically relating to mailing list interoperability. We cannot ask verifiers to just favorably upon, a valid signed `List-ID` header as this will just ensure spammers and phishers add List-ID headers to spam.
To develop standards to assist with email lists as an alternative to the last option above that provides a neat solution, there could be a third-party domain signing policies. Some standard that allows senders to define which third party signatures recipients should receive, even if the author domain signature is broken. An example could be DNS records like list_python_org._3p._domainkey.example.com to indicate that recipients should accept a list.python.org third party DKIM signature. The same validation hierarchy could also be used by verifiers of arbitrary domains to see which domains really operate email lists.
== References: ==
A paper Daniel Black wrote on DKIM and email lists - [[https://community.cacert.org/dkim|https://community.cacert.org/dkim]]. Feedback/discussions welcome on dkim-ops list, personally or on dkim-user/dev lists.
----
<>