liable to incompatible change.
-PRDR support
---------------------------------------------------------------
-
-Per-Recipient Data Reponse is an SMTP extension proposed by Eric Hall
-in a (now-expired) IETF draft from 2007. It's not hit mainstream
-use, but has apparently been implemented in the META1 MTA.
-
-There is mention at http://mail.aegee.org/intern/sendmail.html
-of a patch to sendmail "to make it PRDR capable".
-
- ref: http://www.eric-a-hall.com/specs/draft-hall-prdr-00.txt
-
-If Exim is built with EXPERIMENTAL_PRDR there is a new config
-boolean "prdr_enable" which controls whether PRDR is advertised
-as part of an EHLO response, a new "acl_data_smtp_prdr" ACL
-(called for each recipient, after data arrives but before the
-data ACL), and a new smtp transport option "hosts_try_prdr".
-
-PRDR may be used to support per-user content filtering. Without it
-one must defer any recipient after the first that has a different
-content-filter configuration. With PRDR, the RCPT-time check
-for this can be disabled when the MAIL-time $smtp_command included
-"PRDR". Any required difference in behaviour of the main DATA-time
-ACL should however depend on the PRDR-time ACL having run, as Exim
-will avoid doing so in some situations (eg. single-recipient mails).
-
-
-
OCSP Stapling support
--------------------------------------------------------------
proof expires. The downside is that it requires server support.
If Exim is built with EXPERIMENTAL_OCSP and it was built with OpenSSL,
-then it gains a new global option: "tls_ocsp_file".
+or with GnuTLS 3.1.3 or later, then it gains a new global option:
+"tls_ocsp_file".
The file specified therein is expected to be in DER format, and contain
an OCSP proof. Exim will serve it as part of the TLS handshake. This
on each connection, so a new file will be handled transparently on the
next connection.
-Exim will check for a valid next update timestamp in the OCSP proof;
-if not present, or if the proof has expired, it will be ignored.
+Under OpenSSL Exim will check for a valid next update timestamp in the
+OCSP proof; if not present, or if the proof has expired, it will be
+ignored.
+
+Also, given EXPERIMENTAL_OCSP, the smtp transport gains two options:
+- "hosts_require_ocsp"; a host-list for which an OCSP Stapling
+is requested and required for the connection to proceed. The default
+value is empty.
+- "hosts_request_ocsp"; a host-list for which (additionally) an OCSP
+Stapling is requested (but not necessarily verified). The default
+value is "*" meaning that requests are made unless configured
+otherwise.
-Also, given EXPERIMENTAL_OCSP and OpenSSL, the smtp transport gains
-a "hosts_require_ocsp" option; a host-list for which an OCSP Stapling
-is requested and required for the connection to proceed. The host(s)
-should also be in "hosts_require_tls", and "tls_verify_certificates"
-configured for the transport.
+The host(s) should also be in "hosts_require_tls", and
+"tls_verify_certificates" configured for the transport.
For the client to be able to verify the stapled OCSP the server must
also supply, in its stapled information, any intermediate
intermediate certificates should be added to the server OCSP stapling
file (named by tls_ocsp_file).
+Note that the proof only covers the terminal server certificate,
+not any of the chain from CA to it.
+
At this point in time, we're gathering feedback on use, to determine if
it's worth adding complexity to the Exim daemon to periodically re-fetch
OCSP files and somehow handling multiple files.
OCSP server is supplied. The server URL may be included in the
server certificate, if the CA is helpful.
- One fail mode seen was the OCSP Signer cert expiring before the end
- of vailidity of the OCSP proof. The checking done by Exim/OpenSSL
+ One failure mode seen was the OCSP Signer cert expiring before the end
+ of validity of the OCSP proof. The checking done by Exim/OpenSSL
noted this as invalid overall, but the re-fetch script did not.
This means the queried domain has published
a SPF record, but wants to allow outside
servers to send mail under its domain as well.
- o err_perm This indicates a syntax error in the SPF
- record of the queried domain. This should be
- treated like "none".
- o err_temp This indicates a temporary error during all
+ This should be treated like "none".
+ o permerror This indicates a syntax error in the SPF
+ record of the queried domain. You may deny
+ messages when this occurs. (Changed in 4.83)
+ o temperror This indicates a temporary error during all
processing, including Exim's SPF processing.
You may defer messages when this occurs.
+ (Changed in 4.83)
+ o err_temp Same as permerror, deprecated in 4.83, will be
+ removed in a future release.
+ o err_perm Same as temperror, deprecated in 4.83, will be
+ removed in a future release.
You can prefix each string with an exclamation mark to invert
-is meaning, for example "!fail" will match all results but
+its meaning, for example "!fail" will match all results but
"fail". The string list is evaluated left-to-right, in a
short-circuit fashion. When a string matches the outcome of
the SPF check, the condition succeeds. If none of the listed
$spf_result
This contains the outcome of the SPF check in string form,
- one of pass, fail, softfail, none, neutral, err_perm or
- err_temp.
+ one of pass, fail, softfail, none, neutral, permerror or
+ temperror.
$spf_smtp_comment
This contains a string that can be used in a SMTP response
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;
+result is a list of colon-separated strings.
Several expansion variables are set before the DATA ACL is
processed, and you can use them in this ACL. The following
o $dmarc_status
This is a one word status indicating what the DMARC library
- thinks of the email.
+ 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.
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.
+
o $dmarc_ar_header
This is the entire Authentication-Results header which you can
add using an add_header modifier.
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 = *
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 $domain_used_domain failed sender's DMARC policy, REJECT
3. In the ACL's the following expansion variables are available.
-proxy_host The src IP of the proxy server making the connection
-proxy_port The src port the proxy server is using
-proxy_session Boolean, yes/no, the connected host is required to use
- Proxy Protocol.
+proxy_host_address The (internal) src IP of the proxy server
+ making the connection to the Exim server.
+proxy_host_port The (internal) src port the proxy server is
+ using to connect to the Exim server.
+proxy_target_address The dest (public) IP of the remote host to
+ the proxy server.
+proxy_target_port The dest port the remote host is using to
+ connect to the proxy server.
+proxy_session Boolean, yes/no, the connected host is required
+ to use Proxy Protocol.
There is no expansion for a failed proxy session, however you can detect
it by checking if $proxy_session is true but $proxy_host is empty. As
an example, in my connect ACL, I have:
warn condition = ${if and{ {bool{$proxy_session}} \
- {eq{$proxy_host}{}} } }
+ {eq{$proxy_host_address}{}} } }
log_message = Failed required proxy protocol negotiation \
from $sender_host_name [$sender_host_address]
warn condition = ${if and{ {bool{$proxy_session}} \
- {!eq{$proxy_host}{}} } }
+ {!eq{$proxy_host_address}{}} } }
# But don't log health probes from the proxy itself
- condition = ${if eq{$proxy_host}{$sender_host_address} \
+ condition = ${if eq{$proxy_host_address}{$sender_host_address} \
{false}{true}}
log_message = Successfully proxied from $sender_host_name \
[$sender_host_address] through proxy protocol \
- host $proxy_host
+ host $proxy_host_address
+
+ # Possibly more clear
+ warn logwrite = Remote Source Address: $sender_host_address:$sender_host_port
+ logwrite = Proxy Target Address: $proxy_target_address:$proxy_target_port
+ logwrite = Proxy Internal Address: $proxy_host_address:$proxy_host_port
+ logwrite = Internal Server Address: $received_ip_address:$received_port
+
4. Runtime issues to be aware of:
- Since the real connections are all coming from your proxy, and the