HCL 中文技术社区

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 939|回复: 4

使用应用负载ADC设备例如F5如何正确获取客户端的真实IP地址

[复制链接] TA的帖子

3

主题

11

帖子

95

积分

注册会员

Rank: 2

积分
95

最佳新人

发表于 2020-10-23 17:20:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
大家好,我们的domino服务器集群使用 Radware 负载均衡设备,domino看到的客户端地址都是Radware的设备业务发布的虚拟IP地址,如何获取到用户客户端真实IP地址

回复

使用道具 举报

124

主题

200

帖子

4452

积分

超级版主

Rank: 8Rank: 8

积分
4452

活跃会员热心会员灌水之王最佳新人

发表于 2020-10-24 10:49:20 | 显示全部楼层
以nginx为例,提供一个借鉴。


问题背景

在实际应用中,我们可能需要获取用户的ip地址,比如做异地登陆的判断,或者统计ip访问次数等,通常情况下我们使用request.RemoteAddr就可以获取到客户端ip,但是当我们使用了nginx作为反向代理后,使用request.RemoteAddr获取到的就一直是nginx服务器的ip的地址,那这时应该怎么办?

原理解释

经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址。

当你使用了nginx反向服务器后,在web端使用request.RemoteAddr(本质上就是获取$remote_addr),取得的是nginx的地址,即$remote_addr变量中封装的是nginx的地址,当然是没法获得用户的真实ip的,但是,nginx是可以获得用户的真实ip的,也就是说nginx使用$remote_addr变量时获得的是用户的真实ip,如果我们想要在web端获得用户的真实ip,就必须在nginx这里作一个赋值操作,如下:
proxy_set_header  X-Real_IP  $remote_addr;
其中这个X-Real_IP是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-Real_IP这个变量里了,然后,在web端可以这样获取:
request.Header.Get("X-Real_IP")

这里我们将nginx里的相关变量解释一下,通常我们会看到有这样一些配置

server {        listen       80;        server_name  localhost;        #charset koi8-r;        #access_log  logs/host.access.log  main;        location /{                root   html;                index  index.html index.htm;                proxy_pass                  http://backend;                 proxy_redirect              off;                proxy_set_header            Host $host;                proxy_set_header            X-real-ip $remote_addr;                proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;                # proxy_set_header            X-Forwarded-For $http_x_forwarded_for;        }}



1. proxy_set_header  X-Real_IP  $remote_addr;
这句话之前已经解释过,有了这句就可以在web服务器端获得用户的真实ip
但是,实际上要获得用户的真实ip,不是只有这一个方法,下面我们继续看。

2.  proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
我们先看看这里有个X-Forwarded-For变量,这是一个squid开发的,用于识别通过HTTP代理或负载平衡器原始IP一个连接到Web服务器的客户机地址的非rfc标准,如果有做X-Forwarded-For设置的话,每次经过proxy转发都会有记录,格式就是client1, proxy1, proxy2,以逗号隔开各个地址,由于他是非rfc标准,所以默认是没有的,需要强制添加,在默认情况下经过proxy转发的请求,在后端看来远程地址都是proxy端的ip 。也就是说在默认情况下我们使用request.Header.Get("X-Forwarded-For")获取不到用户的ip,如果我们想要通过这个变量获得用户的ip,我们需要自己在nginx添加如下配置:
proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
意思是增加一个$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增加,而不是覆盖,当然由于默认的X-Forwarded-For值是空的,所以我们总感觉X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,实际上当你搭建两台nginx在不同的ip上,并且都使用了这段配置,那你会发现在web服务器端通过request.Header.Get("X-Forwarded-For")获得的将会是客户端ip和第一台nginx的ip。

那么$proxy_add_x_forwarded_for又是什么?
$proxy_add_x_forwarded_for变量包含客户端请求头中的"X-Forwarded-For",与$remote_addr两部分,他们之间用逗号分开。
举个例子,有一个web应用,在它之前通过了两个nginx转发,即用户访问该web通过两台nginx。
在第一台nginx中,使用
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量的"X-Forwarded-For"部分是空的,所以只有$remote_addr,而$remote_addr的值是用户的ip,于是赋值以后,X-Forwarded-For变量的值就是用户的真实的ip地址了。

到了第二台nginx,使用
proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量,X-Forwarded-For部分包含的是用户的真实ip,$remote_addr部分的值是上一台nginx的ip地址,于是通过这个赋值以后现在的X-Forwarded-For的值就变成了“用户的真实ip,第一台nginx的ip”。

最后我们看到还有一个$http_x_forwarded_for变量,这个变量就是X-Forwarded-For,由于之前我们说了,默认的这个X-Forwarded-For是为空的,所以当我们直接使用proxy_set_header   X-Forwarded-For  $http_x_forwarded_for时会发现,web服务器端使用request.Header.Get("X-Forwarded-For")获得的值是null。如果想要通过request.Header.Get("X-Forwarded-For")获得用户ip,就必须先使用proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;这样就可以获得用户真实ip。



回复

使用道具 举报

124

主题

200

帖子

4452

积分

超级版主

Rank: 8Rank: 8

积分
4452

活跃会员热心会员灌水之王最佳新人

发表于 2020-10-24 10:50:58 | 显示全部楼层
请参考:
domino获取用户真实IP地址和用户的cookie信息根据CGI变量
https://lotusfans.cn/forum.php?m ... d=616&fromuid=5
(出处: 中国 HCL Domino 技术社区)
回复

使用道具 举报

3

主题

11

帖子

95

积分

注册会员

Rank: 2

积分
95

最佳新人

 楼主| 发表于 2020-10-25 10:59:31 来自手机 | 显示全部楼层
收到,学习了,谢谢。
回复

使用道具 举报

0

主题

2

帖子

436

积分

中级会员

Rank: 3Rank: 3

积分
436

最佳新人

发表于 2020-11-10 18:49:01 | 显示全部楼层
这个还可以看你的负载均衡设备的功能,像CITRIX NETSCALER就有这样的功能可以把客户端的IP插入的TCP的一个option的值里面。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|HCL 中文技术社区 ( 沪ICP备17044822号 )

GMT+8, 2022-6-27 21:59 , Processed in 1.043729 second(s), 28 queries .

快速回复 返回顶部 返回列表