haproxy and forwarding client IP address to servers

Solution 1:

I solved this problem. May be it was not a problem from the beginning. I made google search when I faced this problem, and I saw that

option forwardfor

line in order to use in haproxy.cfg file and also other options. I tried those options including recompiling the haproxy... But the real problem related to learning real client's IPs on web servers is not sourced from HAproxy, it is about reading headers by server scripts, in our case this scripting language is PHP.

I try to learn client's IPs by these commands

echo 'Client IP: '.$_SERVER["REMOTE_ADDR"];
echo 'Client IP: '.$_SERVER["HTTP_CLIENT_IP"];

and these commands displays loadbalancer's IP. This is correct but that is not what I am expected. Despite the forwardfor option these commands, gave me loadbalancer's IP

By using forwardfor option we make enable HAproxy to insert the x-forwarded-for header into client's requests sent to our web servers. HAproxy put this field to header but I have ignored this. Today I realized that this is a header field and I have to read this header like this

echo 'Client IP: '.$_SERVER["HTTP_X_FORWARDED_FOR"];

With this command I got the client's IP address not loadbalancer's IP address.

But my offer is in order to get the header data to investigate the other information is getallheaders() function for PHP.

//from php.net http://php.net/manual/en/function.getallheaders.php
foreach (getallheaders() as $name => $value) {
    echo "$name: $value<br>\n";
}

End of all my last haproxy.cfg file is like below.

global
    maxconn 100000
    uid 99
    gid 99
    daemon

defaults
    option forwardfor except 127.0.0.1
    mode    http
    contimeout  5000
    clitimeout  50000
    srvtimeout  50000

listen  myWeb 0.0.0.0:80
    mode http
    balance source
    option forwardfor
    option http-server-close
    stats enable
    stats refresh 10s
    stats hide-version
    stats scope   .
    stats uri     /lb?stats
    stats realm   LB2\ Statistics
    stats auth admin:passwd

    server  S1 192.168.1.117:80 check inter 2000 fall 3
    server  S2 192.168.1.116:80 check inter 2000 fall 3
    server  S3 192.168.1.118:80 check inter 2000 fall 3

Nevertheless I have many missing things about HAproxy like what is the meaning uid or gid.

Solution 2:

If you need the client IP addr on the Apache log you can change your apache conf to log the X-forwarded-for in place the original source (5h)

#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

Solution 3:

Just tried @System's solution and it seems that the header name was changed from HTTP_X_FORWARDED_FOR to x-forwarded-for. Probably it's related with HAproxy version, 'cause the answer was written 5 years ago...?

As an example, this is working on production:

String requestIp = httpRequest.getHeader("x-forwarded-for");