背景信息
在某些场景下,负载均衡使用FullNat模式,客户端通过负载均衡访问服务器,对源地址和目的地址分别进行转换。客户端源地址clientip转换为负载均衡的地址sip,客户端访问的目的地址lbip转换为服务器的地址serverip。所以后端服务器得到的请求源地址是负载均衡的地址。故需要通过技术手段来实现服务端获取客户端真实IP,以获取业务访问的真实来源。
七层负载均衡获取客户端真实源IP地址
七层负载均衡HTTP或HTTPS协议服务,通过配置七层负载均衡服务器,使用X-Forwarded-For方式获取客户端的真实源IP地址。真实的客户端源IP存放在HTTP头部的X-Forwarded-For字段,格式如下:
X-Forwarded-For:用户真实IP,代理服务器1IP,代理服务器2IP,
常见的服务应用,如nginx可以从http头部x-forwarded-for获取真实的源地址
四层负载均衡获取客户端真实源IP地址
- 通过toa模块获取源地址
负载均衡通过tcp option(toa)携带客户端地址,发送到服务器,toa选项的格式如下:
服务器通过Toa内核模块,获取toa选项中的真实clientip。
Toa内核模块的实现原理如下:
Toa内核模块Hook内核的两个方法tcp_v4_sync_recv_sock_toa和inet_getname_toa,将toa选项中的源地址和端口存放到sock结构体的sk_user_data指针中,
inet_getname_toa被应用层getpeername调用,如果sk_user_data不为空时,从中取出源地址和端口。TOA选项8字节,刚好利用sock结构体sk_user_data指针。TOA 内核模块对应用程序透明,应用程序不需要做修改,从getpeername中获取真实源地址。
- 通过proxy protocol获取真实源地址
Proxy Protocol是一个标准的TCP源地址传递方案。负载均衡在与后端服务器建立 TCP 连接后,在发送实际应用数据之前,首先发送一个Proxy Protocol协议头(包括客户端源IP/端口、LBIP/端口等信息)。这样,后端 server 通过解析协议头获取真实的客户端源 IP 地址。
当前常见的应用服务,nginx,haproxy等都支持proxy protocol协议。