共计 1930 个字符,预计需要花费 5 分钟才能阅读完成。
除了 X -FORWARD-FOR,负载均衡中获得真实源 IP 的方法还有很多种。
本文抛砖引玉,主要介绍获得真实源 IP 的多种方法,而不是具体配置。
负载均衡获得真实 IP 的方法有很多种,将形成专题文章。
本文为第一篇,主要做介绍和优劣对比。
小慢哥的原创文章,欢迎转载
获得真实 IP 的 6 种方法
当数据包从负载均衡器往后端转发时候,真实源 IP 可在 L3、L4、L7 实现,并且分别有 2 种方法可以获得真实 IP,因此共有 6 种方法:
保持 L3 层源 IP 不变,根据连接次数可以分为
- 一次连接模式,如 lvs
- 二次连接模式,如 haproxy 的透明模式
在 L4 层数据里,添加源 IP 信息,有 2 种模式
- 在 4 层的 option 字段里增加源 IP 信息,比如 tcp option、udp option
- 在 4 层末尾和 7 层开头之间,增加 proxy protocol 信息
在 L7 层数据里,增加源 IP 信息,有 2 种模式
- 协议自带,例如 HTTP 的 X -FORWARD-FOR
- 业务程序自行实现
一次连接与二次连接
一次连接:负载均衡器对数据包仅做转发,而不对后端重新发起三次握手
二次连接:和一次连接相对应,在 tcp 转发时候,对后端重新进行了三次握手。上面所讲的 L4 和 L7 方法的负载均衡,都是二次连接
可以通过对比源端口是否有改变来简单判断是一次连接还是二次连接,端口没改变,可以理解为一次连接,有改变就是二次连接
方法 1: L3 的一次连接模式
介绍:是指在网络层不对源 IP 做修改,直接将数据包转发给后端,当后端接收到数据的时候,源 IP 就是真实 IP。
实现:LVS-DR、LVS-NAT、LVS-TUNNEL 模式。其中 LVS-TUNNEL 比较特别,是在原有数据包的开头封装了 IP 头,当后端收到数据的时候,将封装的 IP 头进行解封装,获得的就是原有数据包。
优点:逻辑简单,当负载均衡器故障切换的时候,从客户端到后端的 tcp 连接不会中断
缺点:对网络架构有要求,比如 DR 模式,要求后端配 VIP,并且回包要能直接回到客户机;NAT 模式,要求回包经过负载均衡器;TUNNEL 模式要求后端支持 IPIP 隧道
方法 2: L3 的二次连接模式
介绍:是指负载均衡器和后端重新进行三次握手,但保持数据包的源 IP 为真实 IP。
实现:haproxy(开启 tproxy 透明代理模式)+ iptables(fwmark 打标记)+ 策略路由这 3 者组合才能实现
优点:可以实现 L7 层(如 HTTP/HTTPS)的负载均衡,而一次连接主要实现 L4 层的负载均衡
缺点:配置最复杂,同时要求回包经过负载均衡器
方法 3: L4 的 toa 模式
介绍:在 4 层的 option 字段里增加源 IP 信息,比如在 tcp option 里增加源 IP 信息(称为 toa)、udp option 里增加源 IP 信息(称为 uoa)
实现:负载均衡器配置 lvs-fullnat(只支持 toa),iqiyi/dpvs(支持 toa 和 uoa);后端要加载 toa、uoa 模块,这个模块的作用是替换了后端应用程序获取 IP 的系统接口的钩子
优点:对网络架构要求低
缺点:lvs-fullnat 需要编译内核,且只支持 rhel/CentOS 6 的内核,另外多年未更新;iqiyi/dpvs 功能强大,但需要 dpdk 的支持;后端都需要加载 toa/uoa 模块,且只支持 linux 系统。
方法 4: L4 的 proxy protocol 模式
介绍:在 L7 层开头增加 proxy protocol 数据(该协议是 haproxy 发明),目前有 v1(明文)和 v2(二进制)版本
实现:负载均衡器和后端同时开启 proxy protocol,haproxy 和 nginx 均支持,不过 haproxy 的配置颗粒度更小,另外 nginx 转发数据时候只支持 v1
优点:对网络架构要求低,只要程序支持即可,因此理论上没有操作系统限制
缺点:目前支持 proxy protocol 的程序较少,且两端只能都开启或者都不开启该协议,不能一端开一端不开
方法 5: L7 协议自带,例如 HTTP 的 X -FORWARD-FOR
介绍:最常见的方法,协议自带源 IP 信息,或者可定制插入
实现:例如 HTTP 协议有 X -FORWARD-FOR,也可以自己将源 IP 插入到 HTTP 头部信息里
优点:对网络架构要求低,配置简便
缺点:容易被伪造
方法 6: L7 层业务程序自行实现
介绍:最好的方法,就是业务方自行实现
实现:业务自行实现,例如在 client 端插入源 IP 信息,带到 server 端
优点:对网络架构无要求,只要网络可通即可,只要安全做好,不容易被伪造
缺点:业务方要有一定开发能力
总结
如果能做到无状态,不需要真实源 IP,是最好的。因为这样对底层架构没有要求,底层架构就可以做的更高级更弹性。
如果一定要获得真实源 IP,推荐方案的顺序就是倒推,从 L7 到 L3,即首选方法 6,如果不行再选用方法 5,以此类推到方法 1