How to Forward Original Client IP Address Through HAProxy to Backend Servers for Accurate Logging


2 views

When using HAProxy as a load balancer, backend servers typically only see the proxy's IP address instead of the original client IP. This becomes problematic when you need to:

  • Maintain accurate access logs
  • Implement IP-based security rules
  • Perform geolocation analysis
  • Track user sessions accurately

Here's the proper way to configure HAProxy to preserve client IP information:

global
    maxconn 100000
    daemon
    # Required for transparent proxy mode
    tune.ssl.default-dh-param 2048

defaults
    mode http
    option forwardfor
    option http-server-close
    timeout connect 5000
    timeout client 50000
    timeout server 50000

frontend http-in
    bind *:80
    # Add X-Forwarded-For header
    option forwardfor header X-Real-IP
    # For transparent proxy (requires TPROXY)
    source 0.0.0.0 usesrc clientip
    default_backend servers

backend servers
    balance roundrobin
    server s1 192.168.1.117:80 check
    server s2 192.168.1.116:80 check
    server s3 192.168.1.118:80 check

option forwardfor: This is the primary directive that adds the X-Forwarded-For header containing the original client IP.

usesrc clientip: When combined with TPROXY support, this attempts to spoof the source IP at the TCP level.

To check if client IPs are being properly forwarded:

curl -I http://your-haproxy-address/
# Then check your web server logs for the X-Forwarded-For header

For environments where you need the original client IP in TCP connections (not just HTTP):

# Recompile HAProxy with:
make TARGET=linux-glibc USE_LINUX_TPROXY=1
# Then use in configuration:
source 0.0.0.0 usesrc clientip

Your backend servers need to be configured to read the forwarded headers:

For Nginx:

log_format main '$http_x_real_ip - $remote_user [$time_local] '
               '"$request" $status $body_bytes_sent '
               '"$http_referer" "$http_user_agent"';

access_log /var/log/nginx/access.log main;

For Apache:

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" common
CustomLog /var/log/apache2/access.log common
  • Ensure HAProxy was compiled with TPROXY support when using 'usesrc clientip'
  • Verify kernel settings for transparent proxy: net.ipv4.ip_nonlocal_bind=1
  • Check for network devices that might strip headers (like some firewalls)
  • Confirm backend servers are configured to trust the proxy IP

When using HAProxy as a load balancer, one common challenge is maintaining visibility into the original client IP addresses. By default, backend servers only see the HAProxy instance's IP, which creates issues for:

  • Access logging and analytics
  • Geo-IP based functionality
  • Security monitoring and rate limiting
  • Personalization features

There are three primary methods to preserve client IP information:

# Method 1: X-Forwarded-For Header (Recommended for HTTP)
frontend http-in
    mode http
    option forwardfor
    default_backend webservers

backend webservers
    mode http
    server s1 192.168.1.1:80 check
    server s2 192.168.1.2:80 check

For true transparency (including non-HTTP traffic), you'll need:

# Requires Linux kernel support and TPROXY compilation
global
    tune.options.extforward

frontend main
    bind :80 transparent
    source 0.0.0.0 usesrc clientip
    default_backend apps
  1. Ensure your backend applications are configured to read X-Forwarded-For headers
  2. For Apache: LogFormat "%{X-Forwarded-For}i ..." combined
  3. For Nginx: set_real_ip_from and real_ip_header directives

If you're still seeing the load balancer IP:

# Test header forwarding
curl -v http://yourlb.example.com -H "X-Forwarded-For: 1.2.3.4"

# Verify HAProxy compilation
haproxy -vv | grep -i tproxy

# Check kernel support
sysctl net.ipv4.ip_forward
sysctl net.ipv4.conf.all.send_redirects

When implementing IP forwarding:

  • Always validate X-Forwarded-For headers to prevent spoofing
  • Configure option forwardfor if-none to preserve existing headers
  • Set proper acl rules to filter malicious traffic