DMARC Mitigations¶
In order to mitigate the effects of DMARC on mailing list traffic, list administrators have the ability to apply transformations to messages delivered to list members. These transformations are applied only to individual messages sent to list members and not to messages in digests, archives, or gated via NNTP.
The messages can be transformed by either munging the From:
header and
putting original From:
in Cc:
or Reply-To:
, or by wrapping the
original message in an outer message From:
the list.
Exactly which transformations are applied depends on a number of list settings.
The settings and their effects are:
anonymous_list
If True, no mitigations are ever applied because the message is already
From:
the list.dmarc_mitigate_action
The action to apply to messages
From:
a domain publishing a DMARC policy of reject or quarantine, or to all messages depending on the setting ofdmarc_mitigate_unconditionally
.dmarc_mitigate_unconditionally
If True, apply
dmarc_mitigate_action
to all messages, but only ifdmarc_mitigate_action
is neitherreject
ordiscard
.dmarc_moderation_notice
Text to include in any rejection notice to be sent when
dmarc_policy_mitigation
ofreject
applies. This overrides the built-in default text.dmarc_wrapped_message_text
Text to be added as a separate
text/plain
MIME part preceding the original message part in the wrapped message when awrap_message
mitigation applies. If this is not provided the separatetext/plain
MIME part is not added.reply_goes_to_list
If this is set to other than no-munging of
Reply-To:
, the originalFrom:
goes inCc:
rather thanReply-To:
. This is intended to make MUA functions of reply and reply-all have the same effect with messages to which mitigations have been applied as they do with other messages.
The possible actions for dmarc_mitigate_action
are:
no_mitigation
Make no transformation to the message.
munge_from
Change the
From:
header and put the originalFrom:
inReply-To:
or in some casesCc:
.wrap_message
Wrap the message in an outer message with headers from the original message as in
munge_from
.reject
Bounce the message back to the sender with a default reason or one supplied in
dmarc_moderation_notice
.discard
Silently discard the message.
Here’s what happens when we munge the From:
.
>>> from mailman.interfaces.mailinglist import (
... DMARCMitigateAction, ReplyToMunging)
>>> from mailman.app.lifecycle import create_list
>>> mlist = create_list('ant@example.com')
>>> mlist.dmarc_mitigate_action = DMARCMitigateAction.munge_from
>>> mlist.reply_goes_to_list = ReplyToMunging.no_munging
>>> from mailman.testing.helpers import (specialized_message_from_string
... as message_from_string)
>>> msg = message_from_string("""\
... From: Anne Person <aperson@example.com>
... To: ant@example.com
...
... A message of great import.
... """)
>>> msgdata = dict(dmarc=True, original_sender='aperson@example.com')
>>> from mailman.handlers.dmarc import process
>>> process(mlist, msg, msgdata)
>>> print(msg.as_string())
To: ant@example.com
From: Anne Person via Ant <ant@example.com>
Reply-To: Anne Person <aperson@example.com>
A message of great import.
Here we wrap the message without adding a text part.
>>> mlist.dmarc_mitigate_action = DMARCMitigateAction.wrap_message
>>> mlist.dmarc_wrapped_message_text = ''
>>> msg = message_from_string("""\
... From: Anne Person <aperson@example.com>
... To: ant@example.com
...
... A message of great import.
... """)
>>> msgdata = dict(dmarc=True, original_sender='aperson@example.com')
>>> process(mlist, msg, msgdata)
>>> print(msg.as_string())
To: ant@example.com
MIME-Version: 1.0
Message-ID: <...>
From: Anne Person via Ant <ant@example.com>
Reply-To: Anne Person <aperson@example.com>
Content-Type: message/rfc822
Content-Disposition: inline
From: Anne Person <aperson@example.com>
To: ant@example.com
A message of great import.
And here’s a wrapped message with an added text part.
>>> mlist.dmarc_wrapped_message_text = 'The original message is attached.'
>>> msg = message_from_string("""\
... From: Anne Person <aperson@example.com>
... To: ant@example.com
...
... A message of great import.
... """)
>>> msgdata = dict(dmarc=True, original_sender='aperson@example.com')
>>> process(mlist, msg, msgdata)
>>> print(msg.as_string())
To: ant@example.com
MIME-Version: 1.0
Message-ID: <...>
From: Anne Person via Ant <ant@example.com>
Reply-To: Anne Person <aperson@example.com>
Content-Type: multipart/mixed; boundary="..."
--...
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
The original message is attached.
--...
Content-Type: message/rfc822
MIME-Version: 1.0
Content-Disposition: inline
From: Anne Person <aperson@example.com>
To: ant@example.com
A message of great import.
--...--