18

I have a problem with HAproxy.

I use HAproxy as load balancer which distribute incoming http requests to 5 web servers. normally a client request's is forwarded to web servers with loadbalancer's IP. But I need clients IPs or real IPs who request something from web servers. Because we need to log the real client's IPs.

I try to obtain client's IPs on web servers but I can not success up to now. Always I see the load balancer's IP.

I use x-forward-for option but it is not solved the problem. After that I found another option "source 0.0.0.0:80 usesrc clientip" but I got eror while trying to run HAproxy which is about compilation needs with USE_TPROXY option of the HAproxy. I did it, I recompile HAproxy with USE_TPROXY option but does not change anything. what can I do in order to learn real client's IPs.

My linux kernel version is 2.6.32-34 I mean that kernel is support transparent proxy. and I use UBUNTU 10.4 LTS

my config file is here

global
    maxconn 100000
    uid 99
    gid 99
    daemon

defaults
    option forwardfor except 127.0.0.1
    mode    http
    (1)source 0.0.0.0:80 interface hdr_ip(x-forwarded-for,-1)
        (2)source 0.0.0.0:80 usesrc clientip
    contimeout  5000
    clitimeout  50000
    srvtimeout  50000

listen  myWeb 0.0.0.0:80
    mode http
    balance source
    option forwardfor header X-Client
    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:xXx

    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

(1)(2) While testing HAproxy I used one of these two lines.

Is somebody help me to learn real IP's of the clients who being request from our servers?

System
  • 507
  • 1
  • 3
  • 7
  • What you're looking for is called a 'transparent proxy'. iptables is involved somehow, but I'm not sure exactly how. – sysadmin1138 Nov 15 '11 at 12:41
  • by saying transparent proxy I mention that, the proxies which is not modify the http headers while distribute the incoming connections. thus real web page requester client's IP can be sent to the web server. That is the what I understood from transparent proxy. – System Nov 17 '11 at 10:10

3 Answers3

21

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.

System
  • 507
  • 1
  • 3
  • 7
3

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
  • Thanks for your answer Marcelo, but we do not need client's IP address on Apache log. we try to learn by our php scripts. – System Nov 17 '11 at 10:14
1

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");

Roc Boronat
  • 111
  • 3