使用阿里云负载均衡时获取客户端真实IP的方法

本文涉及的产品
Web应用防火墙 3.0,每月20元额度 3个月
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 使用阿里云负载均衡时获取客户端真实IP的方法

很多用户朋友在使用阿里云负载均衡时,都有获取客户端真实IP的需求,并且还要求可以防止X-Forwarded-For伪造,这里笔者在这里向大家提供三种获取客户端真实IP的方法,其中第三种方法还可以防止X-Forwarded-For伪造。


实验环境说明:


  1. 本文均是基于 客户端 --> 负载均衡SLB --> ECS 这种网络架构测试。


  1. 本文提及到的域名 aliyunslb.osmonitor.cn 是解析到阿里云负载均衡SLB的IP上。


  1. 本文提及到的ECS安装的Web软件是Nginx。


  1. 本文提及到的主机名 beijing-ecs-1 是Web服务器(Nginx Server),主机名 aliyun 是客户端。



基础知识讲解


当用户访问网站时,大多数情况下并不是直接访问到Web服务器端的。而是客户端请求先到中间代理,再由代理转发给真实的Web服务器,这样就导致Web服务器端拿到的客户端IP会是中间代理设备的IP,而不是真实的客户端IP。


remote_addr


remote_addr指的是和Web服务器建立TCP连接的客户端IP。当我们的浏览器访问某个网站时,假设中间没有任何代理,那么就可以把remote_addr当为客户端IP;如果中间使用了某些代理(比如CDN、WAF、SLB等),那么我们的浏览器会先访问到代理,然后再由代理层层转发到真正的Web服务器,这时Web服务器拿到的remote_addr实际是上级代理设备的IP。也就是说,remote_addr其实代表的是和Web服务器"直连"(进行TCP三次握手)的客户端IP。


X-Forwarded-For


如前面所述,当我们的Web服务器前端部署有CDN、WAF、SLB等代理产品时,Web服务器就不知道真实的客户端IP了。为了避免这种情况,中间的代理服务器通常会在HTTP Request Header中增加一个叫做X-Forwarded-For的扩展头信息,X-Forwarded-For简称XFF头,其格式规定如下:

X-Forwarded-For: client, proxy1, proxy2

从上可以看出,X-Forwarded-For头信息可以有多个参数值,每个参数值之间用"英文逗号+空格"进行分隔,左边第一个参数值为真实的客户端IP,后边的就是曾经依次经过的代理设备的IP地址。


举个例子,某个客户端在访问到Web服务器之前,依次经过了3个代理产品,分别是CDN、WAF、SLB,这些代理产品的IP分别为IP1-CDN、IP2-WAF、IP3-SLB,用户真实IP为IP0,那么Web服务端最终会收到以下信息:

X-Forwarded-For: IP0, IP1, IP2

SLB直连Web服务器,它会在XFF头中追加IP2,表示它是在帮WAF转发请求。XFF头的值中并没有IP3,IP3可以在Web服务器上通过 $remote_addr 字段获得。


获取客户端真实IP的三种方法


第1种:传统获取法


传统获取法是指直接通过X-Forwarded-For扩展头获取客户端真实IP。

阿里云的负载均衡IP地址段是100.64.0.0/10,对应的主机地址范围是 100.64.0.1  - 100.127.255.254。

Nginx服务端配置如下图所示:



客户端发起访问:


Nginx服务端查看日志进行验证:


第2种:排除获取法


排除获取法是指通过http_realip_module模块解析X-Forwarded-For记录从而获得客户端真实IP。这是笔者自己起的方法名字,主要是为了方便理解和记忆。

阿里云官方文档对此方法亦有介绍,可以点此直接查看详情。

默认情况下,通过yum直接安装的Nginx,是已经集成有http_realip_module模块的,我们无需再手动编译添加该模块。


Nginx服务端配置如下图所示:

指令

说明

set_real_ip_from

指定前端代理产品的IP地址段。

如果前端有多层代理(例如客户端--CDN--WAF-SLB-ECS),那么要多次使用该指令,把前端所有代理产品(CDN、WAF、SLB)的IP地址段都写进来,不能只写一个代理的。

由于本文实验环境是:客户端--SLB--ECS,对于ECS中的Nginx来说,前端代理就是SLB,而SLB的IP地址段是 100.64.0.0/10,因此这个指令的值就需要填写为SLB的地址段 100.64.0.0/10 ,参见下方示例截图。

real_ip_header

表示让Nginx从SLB哪个Header头中提取真实IP。

