Client IP with X-Forwarded-For across multiple proxies

When you're running HA-Proxy or Nginx in front of Apache, you lose client IP address information. The TCP connection to your Apache server come from Nginx, so all your logs reflect one single client IP address. This is a problem if you run a forum, as it will calculate the number of site visitors by IP address. Worse, this may flag the flood controls on some forum software. At minimum, it throws off log analysis.

X-Forwarded-For is an HTTP header that allows allows Layer 7 (HTTP) Proxies to pass along the original, external client IP to the next destination. To use this, your reverse proxy, caching server, or load-balancer must be configure to add that header to HTTP requests, and the destination point must be configured to look for it.

Everyone has a tutorial for configuring X-Fowarded-For across two servers (say, Nginx+Apache, or HAProxy+Apache). But what happens when you have an HAProxy load balancer balancing between three Nginx caches, which forwards to Apache for PHP/MySQL? That client IP address needs to passed across three different HTTP servers.

Assuming that HAProxy is has address, Nginx is running on another server with, and Apache is at

HAProxy will need to be configured with this option to pass the X-Forwarded-For header of the connecting IP.
option forwardfor

Nginx will need the following to both *receive* the X-Forwarded-For header from the HAProxy server, and then *add* the X-Fowarded-For header to the new connection to Apache.

In your main Nginx.conf file:

set_real_ip_from; # this is the HAProxy connecting IP address
real_ip_header X-Forwarded-for; # The specific header to be read

In your proxy configuration, either in nginx.conf or in a separate include file, you'll need something similar to this:

location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Finally, Apache can use the Rpaf module to read the X-Forwarded-For header from Nginx:

RPAFproxy_ips # The Nginx connecting IP address
RPAFheader X-Forwarded-For # Apache is looking for this header to use as the "client IP"