On 2019-04-28 at 16:42 +0100, Andrew C Aitchison via Exim-dev wrote:
> Do the DKIM exim experts subscribe to the mailop list ?
I do, but I just started a new job and am behind on public
mailing-lists.
> There is an ongoing discussion on the mailop@???
> about a snafu with DKIM which implicates exim and google.
It looks like an instance of this:
https://bridge.grumpy-troll.org/2014/04/dmarc-stance/
but for p=none, not p=reject. It's been five years since I wrote that.
DMARC breaks mail for domains sending non-transactional non-bulk mail,
becauase DMARC breaks mailing-lists.
The only "out" is to implement ARC and hope that the receiving domain
does too. Gmail does, but you need to send enough mail for them to
decide to trust you as an ARC sender.
For the @exim.org mail-hub, we run with
------------------------8< exim.conf snippets >8------------------------
# This file is renewed daily by cron as user _exim:
.ifdef _HAVE_DMARC
dmarc_tld_file = /var/cache/exim/opendmarc.tlds
.elifdef _HAVE_ARC
dmarc_tld_file = /var/cache/exim/opendmarc.tlds
.endif
### ACLS section
acl_check_content:
# Outbound ARC-sign is disabled by default because people can auth to us
warn set acl_m_should_arcsign = false
# Do add Message-ID: and Date: headers
warn condition = ${if !def:h_Message-ID: {1}}
message = Message-ID: <E$message_id@$primary_hostname>
warn condition = ${if !def:h_Date: {1}}
message = Date: $tod_full
# If there's an AAR (ARC-Authentication-Results) header which claims to be
# from us, but we're not receiving the mail from Mailman or other local
# system or authenticated user, then we consider it to be fraudulent or a
# mail-loop.
#
# We need to allow authenticated users for when someone is bouncing onwards
# a received message; OUTSIDE->exim.org->fred@???, reads, bounces
# onwards for processing elsewhere, but being sent from fred@??? gets
# routed back via us (for DKIM/SPF alignment), so we appear in the AAR
# headers already.
#
# Does not need to be _HAVE_ARC-guarded, this is pure Exim logic and safe
# even when we're not signing.
deny message = Mail-loop or fraudulent headers: found ourselves in ARC-Authentication-Results:
!hosts = +relay_from_hosts
!authenticated = *
condition = ${if def:h_ARC-Authentication-Results: {yes}}
condition = ${if inlist{ADMD}{<; $h_ARC-Authentication-Results: }}
warn hosts = <; ; 127.0.0.1 ; ::1
condition = ${if def:h_X-Exim-Org-Should-ARC-Sign: {yes}}
set acl_m_should_arcsign = $h_X-Exim-Org-Should-ARC-Sign:
remove_header = X-Exim-Org-Should-ARC-Sign
# Bypass the content scanning for stuff injected from mailman etc
accept hosts = <; ; 127.0.0.1 ; ::1
### THERE ARE MORE STEPS HERE IN THIS ACL (unrelated to ARC)
# list stuff & authenticated....
accept hosts = +relay_from_hosts
accept authenticated = *
# Insert DMARC headers for non-authenticated non-local senders
warn dmarc_status = accept : reject : quarantine : none : norecord : nofrom : temperror : off
log_message = DMARC DEBUG: $dmarc_status $dmarc_used_domain
warn condition = ${if !eq{$dmarc_status}{accept}}
log_message = DMARC DEBUG: not-accept '$dmarc_status' for $dmarc_used_domain
warn condition = ${if eq{$dmarc_status}{quarantine}}
set acl_m_quarantine = 1
deny condition = ${if eq{$dmarc_status}{reject}}
message = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT
.ifdef _HAVE_ARC
# and ARC chaining
warn verify = arc/pass:none:fail
logwrite = ARC: state=<$arc_state>${if def:arc_state_reason{ reason=<$arc_state_reason>}}
.endif
### TRANSPORTS SECTION
remote_smtp:
driver = smtp
rcpt_include_affixes
# hosts_try_chunking =
dnssec_request_domains = *
hosts_try_dane = *
tls_require_ciphers = TLS_OUTBOUND_DEFAULT
dane_require_tls_ciphers = TLS_OUTBOUND_HIGHSEC
dkim_domain = ${domain:$sender_address}
dkim_selector = ${lookup {$dkim_domain}lsearch{/etc/exim/dkim/domains-mapping} {$value}{SKIP}}
dkim_private_key = ${if eq{$dkim_selector}{SKIP}{false}{/etc/exim/dkim/rsa.private.$dkim_selector.$dkim_domain}}
dkim_strict = 1
.ifdef _HAVE_ARC
arc_sign = ${if bool{$acl_m_should_arcsign}{${lookup {ADMD}lsearch{/etc/exim/dkim/domains-mapping}{ADMD : $value : /etc/exim/dkim/rsa.private.$value.ADMD }fail}}fail}
.endif
.ifdef WANT_MAILMAN
mailman_transport:
envelope_to_add
driver = pipe
command = MM_WRAP \
'${if def:local_part_suffix \
{${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
{post}}' \
$local_part
headers_add = X-Exim-Org-Should-ARC-Sign: $acl_m_should_arcsign
current_directory = MM_HOME
home_directory = MM_HOME
user = MM_UID
group = MM_GID
.endif
------------------------8< exim.conf snippets >8------------------------
Our Mailman config has:
----------------------------8< mm_cfg.py >8-----------------------------
# DMARC/DKIM handling:
# This sets the minimum option allowed per-list; minimum is "Munge", not
# "Accept and destroy our reputation".
DEFAULT_DMARC_MODERATION_ACTION = 1
# and for dmarc p=none, also munge, so that sender's domain owner doesn't get
# reports from sites with folks subscribed to our lists:
DEFAULT_DMARC_NONE_MODERATION_ACTION = Yes
# REMOVE_DKIM_HEADERS=3 -> always remove, rename and preserve original DKIM headers
REMOVE_DKIM_HEADERS = 3
----------------------------8< mm_cfg.py >8-----------------------------
Also, per our upgrade notes, we have to manually edit one file of
Mailman which is buggy in the presence of ARC:
-----------------------8< mailman update notes >8-----------------------
## ARC configuration
Minor hack, applied 2018-03-25, such that DKIM header cleansing does _not_
touch the Authentication-Results header.
Edited: `/opt/mailman/Mailman/Handlers/CleanseDKIM.py`
```
if (mm_cfg.REMOVE_DKIM_HEADERS == 3):
## ...
# for value in msg.get_all('authentication-results', []):
# msg['X-Mailman-Original-Authentication-Results'] = value
## ...
# del msg['authentication-results']
-----------------------8< mailman update notes >8-----------------------
That's "leave Authentication-Results: alone, because we need to sign
it". I don't think that I ever got around to trying to feed this
upstream, which is on me (lazyness).
I _think_ that's it.