应用场景
在基于TCP、UDP的应用程序中,获取客户端真实源IP地址可以用于以下应用场景:
- 访问控制和安全策略:通过获取客户端真实源IP地址,应用程序可以实施访问控制策略,限制或允许特定IP地址的访问。这可以用于身份验证、防止未经授权访问、限制特定地理区域的访问等。例如,防火墙可以根据客户端IP地址来决定是否允许连接或阻止连接。
- 防止滥用、攻击和入侵检测:获取客户端真实源IP地址可以用于防止滥用和攻击行为。通过分析IP地址,可以实施阻止流量来自恶意IP地址的策略,如IP黑名单、限制恶意用户的连接速率或引入入侵检测系统。这有助于提高应用程序的安全性,并保护系统免受恶意活动的危害。
- 统计和分析:获取客户端真实源IP地址可以用于统计和分析访问模式和用户行为。通过分析IP地址,可以了解用户的地理位置、访问频率、使用设备和浏览器等信息。这些数据可以用于优化用户体验、定位目标受众、改进应用程序设计和定制内容。
- 安全审计和合规要求:获取客户端真实源IP地址有助于安全审计和合规要求的满足。通过记录和跟踪源IP地址,可以提供追溯用户行为的能力,以满足法规和合规性要求。这对于监测和报告滥用行为、保护用户隐私和满足法律要求非常重要。
方式选择建议
| 特性 | 客户端地址保持(源地址透传)(推荐使用) | TOA插件 | Proxy Protocol |
|---|---|---|---|
| 适用协议 | TCP、UDP | TCP | TCP |
| 实现原理 | 负载均衡器做DNAT转换(源地址透传)负载均衡器不修改数据包的原地址,直接将客户端的源IP作为数据包的源IP转发给后端服务器。 | 负载均衡器做FullNAT转换负载均衡器将客户端的IP和端口编码进TCP报文的协议选项字段中,后端需加载专用内核模块来解析。 | 负载均衡器做FullNAT转换负载均衡器在数据流的最前面插入一个包含客户端IP信息的独立协议头,后端应用需解析这个协议头。 |
| 后端主机改动 | 对应用通常透明,后端主机的安全组需要放通客户端原地址 | 内核级:需加载toa.ko内核模块,应用可能需要通过getsockopt()调用获取IP | 应用级:需在业务软件(如Nginx)中配置解析Proxy Protocol协议。 |
| 适用资源池 | 可用区类型资源池的性能保障性负载均衡 | 可用区类型资源池的性能保障性负载均衡 | 可用区类型、地域资源池的性能保障性负载均衡 |
不同资源池支持的方式请以控制台展示的功能为准。
方式一:客户端地址保持(源地址透传)模式(推荐使用)
工作原理
弹性负载均衡有两种转发模式。
在开启“客户端地址保持”功能开关时,负载均衡器将流量转发至后端主机时做DNAT转换,将客户端请求的源IP不做替换、源地址透传到后端主机,目的地址替换为后端主机IP。
在不开启“客户端地址保持”功能开关时,负载均衡器将流量转发至后端主机时做FullNAT转换,将客户端请求的源IP替换为100.89.0.0/16(IPv4流量)或100:0:0:2::/64(IPv6流量)地址段IP,目的地址替换为后端主机IP。
正常情况下,在创建或者修改TCP、UDP监听器时,将“客户端地址保持”功能开关设置为开启,此时在后端主机上获取的源IP即为客户端真实IP地址。
说明(1)NAT64场景下、四层监听器不支持开启”客户端地址保持“,只可以通过TOA或ProxyProtocol支持;如需开启,请关闭NAT64开关。
(2)该开关对于以下类型后端不生效(即以下类型后端无法使用“客户端地址保持”获取到客户端的源ip;如需获取到客户端源ip可使用TOA模块):
物理机
跨VPC后端IP
弹性网卡/辅助IP或弹性容器ECI —— 若该网卡或容器由物理机承载,则该开关同样不生效
DPU类型云主机(会存在访问异常的情况)
操作步骤
1.创建或者修改TCP、UDP监听器时打开“客户端地址保持”功能开关
2.在后端主机获取到的源IP即为客户端真实IP。
方式二:TOA模式获取客户端的真实源IP地址
工作原理
天翼云资源池,针对四层的TCP请求(TCP监听器),在后端主机内配置TOA插件获取客户端的真实源IP地址,TOA模式不支持UDP请求获取真实源IP。
TOA模式是一种在四层负载均衡(FullNAT模式)场景下,向后端主机透传客户端真实源IP的技术方案,核心原理如下:
信息携带:负载均衡器在将请求转发给后端主机时,将客户端的真实IP和端口信息编码,插入到TCP协议头部的自定义选项(Option)字段中。
透明传递:此操作对业务应用透明,仅在TCP三次握手阶段完成,不影响后续数据传输。
内核解析:后端主机需加载专用的TOA内核模块。该模块负责从TCP报文的选项字段中解析出客户端IP,并将其与当前连接关联。
应用获取:业务应用通过标准的网络接口即可获取到真实的客户端IP,无需修改业务代码。
说明TOA是操作系统的内核模块,需要在ELB后端主机中安装TOA插件,以实现后端主机可获取客户端真实源IP地址的目的。
操作步骤
- 准备编译环境
a. 针对Linux内核版本为3.0以上的操作系统。以Centos环境为例。
b. 安装gcc编译器,执行以下命令:
sudo yum install gcc
c. 安装make工具,执行以下命令:
sudo yum install make
d. 安装内核模块开发包,执行以下命令:
sudo yum install kernel-devel-`uname -r`
e. 注意开发包的版本需要与内核版本一致,假如自带源里没有对应的内核开发包,可以到以下链接地址进行下载,地址如下:
https://mirror.netcologne.de/oracle-linux-repos/ol7_latest/getPackage/
以3.10.0-1160.80.1.0.1.el7.x86_64为例,下载后执行以下命令安装:
rpm -ivh kernel-devel-3.10.0-1160.80.1.0.1.el7.x86_64.rpm
f. 以下步骤是以Ubuntu、Debian环境为例,进行编译环境准备。
g. 安装gcc编译器,执行以下命令:
sudo apt-get install gcc
h. 安装make工具,执行以下命令:
sudo apt-get install make
i. 安装内核模块开发包,执行以下命令:
sudo apt-get install linux-headers-`uname -r `
- 编译内核模块
a. 下载TOA内核模块源代码,点击进入常见TOA下载页面 (获取验证码:t7nv)进行下载。
b. 编译模块。执行以下命令:
cd src
make
c. 编译过程若未提示warning或者error,说明编译成功,检查当前目录下是否已经生成toa.ko文件。
- 加载内核模块
a. 加载内核模块,执行以下命令:
sudo insmod toa.ko
b. 验证模块加载情况及内核输出信息,执行以下命令:
dmesg | grep TOA
假如提示信息中包含“TOA: toa loaded”,则证明内核模块已经加载成功。
说明当CoreOS在容器中编译完内核模块后,需要将内核模块复制到宿主系统,最后在宿主系统中加载内核模块。另外由于编译内核模块的容器和宿主系统共享/lib/modules目录,可以在容器中将内核模块复制到该目录下,以供宿主系统使用
- 自动加载内核模块
a. 把加载TOA内核模块的命令加到您的启动脚本中,能够保证TOA内核模块在系统启动时生效。
b. 在自定义的启动脚本中添加加载TOA内核模块的命令。具体步骤可参考以下操作:
c. 在“/etc/sysconfig/modules/”目录下新建toa.modules文件。该文件包含了TOA内核模块的加载脚本。toa.modules文件内容,请参考如下示例:
#!/bin/sh
/sbin/modinfo -F filename /root/toa/toa.ko > /dev/null 2>&1
if [ $? -eq 0 ]; then
/sbin/insmod /root/toa/toa.ko
fi
d. “/root/toa/toa.ko”为TOA内核模块文件的路径,您需要将其替换为自己编译的TOA内核模块路径。
e. 为toa.modules启动脚本添加可执行权限,执行以下命令:
sudo chmod +x /etc/sysconfig/modules/toa.modules
- 安装多节点
假如要在相同的操作系统中加载此内核模块,可以将toa.ko文件拷贝到您的虚拟机中,参照以上加载内核模块的步骤,内核模块加载成功以后,应用程序可以正常获取访问者的真实源IP地址。
- 验证TOA内核模块
a. TOA内核模块安装成功后即可直接获取到源地址,在安装有python的后端服务器中启动一个HTTP服务,执行如下命令:
python -m SimpleHTTPServer port
b. 其中,port需要与ELB添加该后端服务器时配置的端口一致,默认为80。启动之后,通过客户端访问ELB的IP时,服务端的访问日志如下:
192.168.1.10 - - [08/Sep/2022 15:21:21] "GET / HTTP/1.1" 200 –
方式三:Proxy Protocol模式获取客户端的真实源IP地址
工作原理
Proxy Protocol是一种通信协议,用于在代理服务器(负载均衡器)和后端主机之间传递客户端的原始网络连接信息。
通常情况下,负载均衡器在转发客户端请求到后端主机时会重写请求头部,将客户端的源IP地址和端口等信息替换为负载均衡器自身的信息。这样后端主机就无法获得客户端的真实网络连接信息。
而使用Proxy Protocol,负载均衡器在转发请求时将客户端的原始网络连接信息封装在请求头部中,发送给后端主机。后端主机通过解析Proxy Protocol头部,就可以获得客户端的真实网络连接信息,包括源IP地址、源端口以及传输协议等。
在控制台ELB后端主机组页面打开“获取客户端真实源IP”开关,在后端主机并开启Proxy Protocol后获取到客户端真实源IP。Proxy Protocol为v1版本,支持TCP监听器、不支持UDP监听器。
说明“Proxy Protocol模式”需要代理服务器和后端主机都支持该协议才能正常使用。如果后端主机不具备解析Proxy Protocol协议的能力,打开特性开关可能会导致后端服务解析异常,从而影响服务可用性。
“Proxy Protocol模式”不支持平滑开启,切换到ProxyProtocol需要业务停服升级,请谨慎配置。
Proxy Protocol是V1版本、不支持UDP监听获取客户端真实源IP。
操作步骤
-
在后端主机组上打开如下开关。
-
在后端主机内开启Proxy Protocol。修改/etc/nginx/nginx.conf文件内容如下(以nginx为例演示,用户可按照后端主机真实应用情况决定如何获取客户端源IP)。
http { # 确认已设置$proxy_protocol_addr log_format main '$proxy_protocol_addr - $remote_addr- $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 以888监听端口为例,增加proxy_protocol字段 server { listen 888 proxy_protocol; #... } } 字段含义如下: $proxy_protocol_addr:真实客户端IP。 $remote_addr:负载均衡器使用的转发地址100.89.0.0/16。如果负载均衡开启了VPC内地址转发,则为对应的后端子网。 -
在后端主机的Nginx日志可以看到已获取到客户端源IP。