服务器获取真实客户端 IP
0x01 先查个问题
测试环境微信支付通道提示网络环境未能通过安全验证,请稍后再试
,出现这种情况一般首要 想到可能是双方网络交互中微信方验参与我们出现不一致,翻了下手册确定是这类问题开始排查环节
可能获取真实IP方式错误
getenv('HTTP_CLIENT_IP')
getenv('HTTP_X_FORWARDED_FOR')
getenv('REMOTE_ADDR')
filter_var($remote_ip, FILTER_VALIDATE_IP)
- 已经依次获取并过滤
- 固程序没有任何问题,往上发散
是否反向代理
经过反向代理后,由于在客户端和
web
服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip
,只能通过$remote_addr
变量拿到的将是反向代理服务器的ip地址,检查不存在此类问题,再往上,擅长网络通信工程的同学表示绝不认输可能
NAT
分配出口IP
,或负载均衡服务分发出现异常- 先拿到我本地内网外网IP 方便之后问题排查
# 本机IP ifconfig | grep -A 1 "en" | grep broadcast | cut -d " " -f 2 # 外网IP curl --silent http://icanhazip.com 复制代码
- 检查与80端口建立连接目标都有谁
netstat -tn|grep 80|akw '{print $5}'|awk -F '{print $1}' | grep [本地IP] 复制代码
这里出现问题,竟然没有我的
IP
,再以nginx $remote_addr
拿到的IP作为参考,这是nginx
最后一次握手的IP
,$remote_addr = 10.168.0.0/16
段在
nginx
处打印$remote_addr
,并在server_name
添加当前机器ip
,分别以负载均衡IP与本地IP做测试,最终确定问题出现在负载均衡服务器出现异常
0x02 LNMP栈拿真实IP
LNMP
栈内PHP
所有获得到的TCP
操作信息都是由前面Nginx
通过fastcgi
传递给它的,就比如$_SERVER['REMOTE_ADDR']
由include fastcgi.conf;
引进,其等于nginx
的$remote_addr
Nginx
中的几个变量:
$remote_addr
代表客户端的
IP
,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,icanhazip
的原理也是这样, 当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器就会把remote_addr
设为你在公网暴露的IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web
服务器就会把remote_addr
设为这台代理机器的IP, 除非代理将你的IP附在请求header
中一起转交给web
服务器。$proxy_add_x_forwarded_for
$proxy_add_x_forwarded_for
变量包含客户端请求头中的"X-Forwarded-For
",与$remote_addr
两部分,他们之间用逗号分开。X-Forwarded-For
(简称XFF),X-Forwarded-For
是一个 HTTP 扩展头部。RFC 2616 协议并没有对它的定义,它最开始是由Squid
这个缓存代理软件引入,用来表示HTTP
请求端真实 IP。如今它已经成为事实上的标准,被各大HTTP
代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension` 标准之中。$proxy_set_header
已在排查问题中说明,可设置代理后 header
proxy_set_header Host $http_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-Proto $scheme; 复制代码
X-Real-IP
一般比如
X-Real-IP
这一个自定义头部字段,通常被HTTP
代理用来表示与它产生TCP
连接的设备IP
,这个设备可能是其他代理,也可能是真正的请求端,这个要看经过代理的层级次数或是是否始终将真实IP
一路传下来。(牢记:任何客户端传上来的东西都是不可信的)
当多层代理或使用CDN时,如果代理服务器不把用户的真实IP传递下去,那么服务器将永远不可能获取到用户的真实IP。
0x03 用户的真实IP从何而来
宽带供应商提供独立IP 比如家里电信宽带上网,电信给分配了公网ip,那么一个请求经过的ip路径如下:
这种情况下,
119.147.19.234
会把得到的116.1.2.3
附加到头信息中传给10.168.0.0/32
,因此这种情况下,我们取得的用户ip则为:116.1.2.3
。 如果119.110.0.0/16
没有把116.1.2.3
附加到头信息中传给业务服务器,业务服务器就只能取上上一级ip地址宽带供应商不能提供独立IP
宽带提供商没有足够的公网
ip
,分配的是个内网ip
,比如长宽等小的isp。请求路径则可能如下:这种情况下得到的用户ip,就是
211.162.78.1
。 这种情况下,就可能出现一个ip对应有数十上百个用户的情况了手机2g上网
网络提供商没法直接提供ip给单个用户终端,以中国移动cmwap
上网为例,因此请求路径可能为:
这种情况下得到的用户ip,就是202.96.75.1
。2008年的时候整个广东联通就三个手机上网的公网ip,因此这种情况下,同一ip出现数十万用户也是正常的。
有几万或数十万员工的公司
这种也会出现来自同一
ip
的超多用户,可能达到几万人,但出口IP可能就那么几个。
0x04 NAT [Network Address Translation]
中文意思是网络地址转换
,它允许一个整体机构以一个公用IP
地址出现在Internet
上。
NAT
在 OSI参考模型
的网络层 (第3层), 它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。NAT
可以让那些使用私有地址的内部网络连接到Internet
或其它IP
网络上。NAT
路由器在将内部网络的数据包发送到公用网络时,在IP
包的报头把私有地址转换成合法的IP
地址。
RFC1918 规定了三块专有的地址,作为私有的内部组网使用
- A类:10.0.0.0 — 10.255.255.255 10.0.0.0/8
- B类:172.16.0.0 — 172.31.255.255 172.16.0.0/12
- C类:192.168.0.0 — 192.168.255.255 192.168.0.0/16
这三块私有地址本身是可路由的,只是公网上的路由器不会转发这三块私有地址的流量;当一个公司内部配置了这些私有地址后,内部的计算机在和外网通信时,公司的边界路由会通过NAT
或者PAT
技术,将内部的私有地址转换成外网IP,外部看到的源地址是公司边界路由转换过的公网IP
地址,这在某种意义上也增加了内部网络的安全性
这个过程是通过NAT
中的本地址与全局地址映射条目来实现的,所以事先要在NAT
路由器上配置这样的映射条目。
通过这种方式一个公网 IP
底下可以发私有的 IP
地址。
0x05 IPV6 来了?
写这篇文章的时候看到有个推送,表示阿里全面应用IPV6
,这件事的意义还挺重大的
我们知道,一段 IPv4
标准的 IP
地址,一共由 4 X 8 = 32
位二进制数字组成,理论上存在 2^32
个 IP 地址。等于 4,294,967,296
, 42
亿多个 IPv4
的地址。
参考世界互联网用户统计报告,全球现在大概有4,208,571,287
人在上网,也就是说已经快到ipv4
地址设计的最大IP
数了
不过不用担心,前面提到的 NAT
,让 IPv4
公网 IP
哪怕用完了也能凑合过。
到了 IPv6
,相比 IPv4
最大的提升,就是位数大大增加,变成了 8 个 4 位的十六进制数字。也就是说有 2^128
个 IPv6
地址。地球上的每粒沙子都分一个也管够
存储2^128
字节理论上什么概念呢,在当今的量子水平下,假设计算设备能够操作在原子一级,每公斤质量可存储大约10的25次方bits,存储2的128次方的字节大约需要272 trillion = 2720000亿公斤
。
最后,周末愉快,北京联通已经支持ipv6
了,我在望京测试,可以拿到 ipv6
地址
转载于:https://juejin.im/post/5c0b91a6e51d451d8d69c54c
服务器获取真实客户端 IP相关推荐
- nginx curl命令有效 curl_setopt无效_日志分析系列(外传一):Nginx透过代理获取真实客户端IP...
本系列中的故事纯属虚构,如有雷同实属巧合 小B是Q公司的安全攻城狮,为了完成任务小B开始做起了调研(欲知背景如何,且听下回分说). 首先小B弄明白了Q公司的应用系统架构是:Client --> ...
- Nginx透过代理获取真实客户端IP
本系列中的故事纯属虚构,如有雷同实属巧合 小B是'柒'公司的安全攻城狮,为了完成任务小B开始做起了调研(欲知背景如何,且听下回分说). 首先小B弄明白了'柒'公司的应用系统架构是:Client --& ...
- Nginx在多层代理下获取真实客户端IP地址
最近在研究nginx中如何获取真实客户端IP的方法.众所周知,在编译Nginx时,可通过添加http_realip_module模块来获取真实客户端IP地址.何为真实IP地址呢?请看下图,既获取到的真 ...
- 学习笔记 - Nginx在多层代理下获取真实客户端IP地址
最近在研究nginx中如何获取真实客户端IP的方法.众所周知,在编译Nginx时,可通过添加http_realip_module模块来获取真实客户端IP地址.何为真实IP地址呢?请看下图,既获取到的真 ...
- ABP vNext 审计日志获取真实客户端IP
背景 在使用ABP vNext时,当需要记录审计日志时,我们按照https://docs.abp.io/zh-Hans/abp/latest/Audit-Logging配置即可开箱即用,然而在实际生产 ...
- java获取f5服务器真实ip,F5服务器做负载均衡时WebService获取真实客户端IP地址
首先,我先来介绍一下什么是F5服务器,内容来自百度: 负载均衡,英文名称为Load Balance,其意思就是将负载(工作任务)进行平衡.分摊到多个操作单元上进行执行,例如Web服务器.FTP服务器. ...
- php获取真实客户端IP方法
可能有时候简单地通过php自带的$_SERVER获取的IP参数并不能满足我们的需求,则需要我们自定义一个获取IP的方法,通过学习ECSHOP的源码,我们可以把获取IP的方法封装如下: <?php ...
- 网站配置了Cloudflare代理后,如何配置Nginx获取的真实客户端IP地址?
网站配置了Cloudflare代理后,如何配置Nginx获取的真实客户端IP地址? 这是一个很简单的问题,如何在后台获取真实的访问者IP地址? 网站为了避免有些不怀好意的访问者,不得不自动分析一下客户 ...
- [Web/IP]真实IP获取原理/客户端IP伪造测试
真实IP获取和客户端IP伪造 近期比赛又做到了用户IP伪造的题目,想来不如就总结一下. 为什么要确认IP? 在Web应用下,部分逻辑需要确认用户的客户端IP.如对大量频繁发送危险请求的IP进行封禁. ...
最新文章
- MySQL为Null导致莫名其妙的5大坑
- golang LMDB入门例子——尼玛,LMDB的文档真的是太少了
- 这一次,字节的组织进化选择优化了CEO(附张一鸣卸任CEO内部信全文)
- [Android Studio] Android Studio如何快速生成get,set,tostring,构造函数
- 六天学会BASIC语言的方法——计算机达人成长之路(10)连载
- java虚拟机jvm下载_Java虚拟机(JVM)简介
- 路由器PPPoE拨号密码(ADSL密码)找出方法 ZT
- 语法分析——自顶向下分析方法
- 计算机网络基础 课程设计体会,计算机网络课程设计心得体会.pdf
- python论文排版格式_论文排版(一):三分钟了解页面设置
- 【基础】安卓获取当前系统SDK版本
- 遗传算法(二)——编码
- 中科院大学计算机科学与技术王伟强,王伟强 - 中国科学院大学 - 计算机科学与技术学院...
- grep命令的使用;正则;位置锚定
- 智能家居创意DIY之智能灯泡
- ceph客户端使用_CEPH应用
- Excel中VBA编程学习笔记(一)
- 新手上路,如何迅速搭建一套源码系统
- 我来说说这几天经历的南宁传销!慢慢更!
- gocolly-字符串cookies处理(4)