Show real client IP on HAProxy with backend Nginx server

Problem

I had a situation where a webserver did not see the correct client IP in the logs. The setup was like this:

Client PC <-> Internet <-> HAProxy <-> Nginx

Instead of the client IP, the IP of the HAProxy server was shown.

Testing

You can check the access logs of your Nginx server, every access attempt contains the IP of the client.

Or, you can set up a new Nginx backend using a simpel php page:

<?php
echo $_SERVER["REMOTE_ADDR"];
?>

Configure HAProxy for the test page:

frontend https
...
acl host_ip hdr(host) -i ip.test.com
...
backend ip
  redirect scheme https if !{ ssl_fc }
  server ip 192.168.100.10:80 check

Now open a browser, and navigate to ip.test.com. If you see the IP of your HAProxy server, this post is for you 🙂

Solution

The solution is to add the HTTP “X-Forwarded-For” header to all requests on HAProxy, which Nginx can understand.

On HAProxy:

defaults
        ...
        option  forwardfor

Restart haproxy:

service haproxy restart

On Nginx

Add these two lines in the config file /etc/nginx/nginx.conf:

http {
        ...
        set_real_ip_from    192.168.200.1; #IP Address of HAProxy
        real_ip_header      X-Forwarded-For;
        ...
}

Don't forget to check the syntax and restart Nginx:
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Test again

Now it’s time to test again. Navigate to ip.test.com, or whatever name you gave it. You should now see the correct client IP.

Sources:

https://access.redhat.com/solutions/3552581

https://www.loadbalancer.org/blog/nginx-and-x-forwarded-for-header/

Leave a Reply

Your email address will not be published. Required fields are marked *