Nginx获取真实用户IP
多级代理下Nginx获取真实用户IP地址的总结
声明:本文参考http://www.ttlsa.com/nginx/nginx-get-user-real-ip/并做了一些补充讲解,希望会更加清晰明了~
随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户的真实IP地址,如果后端是apache,请跳转到<apache获取用户真实IP地址>,如果是后端真实服务器是nginx,那么继续往下看。
实例环境:
用户IP 120.22.11.11
CDN前端 61.22.22.22
CDN中转 121.207.33.33
公司NGINX前端代理 192.168.50.121(外网121.207.231.22)
1、使用CDN自定义IP头来获取
假如说你的CDN厂商使用nginx,那么在nginx上将$remote_addr赋值给你指定的头,方法如下:
proxy_set_header remote-user-ip $remote_addr;
|
//如上,后端将会收到remote_user_ip的http头,有些人可能会挑错了,说我设置的头不是remote-user-ip吗,怎么写成了remote_user_ip,是不是作者写错了.请参考文章:<nginx反向代理proxy_set_header自定义header头无效>
后端PHP代码getRemoteUserIP.PHP
<?php
|
$ip = getenv( "HTTP_REMOTE_USER_IP" );
|
echo $ip;
|
?>
|
访问getRemoteUserIP.php,结果如下:
120.22.11.11 //取到了真实的用户IP
|
注:这里$remote_addr是nginx的变量,一般情况是,是报文发送方的IP地址,如果发送方为proxy,那么这里就是proxy的ip,而非用户的真实ip.
注意:这里面会有一个问题,就是所谓的XFF欺骗,当用户直接访问后端的时候,并且他伪造了HTTP报头REMOTE_USER_IP,那么后端获取到的,将是一个虚假的用户IP,这个时候可能会产生一些安全问题。如果可以,建议的做法是:后端服务不允许对外部用户访问,最前端的代理,proxy_set_header xxxxx $remote_addr;这样就能解决欺骗,因为$remote_addr获取的是用户IP数据包中的IP,而非伪造的HTTP报文首部。
2、通过HTTP_X_FORWARDED_FOR获取IP地址
一般情况下CDN服务器都会传送HTTP_X_FORWARDED_FOR头。而且会用proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
这里,$proxy_add_x_forwarded_for是一个神奇的变量,假如接收到的报文已经含有X-FORWARDED-FOR首部,那么nginx将在后面添加上$remote_addr(也就是发送者的ip地址在最后),因此后端的真实服务器获取HTTP_X_FORWARDED_FOR头,截取字符串第一个不为unkown的IP作为用户真实IP地址, 例如:
120.22.11.11, 61.22.22.22, 121.207.33.33,192. 168.50.121(用户IP,CDN前端IP,CDN中转,公司NGINX代理)
getFor.php
<?php
|
$ip = getenv( "HTTP_X_FORWARDED_FOR" );
|
echo $ip;
|
?>
|
访问getFor.php结果如下:
120.22.11.11,61.22.22.22,121.207.33.33,192.168.50.121
|
如果你是php程序员,你获取第一个不为unknow的ip地址,这边就是120.22.11.11.
同理,为防止XFF欺骗,除了第一层代理,后面的多禁止普通用户访问,第一层代理,用$remote_addr来设置pass X-Forwarded-For即可。
3.使用nginx自带模块realip获取用户IP地址
有些时候,中间或者后端的代理,都要能够被普通用户访问,也或者在nginx日志中,想让$remote_adrr配置的格式,能显示外界用户的ip,这个时候,就要使用realip模块了。
安装nginx之时加上realip模块,我的参数如下:
./configure --prefix=/usr/ local /nginx-1.4.1 --with-http_realip_module
|
真实服务器nginx配置
server {
|
listen 80;
|
server_name www.ttlsa.com;
|
access_log /data/logs/nginx/www.ttlsa.com.access.log main;
|
index index.php index.html index.html;
|
root /data/site/www.ttlsa.com;
|
location /
|
{
|
root /data/site/www.ttlsa.com;
|
}
|
location = /getRealip.php
|
{
|
set_real_ip_from 192.168.50.0/24;
|
set_real_ip_from 61.22.22.22;
|
set_real_ip_from 121.207.33.33;
|
set_real_ip_from 127.0.0.1;
|
real_ip_header X-Forwarded-For;
|
real_ip_recursive on;
|
fastcgi_pass unix:/var/run/phpfpm.sock;
|
fastcgi_index index.php;
|
include fastcgi.conf;
|
}
|
}
|
getRealip.php内容
<?php
|
$ip = $_SERVER[ 'REMOTE_ADDR' ];
|
echo $ip;
|
?>
|
访问www.ttlsa.com/getRealip.php,返回:
120.22.11.11
|
如果注释 real_ip_recursive on或者 real_ip_recursive off
访问www.ttlsa.com/getRealip.php,返回:
121.207.33.33
|
很不幸,获取到了中继的IP,real_ip_recursive的效果看明白了吧.
set_real_ip_from:真实服务器上一级代理的IP地址或者IP段,可以写多行
real_ip_header:从哪个header头检索出要的IP地址
real_ip_recursive:递归排除IP地址,ip串从右到左开始排除set_real_ip_from里面出现的IP,如果出现了未出现这些ip段的IP,那么这个IP将被认为是用户的IP。例如我这边的例子,真实服务器获取到的IP地址串如下:
120.22.11.11,61.22.22.22,121.207.33.33,192.168.50.121
在real_ip_recursive on的情况下
61.22.22.22,121.207.33.33,192.168.50.121都出现在set_real_ip_from中,仅仅120.22.11.11没出现,那么他就被认为是用户的ip地址,并且赋值到remote_addr变量
在real_ip_recursive off或者不设置的情况下
192.168.50.121出现在set_real_ip_from中,排除掉,接下来的ip地址便认为是用户的ip地址
如果仅仅如下配置:
set_real_ip_from 192.168.50.0/24;
|
set_real_ip_from 127.0.0.1;
|
real_ip_header X-Forwarded-For;
|
real_ip_recursive on;
|
访问结果如下:
121.207.33.33
|
这里可能有朋友会不理解,我来补充解释一下http_realip_module这个模块好了,它包括三个指令:
1、set_real_ip_from 是指接受从哪个信任前代理处获得真实用户ip
2、real_ip_header 是指从接收到报文的哪个http首部去获取前代理传送的用户ip
3、real_ip_recursive 是否递归地排除直至得到用户ip(默认为off)
首先,real_ip_header 指定一个http首部名称,默认是X-Real-Ip,假设用默认值的话,nginx在接收到报文后,会查看http首部X-Real-Ip。
(1)如果有1个IP,它会去核对,发送方的ip是否在set_real_ip_from指定的信任ip列表中。如果是被信任的,它会去认为这个X-Real-Ip中的IP值是前代理告诉自己的,用户的真实IP值,于是,它会将该值赋值给自身的$remote_addr变量;如果不被信任,那么将不作处理,那么$remote_addr还是发送方的ip地址。
(2)如果X-Real-Ip有多个IP值,比如前一方代理是这么设置的:proxy_set_header X-Real-Ip $proxy_add_x_forwarded_for;
得到的是一串IP,那么此时real_ip_recursive 的值就至关重要了。nginx将会从ip列表的右到左,去比较set_real_ip_from 的信任列表中的ip。如果real_ip_recursive为off,那么,当最右边一个IP,发现是信任IP,即认为下一个IP(右边第二个)就是用户的真正IP;如果real_ip_recursive为on,那么将从右到左依次比较,知道找到一个不是信任IP为止。然后同样把IP值复制给$remote_addr。(可以参考上面的例子,帮助理解这个过程)
因此,明白了整个过程后,我们知道,用realip模块是非常好用的,能满足各种获取用户IP的需求,而且不会受到XFF欺骗!
那么问题来了,后端除了想获取用户ip,也想获取代理ip,怎么办呢?那么此时$proxy_add_x_forwarded_for派上用场。只需要在每一层代理IP,都保持一个良好的习惯:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;然后后端得到的X-Forwarded-For首部,依次就是用户IP到各层代理的IP,至于最靠近自己的代理ip,各种web开发语言都有获取发送方真实IP的接口了,然后你知道该怎么做了吧?!
Nginx获取真实用户IP相关推荐
- nginx经过多层代理后获取真实来源ip
nginx取 $remote_addr 当做真实ip,而事实上,$http_X_Forwarded_For 才是用户真实ip,$remote_addr只是代理上一层的地址 解决方案: 在 http 模 ...
- Nginx在多层代理下获取真实客户端IP地址
最近在研究nginx中如何获取真实客户端IP的方法.众所周知,在编译Nginx时,可通过添加http_realip_module模块来获取真实客户端IP地址.何为真实IP地址呢?请看下图,既获取到的真 ...
- nodejs+nginx获取真实ip
nodejs + nginx获取真实ip分为两部分: 第一.配置nginx: 第二.通过nodejs代码获取: 其他语言也是一样的,都是配置nginx之后,在http头里面获取"x-forw ...
- 学习笔记 - Nginx在多层代理下获取真实客户端IP地址
最近在研究nginx中如何获取真实客户端IP的方法.众所周知,在编译Nginx时,可通过添加http_realip_module模块来获取真实客户端IP地址.何为真实IP地址呢?请看下图,既获取到的真 ...
- Java获取登录用户IP地址
Java获取登录用户IP地址 /*** @param * @return * @throws * @description * @author wqd* @date 2021/9/21 13:45*/ ...
- nginx 获取真实ip
问题背景: 在实际应用中,我们可能需要获取用户的ip地址,比如做异地登陆的判断,或者统计ip访问次数等,通常情况下我们使用request.getRemoteAddr()就可以获取到客户端ip,但是当我 ...
- nginx curl命令有效 curl_setopt无效_日志分析系列(外传一):Nginx透过代理获取真实客户端IP...
本系列中的故事纯属虚构,如有雷同实属巧合 小B是Q公司的安全攻城狮,为了完成任务小B开始做起了调研(欲知背景如何,且听下回分说). 首先小B弄明白了Q公司的应用系统架构是:Client --> ...
- Nginx透过代理获取真实客户端IP
本系列中的故事纯属虚构,如有雷同实属巧合 小B是'柒'公司的安全攻城狮,为了完成任务小B开始做起了调研(欲知背景如何,且听下回分说). 首先小B弄明白了'柒'公司的应用系统架构是:Client --& ...
- 使用nginx代理,怎么获取真实的IP
1.在nginx.conf配置中加入配置信息 proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; pr ...
最新文章
- qq浏览器主页_QQ浏览器遭恶意病毒篡改主页,无法更改的解决办法
- 电脑的发展史_互联网发展史 硅谷传奇之苹果公司
- 深入理解JVM虚拟机(七):虚拟机字节码执行引擎
- 智慧显示:5G时代的新机遇
- window.open打开页面并传值,window. location.search遍历获取到的请求链接中的所有参数
- Web API的CORS
- java取拼音首字母_java取出汉字字符串的拼音首字母
- 为开发者们准备的10款超棒的jQuery视频插件
- 3Ds MAX 软件介绍
- 如何将多张图片转换为pdf格式
- uniapp 连接ibeacon beacon
- iOS 字体转换
- Vue3中TSX和h函数的用法
- 写出HTML的基本结构 做简要说明,北京市顺义区2017年--2018年届高三二模语文试题(卷)与答案解析.doc...
- Android 多进程同时打开相机
- cf 940E Cashback
- 《论语》原文及其全文翻译 学而篇12
- tushare +talib 三指标筛选股票
- Kaggle系列(3)- Telco Customer Churn
- php mysql 上一页 下一页 分页代码片段
热门文章
- IoC容器和 Dependency Injection模式 Inversion of Control Containers and the Dependency Injection pattern
- 基于NLM的插值算法
- 计算机软件技术介绍ppt,计算机软件技术基础.ppt
- matlab 变分不等式,求解变分不等式的matlab程序
- Unity使用反射探头实现地面的镜面反射
- 二年级数学计算机教学教案,人教版-小学二年级数学上册全套教案.pdf
- 成功将 戴尔灵越燃7000 II 改装Win7
- lua中的整除与取整数
- 技术胖Web前端视频教程合集
- 应用及实例,在信用卡业务中的数据挖掘技术分析