package controlled locations (/usr/include and /usr/lib).
-2. Use the following global settings to configure DMARC:
+2. Use the following global options to configure DMARC:
-Optional:
+Required:
dmarc_tld_file Defines the location of a text file of valid
top level domains the opendmarc library uses
during domain parsing. Maintained by Mozilla,
the most current version can be downloaded
from a link at http://publicsuffix.org/list/.
- If unset, "/etc/exim/opendmarc.tlds" (hardcoded)
- is used.
+ See also util/renew-opendmarc-tlds.sh script.
+ The default for the option is currently
+ /etc/exim/opendmarc.tlds
Optional:
dmarc_history_file Defines the location of a file to log results
directory of this file is writable by the user
exim runs as.
-dmarc_forensic_sender The email address to use when sending a
+dmarc_forensic_sender Alternate email address to use when sending a
forensic report detailing alignment failures
if a sender domain's dmarc record specifies it
and you have configured Exim to send them.
- Default: do-not-reply@$default_hostname
+
+ If set, this is expanded and used for the
+ From: header line; the address is extracted
+ from it and used for the envelope from.
+ If not set, the From: header is expanded from
+ the dsn_from option, and <> is used for the
+ envelope from.
+
+ Default: unset.
3. By default, the DMARC processing will run for any remote,
supports, including LDAP, Postgres, MySQL, etc, as long as the
result is a list of colon-separated strings.
+Performing the check sets up information used by the
+${authresults } expansion item.
+
Several expansion variables are set before the DATA ACL is
processed, and you can use them in this ACL. The following
expansion variables are available:
are "none", "reject" and "quarantine". It is blank when there
is any error, including no DMARC record.
- o $dmarc_ar_header
- This is the entire Authentication-Results header which you can
- add using an add_header modifier.
+A now-redundant variable $dmarc_ar_header has now been withdrawn.
+Use the ${authresults } expansion instead.
5. How to enable DMARC advanced operation:
warn dmarc_status = accept : none : off
!authenticated = *
log_message = DMARC DEBUG: $dmarc_status $dmarc_used_domain
- add_header = $dmarc_ar_header
warn dmarc_status = !accept
!authenticated = *
!authenticated = *
message = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT
+ warn add_header = :at_start:${authresults {$primary_hostname}}
+
DSN extra information
The spool files can then be processed by external processes and then
requeued into exim spool directories for final delivery.
+However, note carefully the warnings in the main documentation on
+qpool file formats.
The motivation/inspiration for the transport is to allow external
processes to access email queued by exim and have access to all the
The transport only takes one option:
* directory - This is used to specify the directory messages should be
-copied to
+copied to. Expanded.
The generic transport options (body_only, current_directory, disable_logging,
debug_print, delivery_date_add, envelope_to_add, event_action, group,
Experimental_QUEUEFILE in the line "Support for:".
+ARC support
+-----------
+Specification: https://tools.ietf.org/html/draft-ietf-dmarc-arc-protocol-11
+Note that this is not an RFC yet, so may change.
+
+ARC is intended to support the utility of SPF and DKIM in the presence of
+intermediaries in the transmission path - forwarders and mailinglists -
+by establishing a cryptographically-signed chain in headers.
+
+Normally one would only bother doing ARC-signing when functioning as
+an intermediary. One might do verify for local destinations.
+
+ARC uses the notion of a "ADministrative Management Domain" (ADMD).
+Described in RFC 5598 (section 2.3), this is essentially the set of
+mail-handling systems that the mail transits. A label should be chosen to
+identify the ADMD. Messages should be ARC-verified on entry to the ADMD,
+and ARC-signed on exit from it.
+
+
+Verification
+--
+An ACL condition is provided to perform the "verifier actions" detailed
+in section 6 of the above specification. It may be called from the DATA ACL
+and succeeds if the result matches any of a given list.
+It also records the highest ARC instance number (the chain size)
+and verification result for later use in creating an Authentication-Results:
+standard header.
+
+ verify = arc/<acceptable_list> none:fail:pass
+
+ add_header = :at_start:${authresults {<admd-identifier>}}
+
+ Note that it would be wise to strip incoming messages of A-R headers
+ that claim to be from our own <admd-identifier>.
+
+There are four new variables:
+
+ $arc_state One of pass, fail, none
+ $arc_state_reason (if fail, why)
+ $arc_domains colon-sep list of ARC chain domains, in chain order.
+ problematic elements may have empty list elements
+ $arc_oldest_pass lowest passing instance number of chain
+
+Example:
+ logwrite = oldest-p-ams: <${reduce {$lh_ARC-Authentication-Results:} \
+ {} \
+ {${if = {$arc_oldest_pass} \
+ {${extract {i}{${extract {1}{;}{$item}}}}} \
+ {$item} {$value}}} \
+ }>
+
+Receive log lines for an ARC pass will be tagged "ARC".
+
+
+Signing
+--
+arc_sign = <admd-identifier> : <selector> : <privkey> [ : <options> ]
+An option on the smtp transport, which constructs and prepends to the message
+an ARC set of headers. The textually-first Authentication-Results: header
+is used as a basis (you must have added one on entry to the ADMD).
+Expanded as a whole; if unset, empty or forced-failure then no signing is done.
+If it is set, all of the first three elements must be non-empty.
+
+The fourth element is optional, and if present consists of a comma-separated list
+of options. The options implemented are
+
+ timestamps Add a t= tag to the generated AMS and AS headers, with the
+ current time.
+ expire[=<val>] Add an x= tag to the generated AMS header, with an expiry time.
+ If the value <val> is an plain number it is used unchanged.
+ If it starts with a '+' then the following number is added
+ to the current time, as an offset in seconds.
+ If a value is not given it defaults to a one month offset.
+
+[As of writing, gmail insist that a t= tag on the AS is mandatory]
+
+Caveats:
+ * There must be an Authentication-Results header, presumably added by an ACL
+ while receiving the message, for the same ADMD, for arc_sign to succeed.
+ This requires careful coordination between inbound and outbound logic.
+
+ Only one A-R header is taken account of. This is a limitation versus
+ the ARC spec (which says that all A-R headers from within the ADMD must
+ be used).
+
+ * If passing a message to another system, such as a mailing-list manager
+ (MLM), between receipt and sending, be wary of manipulations to headers made
+ by the MLM.
+ + For instance, Mailman with REMOVE_DKIM_HEADERS==3 might improve
+ deliverability in a pre-ARC world, but that option also renames the
+ Authentication-Results header, which breaks signing.
+
+ * Even if you use multiple DKIM keys for different domains, the ARC concept
+ should try to stick to one ADMD, so pick a primary domain and use that for
+ AR headers and outbound signing.
+
+Signing is not compatible with cutthrough delivery; any (before expansion)
+value set for the option will result in cutthrough delivery not being
+used via the transport in question.
+
+
+
+
+Early pipelining support
+------------------------
+Ref: https://datatracker.ietf.org/doc/draft-harris-early-pipe/
+
+If compiled with EXPERIMENTAL_PIPE_CONNECT support is included for this feature.
+The server advertises the feature in its EHLO response, currently using the name
+"X_PIPE_CONNECT" (this will change, some time in the future).
+A client may cache this information, along with the rest of the EHLO response,
+and use it for later connections. Those later ones can send esmtp commands before
+a banner is received.
+
+Up to 1.5 roundtrip times can be taken out of cleartext connections, 2.5 on
+STARTTLS connections.
+
+In combination with the traditional PIPELINING feature the following example
+sequences are possible (among others):
+
+(client) (server)
+
+EHLO,MAIL,RCPT,DATA ->
+ <- banner,EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
+message-data ->
+------
+
+EHLO,MAIL,RCPT,BDAT ->
+ <- banner,EHLO-resp,MAIL-ack,RCPT-ack
+message-data ->
+------
+
+EHLO,STARTTLS ->
+ <- banner,EHLO-resp,TLS-goahead
+TLS1.2-client-hello ->
+ <- TLS-server-hello,cert,hello-done
+client-Kex,change-cipher,finished ->
+ <- change-cipher,finished
+EHLO,MAIL,RCPT,DATA ->
+ <- EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
+
+------
+(tls-on-connect)
+TLS1.2-client-hello ->
+ <- TLS-server-hello,cert,hello-done
+client-Kex,change-cipher,finished ->
+ <- change-cipher,finshed
+ <- banner
+EHLO,MAIL,RCPT,DATA ->
+ <- EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
+
+Where the initial client packet is SMTP, it can combine with the TCP Fast Open
+feature and be sent in the TCP SYN.
+
+
+A main-section option "pipelining_connect_advertise_hosts" (default: *)
+and an smtp transport option "hosts_pipe_connect" (default: unset)
+control the feature.
+
+If the "pipelining" log_selector is enabled, the "L" field in server <=
+log lines has a period appended if the feature was advertised but not used;
+or has an asterisk appended if the feature was used. In client => lines
+the "L" field has an asterisk appended if the feature was used.
+
+The "retry_data_expire" option controls cache invalidation.
+Entries are also rewritten (or cleared) if the adverised features
+change.
+
+
+NOTE: since the EHLO command must be constructed before the connection is
+made it cannot depend on the interface IP address that will be used.
+Transport configurations should be checked for this. An example avoidance:
+
+ helo_data = ${if def:sending_ip_address \
+ {${lookup dnsdb{>! ptr=$sending_ip_address} \
+ {${sg{$value} {^([^!]*).*\$} {\$1}}} fail}} \
+ {$primary_hostname}}
+
+
+
+
+TLS Session Resumption
+----------------------
+TLS Session Resumption for TLS 1.2 and TLS 1.3 connections can be used (defined
+in RFC 5077 for 1.2). The support for this can be included by building with
+EXPERIMENTAL_TLS_RESUME defined. This requires GnuTLS 3.6.3 or OpenSSL 1.1.1
+(or later).
+
+Session resumption (this is the "stateless" variant) involves the server sending
+a "session ticket" to the client on one connection, which can be stored by the
+client and used for a later session. The ticket contains sufficient state for
+the server to reconstruct the TLS session, avoiding some expensive crypto
+calculation and one full packet roundtrip time.
+
+Operational cost/benefit:
+ The extra data being transmitted costs a minor amount, and the client has
+ extra costs in storing and retrieving the data.
+
+ In the Exim/Gnutls implementation the extra cost on an initial connection
+ which is TLS1.2 over a loopback path is about 6ms on 2017-laptop class hardware.
+ The saved cost on a subsequent connection is about 4ms; three or more
+ connections become a net win. On longer network paths, two or more
+ connections will have an average lower startup time thanks to the one
+ saved packet roundtrip. TLS1.3 will save the crypto cpu costs but not any
+ packet roundtrips.
+
+ Since a new hints DB is used, the hints DB maintenance should be updated
+ to additionally handle "tls".
+
+Security aspects:
+ The session ticket is encrypted, but is obviously an additional security
+ vulnarability surface. An attacker able to decrypt it would have access
+ all connections using the resumed session.
+ The session ticket encryption key is not committed to storage by the server
+ and is rotated regularly. Tickets have limited lifetime.
+
+ There is a question-mark over the security of the Diffie-Helman parameters
+ used for session negotiation. TBD. q-value; cf bug 1895
+
+Observability:
+ New log_selector "tls_resumption", appends an asterisk to the tls_cipher "X="
+ element.
+
+ Variables $tls_{in,out}_resumption have bits 0-4 indicating respectively
+ support built, client requested ticket, client offered session,
+ server issued ticket, resume used. A suitable decode list is provided
+ in the builtin macro _RESUME_DECODE for ${listextract {}{}}.
+
+Issues:
+ In a resumed session:
+ $tls_{in,out}_certificate_verified will be set, and verify = certificate
+ will be true, when verify failed but tls_try_verify_hosts allowed the
+ connection (under OpenSSL)
+ $tls_{in,out}_cipher will have values different to the original (under GnuTLS)
+ $tls_{in,out}_ocsp will be "not requested" or "no response", and
+ hosts_require_ocsp will fail
+
+
--------------------------------------------------------------
End of file
--------------------------------------------------------------