4层透明反向代理:透传客户端真实IP
使用 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 和路由规则同上。