Proxy Protocol - Server support
[users/heiko/exim.git] / doc / doc-txt / experimental-spec.txt
index 3e8f5c549fcdc6a167af37833f2242d8353b68da..92790ae33a158bfd05fc748c0aafc0b32f16bb55 100644 (file)
@@ -755,11 +755,13 @@ mean, refer to the DMARC website above.  Valid strings are:
                 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 none        There is no DMARC record for this sender domain.
-  o error       Library error or dns error.
+  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
@@ -910,7 +912,7 @@ log failures of remote hosts. It is executed only when exim has
 attempted to deliver a message to a remote host and failed due to
 an error which doesn't seem to be related to the individual
 message, sender, or recipient address.
-See section 45.2 of the exim documentation for more details on how
+See section 47.2 of the exim documentation for more details on how
 this is determined.
 
 Example:
@@ -929,6 +931,203 @@ ${lookup mysql {insert into delivlog set \
     deliverrstr = '${quote_mysql:$tpda_defer_errstr}' \
     }}
 
+
+Redis Lookup
+--------------------------------------------------------------
+
+Redis is open source advanced key-value data store. This document
+does not explain the fundamentals, you should read and understand how
+it works by visiting the website at http://www.redis.io/.
+
+Redis lookup support is added via the hiredis library.  Visit:
+
+  https://github.com/redis/hiredis
+
+to obtain a copy, or find it in your operating systems 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. In order to build exim with Redis lookup support add
+
+EXPERIMENTAL_REDIS=yes
+
+to your Local/Makefile. (Re-)build/install exim. exim -d should show
+Experimental_Redis in the line "Support for:".
+
+EXPERIMENTAL_REDIS=yes
+LDFLAGS += -lhiredis
+# 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 hiredis libraries into the
+exim binary.  The commented out lines should be uncommented if you
+built hiredis 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 settings to configure Redis lookup support:
+
+Required:
+redis_servers       This option provides a list of Redis servers
+                    and associated connection data, to be used in
+                    conjunction with redis lookups. The option is
+                    only available if Exim is configured with Redis
+                    support.
+
+For example:
+
+redis_servers = 127.0.0.1/10/ - using database 10 with no password
+redis_servers = 127.0.0.1//password - to make use of the default database of 0 with a password
+redis_servers = 127.0.0.1// - for default database of 0 with no password
+
+3. Once you have the Redis servers defined you can then make use of the
+experimental Redis lookup by specifying ${lookup redis{}} in a lookup query.
+
+4. Example usage:
+
+(Host List)
+hostlist relay_from_ips = <\n ${lookup redis{SMEMBERS relay_from_ips}}
+
+Where relay_from_ips is a Redis set which contains entries such as "192.168.0.0/24" "10.0.0.0/8" and so on.
+The result set is returned as
+192.168.0.0/24
+10.0.0.0/8
+..
+.
+
+(Domain list)
+domainlist virtual_domains = ${lookup redis {HGET $domain domain}}
+
+Where $domain is a hash which includes the key 'domain' and the value '$domain'.
+
+(Adding or updating an existing key)
+set acl_c_spammer = ${if eq{${lookup redis{SPAMMER_SET}}}{OK}}
+
+Where SPAMMER_SET is a macro and it is defined as
+
+"SET SPAMMER <some_value>"
+
+(Getting a value from Redis)
+
+set acl_c_spam_host = ${lookup redis{GET...}}
+
+
+Proxy Protocol Support
+--------------------------------------------------------------
+
+Exim now has Experimental "Proxy Protocol" support.  It was built on
+specifications from:
+http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
+
+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     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.
+
+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}{}} } }
+          log_message    = Failed required proxy protocol negotiation \
+                           from $sender_host_name [$sender_host_address]
+
+  warn    condition      = ${if and{ {bool{$proxy_session}} \
+                                     {!eq{$proxy_host}{}} } }
+          # But don't log health probes from the proxy itself
+          condition      = ${if eq{$proxy_host}{$sender_host_address} \
+                                {false}{true}}
+          log_message    = Successfully proxied from $sender_host_name \
+                           [$sender_host_address] through proxy protocol \
+                           host $proxy_host
+
+4. Runtime issues to be aware of:
+   - 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.
+   - 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!
+
+5. 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
+
+
+
 --------------------------------------------------------------
 End of file
 --------------------------------------------------------------