haproxy 并将客户端 IP 地址转发到服务器

Sys*_*tem 18 haproxy

我有 HAproxy 的问题。

我使用 HAproxy 作为负载均衡器,它将传入的 http 请求分发到 5 个 Web 服务器。通常,客户端请求会通过负载均衡器的 IP 转发到 Web 服务器。但是我需要从 Web 服务器请求某些内容的客户端 IP 或真实 IP。因为我们需要记录真实客户端的 IP。

我尝试在 Web 服务器上获取客户端的 IP,但到目前为止我无法成功。我总是看到负载均衡器的 IP。

我使用 x-forward-for 选项,但没有解决问题。之后,我找到了另一个选项“ source 0.0.0.0:80 usesrc clientip ”,但在尝试运行 HAproxy 时出错,这是关于使用 HAproxy 的 USE_TPROXY 选项的编译需求。我做到了,我用 USE_TPROXY 选项重新编译了 HAproxy,但没有改变任何东西。我该怎么做才能了解真实客户的 IP。

我的 linux 内核版本是 2.6.32-34 我的意思是内核支持透明代理。我使用 UBUNTU 10.4 LTS

我的配置文件在这里

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
Run Code Online (Sandbox Code Playgroud)

(1)(2) 在测试 HAproxy 时,我使用了这两行之一。

有人帮我了解从我们的服务器请求的客户的真实 IP 吗?

Sys*_*tem 19

我解决了这个问题。可能从一开始就不是问题。当我遇到这个问题时,我进行了谷歌搜索,我看到了

option forwardfor
Run Code Online (Sandbox Code Playgroud)

行以便在 haproxy.cfg 文件和其他选项中使用。我尝试了包括重新编译 haproxy 在内的那些选项......但是与在 Web 服务器上学习真实客户端 IP 相关的真正问题不是来自 HAproxy,而是关于通过服务器脚本读取标头,在我们的例子中,这种脚本语言是 PHP。

我尝试通过这些命令学习客户端的 IP

echo 'Client IP: '.$_SERVER["REMOTE_ADDR"];
echo 'Client IP: '.$_SERVER["HTTP_CLIENT_IP"];
Run Code Online (Sandbox Code Playgroud)

这些命令显示负载均衡器的 IP。这是正确的,但这不是我所期望的。尽管这些命令的 forwardfor 选项,给了我负载均衡器的 IP

通过使用 forwardfor 选项,我们使 HAproxy 能够将 x-forwarded-for 标头插入发送到我们 Web 服务器的客户端请求中。HAproxy 将此字段放在标题中,但我忽略了这一点。今天我意识到这是一个标题字段,我必须像这样阅读这个标题

echo 'Client IP: '.$_SERVER["HTTP_X_FORWARDED_FOR"];
Run Code Online (Sandbox Code Playgroud)

通过这个命令,我得到了客户端的 IP 地址,而不是负载均衡器的 IP 地址。

但我的提议是为了获取头数据来调查其他信息是 PHP 的 getallheaders() 函数。

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

我最后的 haproxy.cfg 文件的结尾如下所示。

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
Run Code Online (Sandbox Code Playgroud)

尽管如此,我还是缺少很多关于 HAproxy 的东西,比如 uid 或 gid 的含义。