real_ip_recursive

是否排除IP地址,这也是笔者定义为排除获取法名称的由来。

如果该指令的值设置为on,那么表示从右至左逐个检索并排除set_real_ip_from里面指定的IP,如果出现了不属于set_real_ip_from指令中的IP,那么这个IP将被认为是用户的真实IP,并被赋值给remote_addr变量。此时在日志中打印$remote_addr变量,就会看到客户端的真实IP地址。

客户端发起访问:


Nginx服务端查看日志进行验证:


第3种:另辟蹊径法


这也是笔者自己起的方法名字,主要是为了方便理解和记忆。


众所周知,和服务器直接建立TCP连接的客户端IP必定是客户端真实IP,必定是无法伪造的。目前很多云产品都会新增一个自定义Header头,把remote_addr(也就是和其直接建立TCP连接的客户端IP)的值赋给该字段,然后转发给后端服务器,那么后端应用只需要提取自定义Header头的值即可得到客户端的真实IP。


即使客户端知道了我们云产品新增的Header头,刻意去伪造该字段,也是行不通的。因为云产品无论如何都会强制把建立TCP连接的客户端IP赋给新增的这个Header头,通过这种方法去避免客户端伪造X-Forwarded-For头而导致后端应用无法通过X-Forwarded-For获取到客户端真实IP的情况发生。


例如,阿里云CDN在接收到客户端请求时,会新增一个名为Ali-CDN-Real-IP的Header头,CDN会把客户端的真实IP强制赋值给Ali-CDN-Real-IP字段,然后CDN回源时会带着这个新增的Header头。


再例如,阿里云SLB在接收到客户端请求时,会新增一个名为RemoteIp的Header头,SLB会把客户端的真实IP强制赋值给RemoteIp字段,然后SLB转发客户端请求给后端ECS时,也会带着新增的Header头。


在ECS中抓包可以看到SLB的请求Header头如下:


Nginx服务端配置如下图所示:


客户端发起访问:


Nginx服务端查看日志进行验证:


伪造X-Forwarded-For

客户端发起访问:

curl -I -X GET http://aliyunslb.osmonitor.cn -H "RemoteIp: 1.1.1.1" -H "X-Forwarded-For: 2.2.2.2"


Nginx服务端查看日志进行验证:


在ECS中抓包:


最后说明


通过对比以上3种方法,我们可以发现:


  1. 第1种方法是借助X-Forwarded-For头来获取到客户端真实IP,配置简单,但存在X-Forwarded-For伪造的缺点。


  1. 第2种方法也是借助X-Forwarded-For头来获取到客户端真实IP,配置复杂,需要把前端所有的代理产品的IP段全部写进去进行逐一排除,配置复杂,并且有的代理产品回源IP段不固定,实现起来也不容易。同时也存在X-Forwarded-For伪造的缺点。


  1. 第3种方法不借助X-Forwarded-For头,而是直接提取代理产品所插入的自定义Header头的值,来获取客户端真实IP,配置简单,也避免了X-Forwarded-For伪造的情况。
相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
23天前
|
弹性计算 负载均衡 网络协议
slb健康检查方法
slb健康检查方法
37 4
|
16天前
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
44 3
|
26天前
|
负载均衡 监控 网络协议
slb健康检查路径与方法
slb健康检查路径与方法
40 4
|
27天前
|
弹性计算 网络协议
slb健康检查方法
slb健康检查方法
31 4
|
1月前
|
弹性计算 运维 负载均衡
阿里云SLB的性能优势
【11月更文挑战第3天】
43 3
|
1月前
|
负载均衡 算法 网络协议
阿里云slb中的lvs介绍
【10月更文挑战第17天】
104 2
|
1月前
|
弹性计算 负载均衡 监控
阿里云slb的slb-backend介绍
【10月更文挑战第17天】
79 2
|
1月前
|
弹性计算 负载均衡 监控
阿里云slb的slb-api介绍
【10月更文挑战第17天】
95 1
|
2月前
|
弹性计算 负载均衡 算法
负载均衡如何帮助阿里云国际服务器搭建的网站或应用程序?
负载均衡如何帮助阿里云国际服务器搭建的网站或应用程序?
|
2月前
|
负载均衡 Kubernetes 区块链
随机密码生成器+阿里k8s负载均衡型服务加证书方法+移动终端设计+ico生成器等
随机密码生成器+阿里k8s负载均衡型服务加证书方法+移动终端设计+ico生成器等
56 1