Nginx 反向代理时获取用户的真实 IP
在平时我们开发后端程序的过程中,应该多多少少都会碰到记录客户端 IP 的场景,例如我之前写过的 APP 用户的一个审计功能,就需要获取用户的 IP 地址;还有广告系统里面,也是需要获取用户的 IP 地址,有时这个 IP 地址会被用来标识用户的,因此需要比较准确得获取到用户的地址。当然,在开始本文的内容之前还是有必要强调一下我们现在的网络大环境的,在使用 IP 的时候,我们一定要记住有两个东西很关键,一个是网关,一个是代理。
网关其实好理解,说简单一些的就路由器吧,因为 IPv4 的地址空间是有限的,所以就有了局域网共用一个公网 IP 的事实。这在一个集体里面很容易出现,例如家庭、学校,如果我们不加分辨得直接就使用 IP 来记录或者屏蔽,那么很容易出问题,如果将这个问题再扩大化一点,那就是移动端,因为我们知道移动端都是通过连接信号塔进行数据通信的,那么对于一个范围内的同一运营商来说,IP 地址就很可能是一样的,这是移动开发中一个很关键的点;还有就是代理,很多公司对于网络都是封锁得很严厉的,所以所有的对外流量都通过一个代理交流,这也就导致了很多情况下都是同一个代理出来的都是一个 IP,这也是一个非常重要的问题,很容易一棍子打死一船人。
OK,闲话扯完了,回到主题,在后端程序中,一般客户端/前端的流量都不会直接就打到后端的应用上,正常最少都会加一层反向代理,稍复杂一些的还会有负载均衡啥的,这也给我们提取客户端 IP 带来了很大的麻烦,所以我这里就以 Nginx 为例,说说如何更好得获取正确的 IP 值。
下面下来一段我用了好多年的 Nginx 配置,夸张点说就祖传的吧:

