X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/43e2db44c657b07340368eae5dd05e51eab829fb..047d31cbc35d5323345a135ad87ef38f8a5c4789:/doc/doc-txt/experimental-spec.txt?ds=sidebyside diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt index feecb3375..2569ad3af 100644 --- a/doc/doc-txt/experimental-spec.txt +++ b/doc/doc-txt/experimental-spec.txt @@ -292,10 +292,11 @@ These four steps are explained in more details below. -SRS (Sender Rewriting Scheme) Support +SRS (Sender Rewriting Scheme) Support (using libsrs_alt) -------------------------------------------------------------- +See also below, for an alternative native support implementation. -Exiscan currently includes SRS support via Miles Wilton's +Exim currently includes SRS support via Miles Wilton's libsrs_alt library. The current version of the supported library is 0.5, there are reports of 1.0 working. @@ -312,6 +313,105 @@ EXPERIMENTAL_SRS=yes in your Local/Makefile. +The following main-section options become available: + srs_config string + srs_hashlength int + srs_hashmin int + srs_maxage int + srs_secrets string + srs_usehash bool + srs_usetimestamp bool + +The redirect router gains these options (all of type string, unset by default): + srs + srs_alias + srs_condition + srs_dbinsert + srs_dbselect + +The following variables become available: + $srs_db_address + $srs_db_key + $srs_orig_recipient + $srs_orig_sender + $srs_recipient + $srs_status + +The predefined feature-macro _HAVE_SRS will be present. +Additional delivery log line elements, tagged with "SRS=" will show the srs sender. +For configuration information see https://github.com/Exim/exim/wiki/SRS . + + + + +SRS (Sender Rewriting Scheme) Support (native) +-------------------------------------------------------------- +This is less full-featured than the libsrs_alt version above. + +The Exim build needs to be done with this in Local/Makefile: +EXPERIMENTAL_SRS_NATIVE=yes + +The following are provided: +- an expansion item "srs_encode" + This takes three arguments: + - a site SRS secret + - the return_path + - the pre-forwarding domain + +- an expansion condition "inbound_srs" + This takes two arguments: the local_part to check, and a site SRS secret. + If the secret is zero-length, only the pattern of the local_part is checked. + The $srs_recipient variable is set as a side-effect. + +- an expansion variable $srs_recipient + This gets the original return_path encoded in the SRS'd local_part + +- predefined macros _HAVE_SRS and _HAVE_NATIVE_SRS + +Sample usage: + + #macro + SRS_SECRET = + + #routers + + outbound: + driver = dnslookup + # if outbound, and forwarding has been done, use an alternate transport + domains = ! +my_domains + transport = ${if eq {$local_part@$domain} \ + {$original_local_part@$original_domain} \ + {remote_smtp} {remote_forwarded_smtp}} + + inbound_srs: + driver = redirect + senders = : + domains = +my_domains + # detect inbound bounces which are SRS'd, and decode them + condition = ${if inbound_srs {$local_part} {SRS_SECRET}} + data = $srs_recipient + + inbound_srs_failure: + driver = redirect + senders = : + domains = +my_domains + # detect inbound bounces which look SRS'd but are invalid + condition = ${if inbound_srs {$local_part} {}} + allow_fail + data = :fail: Invalid SRS recipient address + + #... further routers here + + + # transport; should look like the non-forward outbound + # one, plus the max_rcpt and return_path options + remote_forwarded_smtp: + driver = smtp + # modify the envelope from, for mails that we forward + max_rcpt = 1 + return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}} + + DCC Support @@ -390,239 +490,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 @@ -775,6 +642,9 @@ 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. +[RFC 8617 was published 2019/06. Draft 11 was 2018/01. A review of the +changes has not yet been done] + 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. @@ -783,10 +653,18 @@ 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. +Described in RFC 5598 (section 2.3), this is essentially a set of +mail-handling systems that mail transits that are all under the control +of one organisation. 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. + + +Building with ARC Support +-- +Enable using EXPERIMENTAL_ARC=yes in your Local/Makefile. +You must also have DKIM present (not disabled), and you very likely +want to have SPF enabled. Verification @@ -873,84 +751,6 @@ 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 @@ -966,34 +766,46 @@ 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. + 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 -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=" -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 --------------------------------------------------------------