Nginx 获取客户端真实IP $remote_addr与X-Forwarded-For
nginx配置
首先,一个请求肯定是可以分为请求头和请求体的,而我们客户端的IP地址信息一般都是存储在请求头里的。如果你的服务器有用Nginx做负载均衡的话,你需要在你的location里面配置X-Real-IP
和X-Forwarded-For
请求头:
location ^~ /your-service/ {proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://localhost:60000/your-service/;}
X-Real-IP
在《实战nginx》中,有这么一句话:
经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址。
这句话的意思是说,当你使用了nginx反向服务器后,在web端使用request.getRemoteAddr()
(本质上就是获取$remote_addr
),取得的是nginx的地址,即$remote_addr
变量中封装的是nginx的地址,当然是没法获得用户的真实ip的。但是,nginx是可以获得用户的真实ip的,也就是说nginx使用$remote_addr
变量时获得的是用户的真实ip,如果我们想要在web端获得用户的真实ip,就必须在nginx里作一个赋值操作,即我在上面的配置:
proxy_set_header X-Real-IP $remote_addr;
$remote_addr 只能获取到与服务器本身直连的上层请求ip,所以设置$remote_addr一般都是设置第一个代理上面;但是问题是,有时候是通过cdn访问过来的,那么后面web服务器获取到的,永远都是cdn 的ip 而非真是用户ip,那么这个时候就要用到X-Forwarded-For 了,这个变量的意思,其实就像是链路反追踪,从客户的真实ip为起点,穿过多层级的proxy ,最终到达web 服务器,都会记录下来,所以在获取用户真实ip的时候,一般就可以设置成,proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这样就能获取所有的代理ip 客户ip。
X-Forwarded-For
X-Forwarded-For
变量,这是一个squid开发的,用于识别通过HTTP代理或负载平衡器原始IP一个连接到Web服务器的客户机地址的非rfc标准,如果有做X-Forwarded-For
设置的话,每次经过proxy转发都会有记录,格式就是client1,proxy1,proxy2
以逗号隔开各个地址,由于它是非rfc标准,所以默认是没有的,需要强制添加。在默认情况下经过proxy转发的请求,在后端看来远程地址都是proxy端的ip 。也就是说在默认情况下我们使用request.getAttribute("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.getAttribute("X-Forwarded-For")
获得的将会是客户端ip和第一台nginx的ip。
那么$proxy_add_x_forwarded_for
又是什么?
$proxy_add_x_forwarded_for
变量包含客户端请求头中的X-Forwarded-For
与$remote_addr
两部分,他们之间用逗号分开。
举个例子,有一个web应用,在它之前通过了两个nginx转发,www.linuxidc.com
即用户访问该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”,这样就清楚了吧。
举个例子说明 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192.168.179.99->192.168.179.100->192.168.179.101->192.168.179.102(102为最后的服务端)192.168.179.99配置location /{proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://192.168.179.100;}192.168.179.100配置location /{proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://192.168.179.101;}192.168.179.101配置location /{proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://192.168.179.102;}192.168.179.102配置
在日志中设置打印$http_x_forwarded_for,进行观察log_format main '$http_x_forwarded_for|$http_x_real_ip|$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
(1)客户端使用浏览器去访问192.168.179.99服务端192.168.179.102日志如下,可以看到获取到客户端的IP为192.168.179.4
192.168.179.4, 192.168.179.99, 192.168.179.100|-|192.168.179.101 - - [26/Apr/2020:10:57:22 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36" "192.168.179.4, 192.168.179.99, 192.168.179.100"(2)客户端192.168.179.103去访问192.168.179.99服务端192.168.179.102日志如下,可以看到获取到客户端的IP为192.168.179.103
192.168.179.103, 192.168.179.99, 192.168.179.100|-|192.168.179.101 - - [26/Apr/2020:10:57:32 +0800] "GET / HTTP/1.0" 200 4833 "-" "curl/7.29.0" "192.168.179.103, 192.168.179.99, 192.168.179.100"
Nginx 获取客户端真实IP $remote_addr与X-Forwarded-For相关推荐
- Nginx获取客户端真实ip
三.如何在使用代理后获取用户ip 在<实战nginx>中,有这么一句话: 经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$rem ...
- 获取客户端真实 IP
Tomcat + Nginx 反向代理获取客户端真实IP.域名.协议.端口 Nginx 反向代理后,Servlet 应用通过 request.getRemoteAddr() 取到的 IP 是 Ngin ...
- vue获取url中ip_Kubernetes 集群中这样获取客户端真实 IP
Kubernetes 依靠 kube-proxy 组件实现 Service 的通信与负载均衡.在这个过程中,由于使用了 SNAT 对源地址进行了转换,导致 Pod 中的服务拿不到真实的客户端 IP 地 ...
- nginx多层反向代理获取客户端真实ip
访问路径: 用户 --> www.chinasoft.cn(nginx反向代理) --> www.chinasoft.com(nginx反向代理) --> python服务端程序经过 ...
- egg.js 获取客户端真实ip
前言:在使用egg.js的时候,一般会开node服务,然后使用nginx代理我们egg.js的接口,因此产生了egg.js获取的ip地址并不是客户端真实ip,而是拿到的是nginx 的地址.故需要两点 ...
- php获取客户端真实ip
php获取客户端ip地址小结: 微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_5 此外的三个值区别如下: 一.没有使用 ...
- 如何获取客户端真实IP
简介 获取客户端的IP地址常用的方法是:request.getRemoteAddr().但是如果通过了Apache,Nagix等反向代理软件则获取不到客户端的真实IP. 经过代理以后,由于在客户端和服 ...
- django获取客户端真实IP
2019独角兽企业重金招聘Python工程师标准>>> 1settings.py中 添加中间件: 'django.middleware.http.SetRemoteAddrFromF ...
- Asce Networks 获取客户端真实IP
在项目中使用request.getHeader("X-Cluster-Client-IP")获得IP
最新文章
- 两代“狗”开发者首次解答30多个问题,一定有你想了解的!(附论文下载)
- Dubbo-go 发布 1.5 版,朝云原生迈出关键一步
- Cocos2D-X2.2.3学习笔记5(UI系统)
- Jenkins X基本概念:Jenkins K8S helm Draft gitops
- 深入Java关键字null
- 一种单独适配于NER的数据增强方法:DAGA
- poj3422 Kaka's Matrix Travels(最小费用最大流问题)
- (2021) 22 [持久化] 1-Bit的存储
- Kubernetes 使用 ingress 配置 https 集群(十五)
- 简单的动态JavaScript Ajax函数
- mongodb转mysql思路_脚本 将阿里云 mongodb数据转成mysql
- 程序员必备技能-科学砍需求 1
- 水泵综合性能测试系统软件,水泵综合性能测试系统
- 电脑开机3秒就重启循环_手机怎么才能投屏到电脑上?3个方法,小屏1秒变大屏,涨知识了...
- windows系统mysql-5.7官方绿色版zip包安装教程
- 第十三届蓝桥杯A组Python组心得分享
- Informatica的元数据和数据血缘关系
- 相机和镜头选型计算公式
- 用力过猛的“中产阶级教育
- git从本地添加项目到远程仓库