+EXPERIMENTAL_PROXY=yes
+
+2. Global configuration settings:
+
+proxy_required_hosts = HOSTLIST
+
+The proxy_required_hosts option will require any IP in that hostlist
+to use Proxy Protocol. The specification of Proxy Protocol is very
+strict, and if proxy negotiation fails, Exim will not allow any SMTP
+command other than QUIT. (See end of this section for an example.)
+The option is expanded when used, so it can be a hostlist as well as
+string of IP addresses. Since it is expanded, specifying an alternate
+separator is supported for ease of use with IPv6 addresses.
+
+To log the IP of the proxy in the incoming logline, add:
+ log_selector = +proxy
+
+A default incoming logline (wrapped for appearance) will look like this:
+
+ 2013-11-04 09:25:06 1VdNti-0001OY-1V <= me@example.net
+ H=mail.example.net [1.2.3.4] P=esmtp S=433
+
+With the log selector enabled, an email that was proxied through a
+Proxy Protocol server at 192.168.1.2 will look like this:
+
+ 2013-11-04 09:25:06 1VdNti-0001OY-1V <= me@example.net
+ H=mail.example.net [1.2.3.4] P=esmtp PRX=192.168.1.2 S=433
+
+3. In the ACL's the following expansion variables are available.
+
+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_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_address}{}} } }
+ # But don't log health probes from the proxy itself
+ 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_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. Recommended ACL additions:
+ - Since the real connections are all coming from your proxy, and the
+ per host connection tracking is done before Proxy Protocol is
+ evaluated, smtp_accept_max_per_host must be set high enough to
+ handle all of the parallel volume you expect per inbound proxy.
+ - With the smtp_accept_max_per_host set so high, you lose the ability
+ to protect your server from massive numbers of inbound connections
+ from one IP. In order to prevent your server from being DOS'd, you
+ need to add a per connection ratelimit to your connect ACL. I
+ suggest something like this:
+
+ # Set max number of connections per host
+ LIMIT = 5
+ # Or do some kind of IP lookup in a flat file or database
+ # LIMIT = ${lookup{$sender_host_address}iplsearch{/etc/exim/proxy_limits}}
+
+ defer message = Too many connections from this IP right now
+ ratelimit = LIMIT / 5s / per_conn / strict
+
+
+5. Runtime issues to be aware of:
+ - The proxy has 3 seconds (hard-coded in the source code) to send the
+ required Proxy Protocol header after it connects. If it does not,
+ the response to any commands will be:
+ "503 Command refused, required Proxy negotiation failed"
+ - If the incoming connection is configured in Exim to be a Proxy
+ Protocol host, but the proxy is not sending the header, the banner
+ does not get sent until the timeout occurs. If the sending host
+ sent any input (before the banner), this causes a standard Exim
+ synchronization error (i.e. trying to pipeline before PIPELINING
+ was advertised).
+ - This is not advised, but is mentioned for completeness if you have
+ a specific internal configuration that you want this: If the Exim
+ server only has an internal IP address and no other machines in your
+ organization will connect to it to try to send email, you may
+ simply set the hostlist to "*", however, this will prevent local
+ mail programs from working because that would require mail from
+ localhost to use Proxy Protocol. Again, not advised!
+
+6. Example of a refused connection because the Proxy Protocol header was
+not sent from a host configured to use Proxy Protocol. In the example,
+the 3 second timeout occurred (when a Proxy Protocol banner should have
+been sent), the banner was displayed to the user, but all commands are
+rejected except for QUIT:
+
+# nc mail.example.net 25
+220-mail.example.net, ESMTP Exim 4.82+proxy, Mon, 04 Nov 2013 10:45:59
+220 -0800 RFC's enforced
+EHLO localhost
+503 Command refused, required Proxy negotiation failed
+QUIT
+221 mail.example.net closing connection
+
+
+
+
+SOCKS
+------------------------------------------------------------
+Support for proxying outbound SMTP via a Socks 5 proxy
+(RFC 1928) is included if Exim is compiled with
+EXPERIMENTAL_SOCKS defined.
+
+If an smtp transport has a nonempty socks_proxy option
+defined, this is active. The option is expanded and
+should be a list (colon-separated by default) of
+proxy specifiers. Each proxy specifier is a list
+(space-separated by default) where the initial element
+is an IP address and any subsequent elements are options.
+
+Options are a string <name>=<value>.
+These options are currently defined:
+- "auth", with possible values "none" and "name".
+ Using "name" selects username/password authentication
+ per RFC 1929. Default is "none".
+- "name" sets the authentication username. Default is empty.
+- "pass" sets the authentication password. Default is empty.
+- "port" sets the tcp port number for the proxy. Default is 1080.
+- "tmo" sets a connection timeout in seconds for this proxy. Default is 5.
+
+Proxies from the list are tried in order until
+one responds. The timeout for the overall connection
+applies to the set of proxied attempts.
+
+If events are used, the remote IP/port during a
+tcp:connect event will be that of the proxy.
+
+
+
+
+DANE
+------------------------------------------------------------
+DNS-based Authentication of Named Entities, as applied
+to SMTP over TLS, provides assurance to a client that
+it is actually talking to the server it wants to rather
+than some attacker operating a Man In The Middle (MITM)
+operation. The latter can terminate the TLS connection
+you make, and make another one to the server (so both
+you and the server still think you have an encrypted
+connection) and, if one of the "well known" set of
+Certificate Authorities has been suborned - something
+which *has* been seen already (2014), a verifiable
+certificate (if you're using normal root CAs, eg. the
+Mozilla set, as your trust anchors).
+
+What DANE does is replace the CAs with the DNS as the
+trust anchor. The assurance is limited to a) the possibility
+that the DNS has been suborned, b) mistakes made by the
+admins of the target server. The attack surface presented
+by (a) is thought to be smaller than that of the set
+of root CAs.
+
+It also allows the server to declare (implicitly) that
+connections to it should use TLS. An MITM could simply
+fail to pass on a server's STARTTLS.
+
+DANE scales better than having to maintain (and
+side-channel communicate) copies of server certificates
+for every possible target server. It also scales
+(slightly) better than having to maintain on an SMTP
+client a copy of the standard CAs bundle. It also
+means not having to pay a CA for certificates.
+
+DANE requires a server operator to do three things:
+1) run DNSSEC. This provides assurance to clients
+that DNS lookups they do for the server have not
+been tampered with. The domain MX record applying
+to this server, its A record, its TLSA record and
+any associated CNAME records must all be covered by
+DNSSEC.
+2) add TLSA DNS records. These say what the server
+certificate for a TLS connection should be.
+3) offer a server certificate, or certificate chain,
+in TLS connections which is traceable to the one
+defined by (one of?) the TSLA records
+
+There are no changes to Exim specific to server-side
+operation of DANE.
+
+The TLSA record for the server may have "certificate
+usage" of DANE-TA(2) or DANE-EE(3). The latter specifies
+the End Entity directly, i.e. the certificate involved
+is that of the server (and should be the sole one transmitted
+during the TLS handshake); this is appropriate for a
+single system, using a self-signed certificate.
+ DANE-TA usage is effectively declaring a specific CA
+to be used; this might be a private CA or a public,
+well-known one. A private CA at simplest is just
+a self-signed certificate which is used to sign
+cerver certificates, but running one securely does
+require careful arrangement. If a private CA is used
+then either all clients must be primed with it, or
+(probably simpler) the server TLS handshake must transmit
+the entire certificate chain from CA to server-certificate.
+If a public CA is used then all clients must be primed with it
+(losing one advantage of DANE) - but the attack surface is
+reduced from all public CAs to that single CA.
+DANE-TA is commonly used for several services and/or
+servers, each having a TLSA query-domain CNAME record,
+all of which point to a single TLSA record.
+
+The TLSA record should have a Selector field of SPKI(1)
+and a Matching Type field of SHA2-512(2).
+
+At the time of writing, https://www.huque.com/bin/gen_tlsa
+is useful for quickly generating TLSA records; and commands like
+
+ openssl x509 -in -pubkey -noout <certificate.pem \
+ | openssl rsa -outform der -pubin 2>/dev/null \
+ | openssl sha512 \
+ | awk '{print $2}'
+
+are workable for 4th-field hashes.
+
+For use with the DANE-TA model, server certificates
+must have a correct name (SubjectName or SubjectAltName).
+
+The use of OCSP-stapling should be considered, allowing
+for fast revocation of certificates (which would otherwise
+be limited by the DNS TTL on the TLSA records). However,
+this is likely to only be usable with DANE-TA. NOTE: the
+default of requesting OCSP for all hosts is modified iff
+DANE is in use, to:
+
+ hosts_request_ocsp = ${if or { {= {0}{$tls_out_tlsa_usage}} \
+ {= {4}{$tls_out_tlsa_usage}} } \
+ {*}{}}
+
+The (new) variable $tls_out_tlsa_usage is a bitfield with
+numbered bits set for TLSA record usage codes.
+The zero above means DANE was not in use,
+the four means that only DANE-TA usage TLSA records were
+found. If the definition of hosts_request_ocsp includes the
+string "tls_out_tlsa_usage", they are re-expanded in time to
+control the OCSP request.
+
+This modification of hosts_request_ocsp is only done if
+it has the default value of "*". Admins who change it, and
+those who use hosts_require_ocsp, should consider the interaction
+with DANE in their OCSP settings.
+
+
+For client-side DANE there are two new smtp transport options,
+hosts_try_dane and hosts_require_dane. They do the obvious thing.
+[ should they be domain-based rather than host-based? ]
+
+DANE will only be usable if the target host has DNSSEC-secured
+MX, A and TLSA records.
+
+A TLSA lookup will be done if either of the above options match
+and the host-lookup succeded using dnssec.
+If a TLSA lookup is done and succeeds, a DANE-verified TLS connection
+will be required for the host.
+
+(TODO: specify when fallback happens vs. when the host is not used)
+
+If DANE is requested and useable (see above) the following transport
+options are ignored:
+ hosts_require_tls
+ tls_verify_hosts
+ tls_try_verify_hosts
+ tls_verify_certificates
+ tls_crl
+ tls_verify_cert_hostnames
+
+If DANE is not usable, whether requested or not, and CA-anchored
+verification evaluation is wanted, the above variables should be set
+appropriately.
+
+Currently dnssec_request_domains must be active (need to think about that)
+and dnssec_require_domains is ignored.
+
+If verification was successful using DANE then the "CV" item
+in the delivery log line will show as "CV=dane".
+
+There is a new variable $tls_out_dane which will have "yes" if
+verification succeeded using DANE and "no" otherwise (only useful
+in combination with EXPERIMENTAL_EVENT), and a new variable
+$tls_out_tlsa_usage (detailed above).