使用 Haproxy、Nginx 等软件反向代理 HTTP 协议时,往往会设置 X-Forwarded-For 等头部让后端 Web server 能正确取到客户端真实 IP。如果做 4 层代理,那么就得借助 Linux 的特性 TProxy 来实现,本文讲解如何配置 Haproxy、Nginx 来实现透明代理。

Haproxy

网上很多文章都说到 Haproxy 要重新编译,编译参数加上USE_LINUX_TPROXY=1。其实这种说法已经过时了,以 RHEL 系 Linux 发行版为例,RHEL6、RHEL7、RHEL8 官方提供的 rpm 包默认就加上了这个编译参数,因此如对版本无特殊要求,使用官方提供的版本就可以了,使用 yum install haproxy 安装即可。

使用限制

  • 代理服务器与后端服务器IP地址必须在同一个网段
  • 后端服务器的默认网关要指向代理服务器的地址*

代理服务器配置

haproxy

listen 80
    bind :80
    mode tcp
    source 0.0.0.0 usesrc clientip
    server server1 server1:8080 weight 1

关键配置 source 0.0.0.0 usesrc clientip

iptables

# 收到后端服务器回来的包,打上标签1
# 这条规则还可以进一步精确匹配,如加上源地址,以免可能因匹配条件过于宽松而引起的其他问题
/sbin/iptables -t mangle -A PREROUTING -p tcp --sport 8080 -j MARK --set-mark 1

路由

# 增加一条 ip 规则,匹配打了标签1的数据包
/sbin/ip rule add fwmark 1 lookup 100
# 将匹配到的数据包路由到 lo 接口
/sbin/ip route add local 0.0.0.0/0 dev lo table 100

后端服务器配置

将默认网关指向代理服务器

常见错误

[/usr/sbin/haproxy.main()] Some configuration options require full privileges, so global.uid cannot be changed.

出现此错误是因为 haproxy 以普通用户运行,要使用 TProxy 特性,那么 haproxy 必须以 root 用户运行。改由 root 运行即可。

Nginx

使用限制

  • nginx 版本需 1.11 及更新版本

nginx

stream {
    server {
        listen 80;
        proxy_pass app_server;
        proxy_bind $remote_addr transparent;
    }
    upstream app_server{
        server server1:8080;
    }
}

关键配置 proxy_bind $remote_addr transparent;

iptables 和路由规则同上。

标签: none

添加新评论