这里会出现了好几个和 IP 有关的字段,这也是获取 IP 的关键,对于这些字段如果我们细致得了解了它的来源和原理之后,那么获取相对准确的 IP 也就没那么困难了,下面就一一进行介绍:
Remote Addr
remote_addr 这个字段不是 http 里面的概念,其实是 tcp 的概念,表示的是当前连接的对端的地址,也就是说:
- 如果在浏览器和 Nginx 之间不存在其他代理,那么这个字段就是真实的 IP
- 但是,一旦浏览器和 Nginx 之间存在代理,那么这个字段的值就是最后一个代理的地址
X-Real-IP
正如配置中所示,HTTP 中其实不存在这个 Header,但是在 Nginx 中习惯于用来标识用户的真实地址,至于是否真的是客户端的地址,看前面的 remote_addr 的解释我们就清楚了。
X-Forwarded-For
这个就有意思了,X-Forwarded-For 表示在客户端访问 Nginx 的过程中如果需要经过 HTTP 代理或者负载均衡服务器,可以被用来获取最初发起请求的客户端的 IP 地址,这个消息首部成为事实上的标准。怎么说,其实就是一个 HTTP 请求从浏览器发出,每经过一个 HTTP 代理或者负载均衡,都会在这个 Header 里面添加一条记录(当然,这是规定,你不遵守我也没办法),所以对于一个请求来说,X-Forwarded-For Header 的值列表里面的第一个值应该就是客户端的地址,及时经过了 N 多的代理和负载均衡。
但是,这毕竟不是真正的标准,所以我们不能期望 100% 一定有这个,但是根据我的经验,对于一些比较成熟的反向代理软件 例如 Nginx/Squid 都是有的,所以大多数情况下都可以通过这个字段获取到真实值。
X-Forwarded-Host
好吧,这个 Header 是乱入的,它和客户端的 IP 没啥关系,它其实是标识客户端发起请求时的 Host 的地址,我们可以通过这个 Header 来获取客户端是访问的哪个 Host 进来的。
结论
所以通过上面的介绍,我们知道,其实就只有两个东西,分别是 remote_addr 和 X-Forwarded-For,如果中间存在不可控的代理,那么我们应该优先通过 X-Forwarded-For 的第一个值来获取客户端真实 IP;如果中间的代理都是可控的,那么我们优先通过 remote_addr 来获取客户端真实的 IP,而且这个 IP 是不可伪造的。
Nginx 反向代理时获取用户的真实 IP的更多相关文章
- nginx做反向代理时获取真实IP
原文:http://blog.csdn.net/aquester/article/details/48657395 1. 编译 对于client -> nginx reverse proxy - ...
- JAVA获取客户端请求的当前网络ip地址(附:Nginx反向代理后获取客户端请求的真实IP)
1. JAVA获取客户端请求的当前网络ip地址: /** * 获取客户端请求的当前网络ip * @param request * @return */ public static String get ...
- 深入nginx之《获取用户的真实IP》
获取用户的真实IP Nginx会将客户端的IP信息存放在$remote_addr变量里,但这并不意味着它就是客户端的IP,生产环境往往会充满各种代理,让IP的来龙去脉变得扑朔迷离. 目前互联网公司基本 ...
- nginx 反向代理时丢失端口的解决方案
今天,配置nginx反向代理时遇到一个问题,当设置nginx监听80端口时转发请求没有问题.但一旦设置为监听其他端口,就一直跳转不正常:如,访问欢迎页面时应该是重定向到登录页面,在这个重定向的 ...
- nginx 反向代理时丢失端口的解决方案(转)
今天,配置nginx反向代理时遇到一个问题,当设置nginx监听80端口时转发请求没有问题.但一旦设置为监听其他端口,就一直跳转不正常:如,访问欢迎页面时应该是重定向到登录页面,在这个重定向的过程中端 ...
- 获取用户的真实ip
常见的坑有两个: 一.获取的是内网的ip地址.在nginx作为反向代理层的架构中,转发请求到php,java等应用容器上.结果php获取的是nginx代理服务器的ip,表现为一个内网的地址.php获取 ...
- PHP获取用户的真实IP地址
本文出至:新太潮流网络博客 PHP获取用户的真实IP地址,非代理IP function getClientIP(){ global $ip; if(getenv("HTTP_CLIENT_I ...
- F5后端nginx+tomcat应用如何获得用户的真实ip【转】
根据业务需要要求记录每个通过wap或者客户端访问我们服务器的用户真实ip但是由于业务前端部署了两个3900系列的F5设备导致程序一直获得F5设备自身的ip,所以笔者考虑可能是因为F5导致无法获得用户的 ...
- 使用nginx反向代理时,如何正确获取到用户的真实ip
在记录日志的的时候,获取用户的信息,比如用户的ip,浏览器等等信息是十分重要的. 但是在使用nginx反向代理的时候,可能经过转发无法获取到用户的真实的ip, 在此情况下需要配置nginx,让其在转发 ...
随机推荐
- (转)为什么要重写 hashcode 和 equals 方法?
作者丨hsm_computer cnblogs.com/JavaArchitect/p/10474448.html 我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候 ...
- Code Chef TSUM2(动态凸包+点分治)
题面 传送门 题解 真是毒瘤随机化算法居然一分都不给 首先这种树上的题目一般想到的都是点分 我们考虑如何统计经过当前点的路径的贡献,设当前点\(u\)在序列中是第\(c\)个,那么一条路径的贡献就是 ...
- AndroidManifest.xml文件安全探索
本文作者:i春秋签约作家——icq8756c1a2 最近在做一些apk的安全检测,对AndroidManifest.xml文件进行了研究和探讨,介绍AndroidManifest.xml文件的作用和架 ...
- git忽略掉文件权限检查
有时 git diff 执行显示文件内容没变化,但是有 old mode xxx new mode,原因是文件的权限,被chmod变化了,这种变化也被 diff 识别出来了,让git忽略掉文件权限检查 ...
- maven添加仓库没有的jar包
mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.4.0 -Dpackaging= ...
- cas单点登陆系统-casServer搭建
最近工作比较忙,空闲的时间在搞单点登陆系统,自己写了一套SSO在GitHub上,过程走通了.通过这个例子,自己熟悉了流程,而且破天荒的使用了抽象设计模式,并且熟悉了cookies和session的使用 ...
- NSTimer、performSelector 函数没有被调用的原因
performSelector 指定的方法没有被调用 Invokes a method of the receiver on the current thread using the default ...
- D07——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D07 20180826内容纲要: 面向对象进阶学习 1 静态方法 2 类方法 3 属性方法 4 类的特殊成员方法(本节重点) 5 反射(本节重点) 6 异常(本 ...
- 【learning】微信跳一跳辅助c++详解 轻松上万 【下】
如果你还没有看完本blog的上篇,建议您先看完上篇!! 第一代辅助如何死的? 我们先来看四张图 如上方最左图所示,前面是一个小圆柱子,看起来很人畜无害似不似?? 由于上一步跳出了偏差,并没有 ...
- 平衡二叉树(AVL)的理解和实现(Java)
AVL的定义 平衡二叉树:是一种特殊的二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1.从平衡二叉树的名字中可以看出来,它是一种高度平衡的二叉排序树.那么什么叫做高度平衡呢?意思就是要么它 ...