智汇华云-负载分布式源地址可视技术
- 时间:
- 浏览:0
摘要
非网关负载均衡器通常使用FullNat模式。在这种模式下,客户端访问后端服务器的源IP将在负载均衡器上更改,从而使后端服务器上的服务无法正确识别客户端的实际IP地址。有些应用场景需要感知客户端的真实IP,以实现安全性和大数据分析等应用。本文介绍了FullNat模式下负载均衡的源地址可视方法。
概述
负载平衡有三种模式:DR、NAT和Tunnel。FullNat模式在NAT模式下增加源IP NAT。FullNat模式的优点:解决了NAT对Director和RS以相同vlan要求的问题,不需要应用更复杂的部署形式将Director配置为网关,Director和RS可以通过三层通信进行通信。缺点:RS看不到客户端的真实IP。
为了解决后端服务器感知到客户端的真实IP,本文介绍了以下方法。
显示四层源地址
四层业务通常是TCP和UDP协议消息。显示源地址的常用方法是将客户端的实际IP发送到消息的某些字段。在后端通过内核模块获取客户端IP。
显示TCP源地址
TCP业务是TOA以实现源地址的可视化。TOA名称的全名是tcp option address,是能够在FullNat模式下使后端服务器取得客户端IP的实现方法,其基本原理比较简单。
当客户端用户请求分组到达负载均衡器时,负载均衡器将源IP信息插入分组的tcp option。
当包到达后端服务器(带有toa内核模块)时,应用程序通常调用getpeername系统函数来获取连接的源IP地址。
在toa代码中为inet_从tcp option获取负载均衡器填充的源IP信息的getname函数(getpeername系统调用相应的内核处理函数)
这将使后端服务器应用程序获得实际的客户端IP,并对应用程序透明。
TCP标头格式如下:
在option选项部分携带客户端的IP地址。
IPv4TOA格式
opcode
opsize
port
clientIP
opcode: opcode = 254
opsize:toa大小8字节
端口:客户端端口
clientIP:客户端IP(4字节)
注:opsize大小包含自opsize(2B)+port(2B)+ip(4B)
何时更改option
负载均衡器需要在每个tcp包中插入toa信息吗?这可能会影响负载均衡器的整体性能。后端服务器也不需要按tcp包解析。当然,它也会影响服务器的性能。实际上,只需将toa选项插入到第三次握手ack分组中即可,后端服务器可以从ack分组中解析并获取。
在后端服务器上获取客户端IP捕获。
TCP协议栈中处理三次握手的ack分组的函数为tcp_v4_syn_recv_sock,完成连接的建立,创建newsock。更改TOA内核模块
1.hook tcp_v4_syn_recv_sock_toa函数从TCP的skb取得tcp option携带的IP信息,保存在socket中
2. Hook inet_getname,应用程序调用getpeername时inet_getname_toa函数处理,返回从socket保存的ip信息
显示UDP源地址
UDP使用UOA实现源地址的可视化。UDP消息报头中没有option字段,通常将客户端IP运送到IP报头的option。另外UDP没有连接,没有3层握手。通常在前面的几个留言里携带信息。
显示第7层源地址
7层负载平衡通常由Nginx或Haproxy等反向代理实现。7层业务通常是HTTP,通过在HTTP报头的X-FORWARD-FOR中携带客户端的实际IP,后端服务器应用从HTTP报头的该字段取得。
X-Forwarded-For是HTTP扩展标头。HTTP/1.1(RFC2616、协议不是Squid高速缓存代理软件最初部署的定义,以表示HTTP客户端的实际IP。目前已成为事实上的标准,广泛用于各HTTP代理、负载平衡等转发服务,并写入RFC 7239(Forwarded HTTP Extension)标准。
X-Forwarded-For请求标头格式非常简单,如下所示:。
X-Forwarded-For: client, proxy1, proxy2
您可以看到,XFF的内容由多个以“英文逗号+空格”分隔的部分组成,最初是距离服务终端最远的设备IP,以及各级代理的IP。
如果在HTTP请求到达服务器之前,三个代理Proxy1、Proxy2、Proxy3和IP分别经过IP1、IP2和IP3,并且用户的实际IP为IP0,则根据XFF标准,服务端最终将接收以下信息:。
X-Forwarded-For: IP0, IP1, IP2
接着,以NGINX为例,对构成方法进行说明。
要添加到Nginx配置文件:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
$proxy_add_x_forwarded_for保存X-Forwarded-For中已经存在的值,并将$remote_addr值由逗号分隔。
如果先前的X-Forwarded-For没有值,则更改后的X-Forwarded-For将具有$remote_addr值。
例如:
A(client)mdash;gt;B(Nginx1、mdash;gt;C(Nginx2、mdash;gt;D
A是客户端,B和C是Nginx反向代理,D是服务终端
如果A访问B,X-Forwarded-For为空,$remote_由于addr是A IP,所以B被转发到C时附带的头XForwardedFor是A的IP
如果B访问了C,X-Forwarded-For是A的IP,$remote_addr是B的IP,此时C被转发到附属于D的Header报头X-Forwarded-For即A的IP、B的IP。
当C访问D时,D可以使用C送来的X-Forwarded-For磁头来分析源IP。