DMARC: promote the support from Experimental to mainline
[exim.git] / doc / doc-txt / experimental-spec.txt
index a2861c4a968b94f07d7e7f4ff1ad0b246b6279a1..2b77d264733ca7c7c40862ec831e0e9f323ff7f3 100644 (file)
@@ -390,239 +390,6 @@ Use a reasonable IP. eg. one the sending cluster actually uses.
 
 
 
 
 
 
-DMARC Support
---------------------------------------------------------------
-
-DMARC combines feedback from SPF, DKIM, and header From: in order
-to attempt to provide better indicators of the authenticity of an
-email.  This document does not explain the fundamentals, you
-should read and understand how it works by visiting the website at
-http://www.dmarc.org/.
-
-DMARC support is added via the libopendmarc library.  Visit:
-
-  http://sourceforge.net/projects/opendmarc/
-
-to obtain a copy, or find it in your favorite rpm package
-repository.  If building from source, this description assumes
-that headers will be in /usr/local/include, and that the libraries
-are in /usr/local/lib.
-
-1. To compile Exim with DMARC support, you must first enable SPF.
-Please read the Local/Makefile comments on enabling the SUPPORT_SPF
-feature.  You must also have DKIM support, so you cannot set the
-DISABLE_DKIM feature.  Once both of those conditions have been met
-you can enable DMARC in Local/Makefile:
-
-EXPERIMENTAL_DMARC=yes
-LDFLAGS += -lopendmarc
-# CFLAGS += -I/usr/local/include
-# LDFLAGS += -L/usr/local/lib
-
-The first line sets the feature to include the correct code, and
-the second line says to link the libopendmarc libraries into the
-exim binary.  The commented out lines should be uncommented if you
-built opendmarc from source and installed in the default location.
-Adjust the paths if you installed them elsewhere, but you do not
-need to uncomment them if an rpm (or you) installed them in the
-package controlled locations (/usr/include and /usr/lib).
-
-
-2. Use the following global options to configure DMARC:
-
-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/.
-                    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
-                    of dmarc verification on inbound emails. The
-                    contents are importable by the opendmarc tools
-                    which will manage the data, send out DMARC
-                    reports, and expire the data. Make sure the
-                    directory of this file is writable by the user
-                    exim runs as.
-
-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.
-
-                   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,
-non-authenticated user.  It makes sense to only verify DMARC
-status of messages coming from remote, untrusted sources.  You can
-use standard conditions such as hosts, senders, etc, to decide that
-DMARC verification should *not* be performed for them and disable
-DMARC with a control setting:
-
-  control = dmarc_disable_verify
-
-A DMARC record can also specify a "forensic address", which gives
-exim an email address to submit reports about failed alignment.
-Exim does not do this by default because in certain conditions it
-results in unintended information leakage (what lists a user might
-be subscribed to, etc).  You must configure exim to submit forensic
-reports to the owner of the domain.  If the DMARC record contains a
-forensic address and you specify the control statement below, then
-exim will send these forensic emails.  It's also advised that you
-configure a dmarc_forensic_sender because the default sender address
-construction might be inadequate.
-
-  control = dmarc_enable_forensic
-
-(AGAIN: You can choose not to send these forensic reports by simply
-not putting the dmarc_enable_forensic control line at any point in
-your exim config.  If you don't tell it to send them, it will not
-send them.)
-
-There are no options to either control.  Both must appear before
-the DATA acl.
-
-
-4. You can now run DMARC checks in incoming SMTP by using the
-"dmarc_status" ACL condition in the DATA ACL.  You are required to
-call the spf condition first in the ACLs, then the "dmarc_status"
-condition.  Putting this condition in the ACLs is required in order
-for a DMARC check to actually occur.  All of the variables are set
-up before the DATA ACL, but there is no actual DMARC check that
-occurs until a "dmarc_status" condition is encountered in the ACLs.
-
-The dmarc_status condition takes a list of strings on its
-right-hand side.  These strings describe recommended action based
-on the DMARC check.  To understand what the policy recommendations
-mean, refer to the DMARC website above.  Valid strings are:
-
-  o accept      The DMARC check passed and the library recommends
-                accepting the email.
-  o reject      The DMARC check failed and the library recommends
-                rejecting the email.
-  o quarantine  The DMARC check failed and the library recommends
-                keeping it for further inspection.
-  o none        The DMARC check passed and the library recommends
-                no specific action, neutral.
-  o norecord    No policy section in the DMARC record for this
-                sender domain.
-  o nofrom      Unable to determine the domain of the sender.
-  o temperror   Library error or dns error.
-  o off         The DMARC check was disabled for this email.
-
-You can prefix each string with an exclamation mark to invert its
-meaning, for example "!accept" will match all results but
-"accept".  The string list is evaluated left-to-right in a
-short-circuit fashion.  When a string matches the outcome of the
-DMARC check, the condition succeeds.  If none of the listed
-strings matches the outcome of the DMARC check, the condition
-fails.
-
-Of course, you can also use any other lookup method that Exim
-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:
-
-  o $dmarc_status
-    This is a one word status indicating what the DMARC library
-    thinks of the email.  It is a combination of the results of
-    DMARC record lookup and the SPF/DKIM/DMARC processing results
-    (if a DMARC record was found).  The actual policy declared
-    in the DMARC record is in a separate expansion variable.
-
-  o $dmarc_status_text
-    This is a slightly longer, human readable status.
-
-  o $dmarc_used_domain
-    This is the domain which DMARC used to look up the DMARC
-    policy record.
-
-  o $dmarc_domain_policy
-    This is the policy declared in the DMARC record.  Valid values
-    are "none", "reject" and "quarantine".  It is blank when there
-    is any error, including no DMARC record.
-
-A now-redundant variable $dmarc_ar_header has now been withdrawn.
-Use the ${authresults } expansion instead.
-
-
-5. How to enable DMARC advanced operation:
-By default, Exim's DMARC configuration is intended to be
-non-intrusive and conservative.  To facilitate this, Exim will not
-create any type of logging files without explicit configuration by
-you, the admin.  Nor will Exim send out any emails/reports about
-DMARC issues without explicit configuration by you, the admin (other
-than typical bounce messages that may come about due to ACL
-processing or failure delivery issues).
-
-In order to log statistics suitable to be imported by the opendmarc
-tools, you need to:
-a. Configure the global setting dmarc_history_file.
-b. Configure cron jobs to call the appropriate opendmarc history
-   import scripts and truncating the dmarc_history_file.
-
-In order to send forensic reports, you need to:
-a. Configure the global setting dmarc_forensic_sender.
-b. Configure, somewhere before the DATA ACL, the control option to
-   enable sending DMARC forensic reports.
-
-
-6. Example usage:
-(RCPT ACL)
-  warn    domains        = +local_domains
-          hosts          = +local_hosts
-          control        = dmarc_disable_verify
-
-  warn    !domains       = +screwed_up_dmarc_records
-          control        = dmarc_enable_forensic
-
-  warn    condition      = (lookup if destined to mailing list)
-          set acl_m_mailing_list = 1
-
-(DATA ACL)
-  warn    dmarc_status   = accept : none : off
-          !authenticated = *
-          log_message    = DMARC DEBUG: $dmarc_status $dmarc_used_domain
-
-  warn    dmarc_status   = !accept
-          !authenticated = *
-          log_message    = DMARC DEBUG: '$dmarc_status' for $dmarc_used_domain
-
-  warn    dmarc_status   = quarantine
-          !authenticated = *
-          set $acl_m_quarantine = 1
-          # Do something in a transport with this flag variable
-
-  deny    condition      = ${if eq{$dmarc_domain_policy}{reject}}
-          condition      = ${if eq{$acl_m_mailing_list}{1}}
-          message        = Messages from $dmarc_used_domain break mailing lists
-
-  deny    dmarc_status   = reject
-          !authenticated = *
-          message        = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT
-
-  warn    add_header     = :at_start:${authresults {$primary_hostname}}
-
-
-
 DSN extra information
 ---------------------
 If compiled with EXPERIMENTAL_DSN_INFO extra information will be added
 DSN extra information
 ---------------------
 If compiled with EXPERIMENTAL_DSN_INFO extra information will be added
