HAproxy 做四层均衡负载时,如何传递真实IP给后端?
环境:CentOS 6
负载端口:80
HAproxy 服务器:10.99.115.83
后端Nginx服务器:10.99.115.84
我本机PC IP:10.100.165.28
HAProxy服务器做了80端口转发至Nginx服务器上。
此时,我访问http://10.99.115.83 , 后端服务器115.84记录来访IP为HA服务器的IP,而并非真实源IP。
基于7层HTTP均衡负载时,我知道可以用X-Forwarded-For头信息来传递真实IP。
可是基于四层均衡负载(tcp/ip)协议时,请问如何能让HAproxy传递真实IP给后端机器呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
如果你的后端应用能支持PROXY protocol的话,可能会好办很多。
例如我这个透传https流量的方法,后端可以通过代理协议获取访客真实IP。
这个需求在TCP层实现不了的。
原因很简单:
实际客户端 ---> ha_proxy -----> 你的服务器
如果你的服务器看到的是实际客户端的ip,回应响应时会直接把TCP报文发给实际客户端,那ha-proxy上面的TCP连接怎么办呢?
但是通过网络组网,也会有一个办法:
你的ha-proxy所在的机器必须是你的实际应用服务器的网关,这样在ha-proxy上面通过iptables做snat,是有可能实现的要求的。
我用的是HAProxy的四层tcp负载啊
要知道TCP层本质上就是左耳和右耳的性质,从左耳(客户端)来的所有字节原封不动的发给右耳(服务器),同理也是从服务器发给客户端。
要命的是,因为TCP字节流的关系,所有从左耳发给右耳的东西都是对方服务器需要的东西,一个字节都不能更改。
-----------------细细思考一下,真的没有办法解决了?
我认为可行的一个解决方案如下:
修改haproxy的源码,将haproxy发给服务器的那部分内容做如下修改。
假设原先的内容为A.
封装成
[Length,性质,内容】
其中length占固定长度的字节,性质定义0自定义内容,此时内容部分就是任何你可以插入的信息,1 客户端发来的原内容A。
然后你的服务器那边解析自定义内容就可以获得客户端的IP和端口以及任何你想要的信息。
---
这里要做一个控制,就是每次发送内容给服务器时,判断之前是否已经发过了
可以在session里增加一个字段,每次查看,如果已经发过了,就不要再发了
这样保证每个session只会发送一次客户端的IP和端口给你的服务器。
---主要就是要修改源码,增加了一些自定义解析规则。
不过可以解决你的问题。
===注意要考虑到session的clientfd,serverfd以及两边的IP和端口是否发生改变。
HAProxy是七层负载啊
是的,我郁闷的就是这里。 我专门tail -f nginx.log 显示的IP全部是HA服务器的IP
回复
嗯嗯,测试了下,确实都是ha的ip。
经过haproxy转到到nginx上,nginx日志上看的源ip不是客户ip吗?奇怪,
能否请教兄弟用iptables如何实现? 服务器A,双网卡,外网IP 2.2.2.2 , 内网IP 10.99.115.83 内网服务器B,单网卡,内网IP:10.99.115.84 我想实现:访问 2.2.2.2:80 转发到 10.99.115.84:80 上。 请教兄弟,这个规则如何写?
回复
1: 开启net.ipv4.ip_forward; 2: iptables -t nat -A PREROUTING -i eth0 -d 2.2.2.2 -p tcp --dport 80 -j DNAT --to-destination 10.99.115.84:80 这样不知道可以不,
不能,这个是LVS或者防火墙实现的