DKIM is a standard for digitally signing mail to prove it’s authenticity and prove that it was not modified. In an ideal situation it can be used to reject corrupted or forged messages.
DMARC and ADSP are standards for indicating that mail from a domain should be signed. This prevents hostile parties from removing the DKIM signature and modifying the message. DKIM is only half as useful without them (it can still prove authenticity but it can’t prove that mail was forged and allow rejecting forged mail).
A mailing list is a software system that receives a message from one person and then generates messages to many people with the same content. A common setting of a mailing list is to insert “[listname]” at the start of the subject line of each message that goes through, this breaks the DKIM signature. Another common setting is to append a footer to the message giving information about the list, this breaks the DKIM signature unless the signature uses the “l=” flag (which Gmail doesn’t). When the “l=” flag is used a hostile party can append text to a message without the signature breaking which is often undesired. Mailman (one of the most common mailing list systems) parses and regenerates headers, so it can break DKIM signatures on messages with unexpected header formatting. Mailman also in some situations uses a different MIME encoding for the body which breaks DKIM signatures.
It seems almost impossible to reliably get all mail to go through a Mailman list without something happening to it that breaks DKIM signatures. The problem is that Mailman doesn’t just send the message through, it creates new messages with new headers (created from a parsed copy of the original headers not copying the original headers), and it sometimes parses and re-encodes the body. Even if you don’t choose to use the features for appending a message footer or changing the subject DKIM signatures will often be broken.
Stripping the Signatures
As there is no way to reliably (IE for every message from every sending domain that uses DKIM) pass through messages with DKIM signatures intact the only option is to strip them. To do that with Mailman edit /etc/mailman/mm_cfg.py, add the directive “REMOVE_DKIM_HEADERS = Yes“, and then restart Mailman. If none of the people who send to your list used DMARC or ADSP then that solves your problem.
However if there are senders who use DMARC or ADSP and recipients who check those features then mail will still be rejected and users will get unsubscribed. When DMARC or ADSP are in use the mailing list can’t send out list mail purporting to be from a list member, it must send out mail from it’s own domain.
A Legitimate From Field
In the web based configuration for Mailman there is a dmarc_moderation_action setting that can munge the From field on messages with a DMARC policy. One thing to note is that when one list uses the dmarc_moderation_action setting it causes DKIM users to configure DMARC which then makes more problems for the people who run lists with no settings for DKIM. Also that doesn’t solve things for ADSP messages or messages that don’t use either DMARC or ADSP. It’s not uncommon for people to have special configuration to prevent forged mail from their own domain, requiring a valid DKIM signature is one way of doing this. Finally many users of DKIM enabled mail servers don’t have the option of enabling DMARC.
If you use the from_is_list setting in the web based configuration for Mailman then all mail will have a From field which shows who the message is from as well as the fact that it came From a list server. This combined with REMOVE_DKIM_HEADERS will allow DKIM signed mail sent to the list to go through correctly in all cases.
If you run many lists then changing them all through the web interface can be tedious. Below is a sample of shell code that will use the Mailman config_list program to change the settings to use from_is_list. NB I haven’t actually run this on a Mailman server with lots of lists so check it before you use it, consider it pseudo-code.
for n in lista listb listc ; do
config_list -o /tmp/$n $n
sed -i -e "s/from_is_list = 0/from_is_list = 1/" /tmp/$n
config_list -i /tmp/$n $n
The from_is_list setting makes a change like the following:
-From: Russell Coker <russell at coker.com.au>
+From: Russell Coker via linux-aus <linux-aus at lists.linux.org.au>
There are similar problems with SPF and other anti-forgery methods. The use of from_is_list solves them too.
Signing List Mail
An ideal list configuration has the list server checking DKIM signatures and DMARC settings before receiving mail. There is normally no reason for a mailing list to send mail to another mailing list so mail that the list server receives should pass all DKIM, DMARC, and ADSP checks. Then the list server should send mail out with it’s own DKIM signature.
When a user receives mail from the list they can verify that the DKIM signature is valid. Then if they know that the sender used DKIM (EG the mail originated from gmail.com or another domain that’s well known to use DKIM) then they know that it was verified at the list server and therefore as long as the list server was not compromised the message was not altered from what the sender wrote.
The Debian Wiki page about OpenDKIM is worth reading . OpenDKIM is generally regarded as the best free software DKIM verification and signing daemon available. The Debian Wiki only documents how to install it with Postfix but the milter interface is used by other MTAs so it shouldn’t be too hard to get it working with other MTAs. Also the Debian Wiki documents the “relaxed” setting which will in some situations solve some of the problems with Mailman munging messages, but it doesn’t guarantee that they will all be solved. Also in most cases it’s not possible to get every user of your list to change the settings of their DKIM signing to “relaxed” for the convenience of the list admin.
Here is an example of how to use SpamAssassin to score DKIM signatures and give a negative weight to mail from lists that are known to have problems . Forcing list users to do this means more work overall than just having the list master configure the list server to pass DKIM checks.