Given a setup where CloudFlare is in front of a Varnish Cache that relays traffic to multiple Apache backends, the problem is to be able to log and receive the correct / real IP address of connecting clients on the Apache backends. This has to be performed for various reasons - most notably, however, would be the need for PHP and other session consistency where you cannot have an Apache backend believing that all traffic originates from the upstream cache (in this case, Varnish).
When the client wants to connect to your server, it passes through CloudFlare. CloudFlare takes the real IP address of the client and places it in the CF-Connecting-IP header whilst passing on the CloudFlare IP address to the Varnish server. Varnish will then connect to the Apache backends and pass the Varnish IP address to Apache such that the logs will display accesses from Varnish - which is a very far stretch from the client's real IP address.
This note assumes that Apache is installed and working on the backends and that Varnish is installed on the frontend.
The varnish VCL for your site will have to be altered to make an addition to the vcl_recv
stanza that is called at the beginning of the request in order to extract the value of the CloudFlare non-standard CF-Connecting-IP
header and place the value in X-Forwarded-For
and pass the request to Apache.
sub vcl_recv { # When CloudFlare is in front of varnish, send the real IP address through X-Forwarded-For # otherwise if CloudFlare is not involved, set the X-Forwarded-For to the client IP address. unset req.http.X-Forwarded-For; if (req.http.cf-connecting-ip) { set req.http.X-Forwarded-For = req.http.cf-connecting-ip; } else { set req.http.X-Forwarded-For = client.ip; } }
The additions take care to pass the client IP address in case the CloudFlare CF-Connecting-IP
header is not present.
Apache needs the rpaf
module installed. Under Debian (and derivates such as Ubuntu), this can be achieved by issuing:
aptitude install libapache2-mod-rpaf
and on BSD, one would need to install the www/mod_rpaf2
port.
rpaf
will be responsible for capturing the X-Forwarded-For
header sent by Varnish and then replacing the Varnish cache IP address with the real IP address.
Depending on your *nix flavour, rpaf
must be enabled and configured - for Apache-specific configurations, this should be done by adding an include file with the following contents:
<IfModule dav_svn_module> RPAFenable On RPAFproxy_ips 84.26.130.2 RPAFsethostname On RPAFheader X-Forwarded-For RPAFheader Incap-Client-IP </IfModule>
where:
84.26.130.2
is the IP address of the Varnish server that connects to this Apache backend.Reload Apache and Varnish and monitor the Apache access logs to see the requests coming in and check that the IP addresses are real client IP addresses instead of your Varnish frontend or CloudFlare addresses.