haproxy+nginx+tproxy实现透明代理
1.tproxy的原理
内核实现的一个透明代理,该模块允许监听一个非本机ip的socket(listen阶段),并可以send到远端服务器。
1.haproxy与nginx通信
haproxy与nginx同时对proxy protocol进行了支持,所以两者之间可以透传真实的用户ip(非tcp报文直接透传)
proxy protocol代理协议的原理:
该协议的本质是在三次握手结束后由代理在连接中插入了一个携带了原始连接四元组信息的数据包。携带的数据包示例内容如下:
1 | PROXY TCP4 202.112.144.236 10.210.12.10 5678 80\r\nPROXY TCP6 2001:da8:205::100 2400:89c0:2110:1::21 6324 80\r\n |
proxy protocol的接收端必须在接收到完整有效的 proxy protocol 头部后才能开始处理连接数据。如果服务器接收到的第一个数据包不符合proxy protocol的格式,那么服务器会直接终止连接。
haproxy代理节点的示例配置如下:
1 | global |
2.nginx与后端服务通信的
nginx对proxy protocol的支持,可以从haproxy处拿到的真实用户ip,高版本(暂未确定具体版本)nginx自身就支持tproxy,因此可以通过配置,将源ip通过指令bind绑定为源ip(tproxy服务的本质就是绑定一个非本机ip),并向后端服务转发封装好的tcp包。
nginx实现代理协议支持及透明代理的示例配置如下:
1 | stream { |
此外,还需要设置tproxy相关的路由规则以正常回报给haproxy,设置命令示例如下:
1 | iptables -t mangle -A PREROUTING -p tcp -s 10.0.0.100 -m multiport --sport 3389,80 -j MARK --set-xmark 0x1/0xffffffff #将来源ip为10.0.0.100(上游服务器),且来源端口为3389或80的流量在路由前设置一个标记值1 |
4.后端(上游)服务器响应回包
在上游服务器上也须设置网关,将所有相关的响应包发送至nginx服务器
1 | iptables -t mangle -A OUTPUT -p tcp -m multiport --sport 3389,80 -j MARK --set-xmark 0x1/0xffffffff #将来源ip为10.0.0.100(上游服务器),且来源端口为3389的流量在OUTPUT链设置一个标记值1 |