nginx 获取真实ip
问题背景:
在实际应用中,我们可能需要获取用户的ip地址,比如做异地登陆的判断,或者统计ip访问次数等,通常情况下我们使用request.getRemoteAddr()就可以获取到客户端ip,但是当我们使用了nginx作为反向代理后,使用request.getRemoteAddr()获取到的就一直是nginx服务器的ip的地址,那这时应该怎么办?
part1:解决方案
我在查阅资料时,有一本名叫《实战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;
其中这个X-real-ip是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-real-ip这个变量里了,然后,在web端可以这样获取:
request.getAttribute("X-real-ip")
这样就明白了吧。
part2:原理介绍
这里我们将nginx里的相关变量解释一下,通常我们会看到有这样一些配置
server {
listen 88;
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.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转发,即用户访问该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.getAttribute("X-Forwarded-For")获得的值是null。如果想要通过request.getAttribute("X-Forwarded-For")获得用户ip,就必须先使用proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;这样就可以获得用户真实ip。
nginx 获取真实ip相关推荐
- nodejs+nginx获取真实ip
nodejs + nginx获取真实ip分为两部分: 第一.配置nginx: 第二.通过nodejs代码获取: 其他语言也是一样的,都是配置nginx之后,在http头里面获取"x-forw ...
- ASP.NET Core 搭配 Nginx 的真实IP问题
一.前言 Nginx(Engine X)是一个高性能HTTP和反向代理服务,是由俄罗斯人伊戈尔·赛索耶夫为访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发 ...
- Netty获取真实IP
本文参考:https://www.jianshu.com/p/cc8d592582c9 感谢分享 Netty获取真实IP netty想要获取客户端请求的IP有两种方法: 一.通过ChannelHand ...
- nginx 后端获取真实ip
nginx前端配置 server { listen 80; server_name blog.jinchuang.org; access_log logs/blog.access.log; error ...
- nginx 日志格式设置 和 负载均衡下 获取真实ip
log_format log 格式 '配置规则'; 日志格式设置: $remote_addr与$http_x_forwarded_for用以记录客户端的ip地址: $remote_user:用来记 ...
- php负载均衡如何获得真实ip,nginx负载均衡后端RS中获取真实ip
nginx负载均衡后端RS中获取真实ip 前端proxy配置 #################### worker_processes 1; events { worker_connections ...
- Nginx获取真实用户IP
多级代理下Nginx获取真实用户IP地址的总结 声明:本文参考http://www.ttlsa.com/nginx/nginx-get-user-real-ip/并做了一些补充讲解,希望会更加清晰明了 ...
- nginx反向代理后,java获取真实ip和解决request.getServerName()的问题
1. nginx.conf的server下增加以下配置 #解决request.getServerName()的问题proxy_set_header Host $host:$server_port;pr ...
- waf+Nginx+apache获取真实ip
1.waf作为首层代理配置项: proxy_set_header X-real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add ...
最新文章
- linux 修改home 目录
- G.703通道故障打环测试方法
- 【APP接口开发】chrome浏览器DHC工具安装使用(亲测有效)
- 由laravel 5.5无法获取url中的参数引发的apache的.htaccess文件问题
- spring-AOP前言
- 两列布局、三列适应布局、两列等高适应布局。
- [html] 为什么说cookie不可以滥用?
- ROS学习笔记基础2(基础知识和ROS架构)
- 控制台打印菱形和方形
- TraceView的使用
- 乐视盒子u4刷Android,乐视盒子u4安装优酷
- 如何在本地运行jar文件
- OBS录屏软件使用指南
- 图像分割论文 “RANet : Region Attention Network for Semantic Segmentation”
- GO的lua虚拟机 gopher-lua
- device-side assert triggered原因和解决方法
- Win11如何设置系统还原点?
- 网站SEO优化方案 全面详细的写法
- Flask06_ORM多表
- Linux 加密与解密应用
热门文章
- 对称加密与非对称加密的区别_https原理及对称加密、非对称加密、数字证书、数字签名的含义...
- linux安装neo4j及远程访问
- Linux 检查域名服务,linux上的域名服务
- python实现将文件内容按照某一列内容的大小值重新排序_Python数据分析入门教程(四):数值操作...
- 数据可视化模块---Matplotlib
- php指定异常状态码,php怎么设置状态码
- myeclipse导出doc
- 《系统集成项目管理工程师》必背100个知识点-07项目建议书的内容
- 笔记-项目干系人管理
- MapReduce Java API实例-统计出现过的单词