负载均衡-获取真实源IP地址

获取真实源IP地址

简述

一般来说普通 http 场景,推荐使用 xff 头的方式获取IP,
如果是 tcp 或 udp,先看是否支持 proxy protocol 协议,然后再考虑 lvs。

三层获取(IP层)

方法一

如果 LB 采用一次连接模式, 即只转发包,非代理模式时, 可以在网络层不对源 IP 做修改, 直接将数据包转发给后端, 当后端接收到数据的时候, 源 IP 就是真实 IP。

实现: LVS-DR, LVS-NAT, LVS-TUNNEL 模式;

优点: 逻辑简单, 当负载均衡器故障切换的时候, 从客户端到后端的 tcp 连接不会中断

缺点: 对网络架构有要求, 例如

LVS-TUNNEL 比较特别, 走的是隧道, 在原有数据包的开头封装了 IP 头, 当后端收到数据的时候, 将封装的 IP 头进行解封装, 获得的就是原始数据包,当然包括真实的 client IP。但是要后端也支持 ip 隧道。

DR 模式, 要求后端配 VIP, 并且回包要能直接回到客户机;
NAT 模式, 要求回包经过负载均衡器;

方法二

如果 LB 采用二次连接模式, 如 haproxy 的透明模式。

是指负载均衡器和后端会重新进行三次握手, 但保持数据包的源 IP 为真实 IP,类似于 F5 的透明模式。

实现原理: haproxy(开启 tproxy 透明代理模式)+ iptables(fwmark 打标记)+ 策略路由这 3 者组合才能实现。

优点: 可以实现 L7 层(如 HTTP/HTTPS)的负载均衡, 而一次连接方式主要是实现 L4 层的负载均衡。
缺点: 配置最复杂, 同时要求回包经过负载均衡器


四层获取(TCP/IP 也就是端口这一层)

方法三

原理: 在 4 层报文的 option 字段里增加源 IP 信息, 比如 tcp option, udp option,即 L4 的 toa 模式;

注:
toa 是指在 tcp option 里增加源 IP 信息;
uoa 是指在 udp option 里增加源 IP 信息;

实现: lvs-fullnat(只支持 toa), iqiyi/dpvs(支持 toa 和 uoa);

后端应用程序也要加载 toa, uoa 模块, 是用于替换后端应用程序获取 IP 时的系统接口的钩子。

优点: 对网络架构要求低。

缺点: lvs-fullnat 需要编译内核, 且多年未更新;
iqiyi/dpvs 功能强大, 但需要 dpdk 的支持;
而且都需要后端程序需要加载 toa/uoa 模块, 且只支持 linux 系统。

方法五: proxy protocol 协议支持

原理:
即在三次握手结束后的第一个数据包的头部插入一段数据, 记录着源IP地址, 这段数据在 4 层末尾和 7 层开头之间。

这项协议最早是 haproxy 开发推广的, 目前主流 proxy 应该是都支持了;

目前有 v1(明文)和 v2(二进制)两个版本;

优点: 网络侧不需要改造什么, 只要应用软件支持即可。

限制条件:

  1. 需要负载均衡器和后端同时开启 proxy protocol 协议,不能只开一侧;
  2. 支持此协议的后端应用比较少;
    已知支持此协议的软件: haproxy, nginx, apache、traefik、squid、mysql等,
  3. 已经支持的 LB 还得看支持什么版本,如阿里云的CLB只支持V2版本,
    nginx 早期只支持 v1 版本,1.13.11+ 才支持 v2 版本。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
nginx 配置示例

插入配置
server {
    listen              12345;
    proxy_pass          backend.example.com:8080;
    proxy_protocol      on;
}

接收配置
server {
    listen 80   proxy_protocol;
    listen 443  ssl proxy_protocol;

    real_ip_header  proxy_protocol;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}

七层获取

方法六: 通信协议自带的方法

如 http 协议约定, X-FORWARD-FOR 头部用于存放源IP地址

如 nginx 一般配置

1
2
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

优点: 对网络架构要求低, 配置简便
缺点: 容易被伪造

方法七: 业务程序自行实现

即程序自行实现, 例如 client 端将源IP插入到报文正文内某字段, 再带到 server 端。

优点: 对网络架构无要求, 只要网络可通即可, 只要安全做好, 不容易被伪造
缺点: 需要改造旧的客户端和服务器

微信搜索IT运维小秋

Licensed under CC BY-NC-SA 4.0
转载或引用本文时请遵守许可协议,知会作者并注明出处
不得用于商业用途!
最后更新于 2023-02-25 00:00 UTC