-Exim now has Experimental "Proxy Protocol" support. It was built on
-specifications from:
-http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
-Above URL revised May 2014 to change version 2 spec:
-http://git.1wt.eu/web?p=haproxy.git;a=commitdiff;h=afb768340c9d7e50d8e
-
-The purpose of this function is so that an application load balancer,
-such as HAProxy, can sit in front of several Exim servers and Exim
-will log the IP that is connecting to the proxy server instead of
-the IP of the proxy server when it connects to Exim. It resets the
-$sender_address_host and $sender_address_port to the IP:port of the
-connection to the proxy. It also re-queries the DNS information for
-this new IP address so that the original sender's hostname and IP
-get logged in the Exim logfile. There is no logging if a host passes or
-fails Proxy Protocol negotiation, but it can easily be determined and
-recorded in an ACL (example is below).
-
-1. To compile Exim with Proxy Protocol support, put this in
-Local/Makefile:
-
-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
-
-
-DSN Support
---------------------------------------------------------------