@@ -873,89 +640,12 @@ 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
 ----------------------
-TLS Session Resumption for TLS 1.2 and TLS1.3 connections can be used (defined
+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
 in RFC 5077 for 1.2).  The support for this can be included by building with
-EXPERIMENTAL_TLS_RESUME defined.
+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
 
 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
@@ -965,34 +655,46 @@ calculation and one full packet roundtrip time.
 
 Operational cost/benefit:
  The extra data being transmitted costs a minor amount, and the client has
 
 Operational cost/benefit:
  The extra data being transmitted costs a minor amount, and the client has
-extra costs in storing and retrieving the data.
+ 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.
+ 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
 
 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.
+ 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 (OpenSSL: 1hr, and one previous key is used for
+ overlap; GnuTLS 6hr but does not specify any overlap).
+ Tickets have limited lifetime (2hr, and new ones issued after 1hr under
+ OpenSSL.  GnuTLS 2hr, appears to not do overlap).
 
 
-There is a question-mark over the security of the Diffie-Helman parameters
-used for session negotiation. TBD.  q-value; cf bug 1895
+ 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="
 
 Observability:
  New log_selector "tls_resumption", appends an asterisk to the tls_cipher "X="
-element.
-
-Variables $tls_{in,out}_resumption have bit 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 {}{}}.
+ 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}_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
 
 
 --------------------------------------------------------------
 
 
 --------------------------------------------------------------