PHP获取客户端真实IP地址的5种情况分析和实现代码


Posted in PHP onJuly 08, 2014

在PHP获取客户端IP中常使用 $_SERVER["REMOTE_ADDR"] 。
(1) 但如果客户端是使用代理服务器来访问,那取到的是代理服务器的 IP 地址,而不是真正的客户端 IP 地址。要想透过代理服务器取得客户端的真实 IP 地址,就要使用 $_SERVER["HTTP_X_FORWARDED_FOR"] 来读取。
(2) 但只有客户端使用“透明代理”的情况下,$_SERVER["HTTP_X_FORWARDED_FOR"] 的值才是客户端真正的IP(如果是多层代理,该值可能是由客户端真正IP和多个代理服务器的IP组成,由逗号“,”分隔)。
(3) 而在“匿名代理”、“欺骗性代理”的情况下是代理服务器的IP值(如果是多层代理,该值可能由多个代理服务器的IP组成,由逗号“,”分隔)。
(4) 在“高匿名代理”的情况下是空值。

关于HTTP头信息中的REMOTE_ADDR、HTTP_FORWARDED_FOR值,分析如下,假设客户端真实IP是221.5.252.160:

 一、没有使用代理服务器的PHP获取客户端IP情况:

REMOTE_ADDR = 221.5.252.160

HTTP_VIA=没数值或者不显示

HTTP_X_FORWARDED_FOR = 没数值或不显示

二、使用透明代理服务器的情况:Transparent Proxies

REMOTE_ADDR = 最后一个代理服务器 IP

HTTP_VIA=代理服务器IP

HTTP_X_FORWARDED_FOR = 客户端真实 IP (经过多个代理服务器时,这个值类似:221.5.252.160, 203.98.182.163, 203.129.72.215)

 这类代理服务器还是将客户端真实的IP发送给了访问对象,无法达到隐藏真实身份的目的。

三、使用普通匿名代理服务器的PHP获取客户端IP情况:Anonymous Proxies

REMOTE_ADDR = 最后一个代理服务器 IP

HTTP_VIA=代理服务器IP

HTTP_X_FORWARDED_FOR = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215)

 这种情况下隐藏了客户端的真实IP,但是向访问对象透露了客户端是使用代理服务器访问它们的。

四、使用欺骗性代理服务器的情况:Distorting Proxies

REMOTE_ADDR = 代理服务器 IP

HTTP_VIA=代理服务器IP

 HTTP_X_FORWARDED_FOR = 随机的 IP(经过多个代理服务器时,这个值类似:220.4.251.159, 203.98.182.163, 203.129.72.215)

这种情况下同样透露了客户端是使用了代理服务器,但编造了一个虚假的随机IP(220.4.251.159)代替客户端的真实IP来欺骗它。

五、使用高匿名代理服务器的PHP获取客户端IP情况:High Anonymity Proxies (Elite proxies)

REMOTE_ADDR = 代理服务器 IP
HTTP_VIA=没数值或者不显示

 HTTP_X_FORWARDED_FOR = 没数值或不显示。

无论是REMOTE_ADDR还是HTTP_FORWARDED_FOR,这些头消息未必能够取得到,因为不同的浏览器不同的网络设备可能发送不同的IP 头消息。因此PHP使用$_SERVER["REMOTE_ADDR"] 、$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值可能是空值也可能是“unknown”值。

PHP获取客户端IP时另外一点需注意,使用函数getenv('HTTP_X_FORWARDED_FOR')或getenv('REMOTE_ADDR') 也可以如上代码一样取得同样的效果。但getenv()不支持在IIS的isapi方式下运行的PHP。

REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP。

HTTP_CLIENT_IP 是代理服务器发送的HTTP头。如果是“超级匿名代理”,则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。

$_SERVER['REMOTE_ADDR']; //访问端(有可能是用户,有可能是代理的)IP

$_SERVER['HTTP_CLIENT_IP'];  //代理端的(有可能存在,可伪造)

$_SERVER['HTTP_X_FORWARDED_FOR']; //用户是在哪个IP使用的代理(有可能存在,也可以伪造)

根据以上几种情况写出的PHP代码:

<?php

function getip() {  

 $unknown = ‘unknown';  

 if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown) ) {  

  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];  

 } 

 elseif ( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown) ) {  

  $ip = $_SERVER['REMOTE_ADDR'];  

 } 

}

?>
PHP 相关文章推荐
PHP输出英文时间日期的安全方法(RFC 1123格式)
Jun 13 PHP
ThinkPHP的L方法使用简介
Jun 18 PHP
PHP安全的URL字符串base64编码和解码
Jun 19 PHP
Zend Framework页面缓存实例
Jun 25 PHP
thinkphp使用phpmailer发送邮件的方法
Nov 24 PHP
thinkphp模板输出技巧汇总
Nov 24 PHP
Laravel 5框架学习之环境与配置
Apr 08 PHP
微信access_token的获取开发示例
Apr 16 PHP
php支持中文字符串分割的函数
May 28 PHP
WordPress网站性能优化指南
Nov 18 PHP
PHP实现的权重算法示例【可用于游戏根据权限来随机物品】
Feb 15 PHP
php实现将数组或对象写入到文件的方法小结【三种方法】
Apr 22 PHP
php+mysql不用递归实现的无限级分类实例(非递归)
Jul 08 #PHP
PHP生成短网址的3种方法代码实例
Jul 08 #PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
Jul 08 #PHP
php中函数前加&amp;符号的作用分解
Jul 08 #PHP
PHP实现的连贯操作、链式操作实例
Jul 08 #PHP
PHP类中的魔术方法(Magic Method)简明总结
Jul 08 #PHP
PHP的魔术常量__METHOD__简介
Jul 08 #PHP
You might like
在apache下限制每个虚拟主机的并发数!!!!
2006/10/09 PHP
PHP采集类Snoopy抓取图片实例
2014/06/19 PHP
Laravel框架实现redis集群的方法分析
2017/09/14 PHP
jquery中 $.expr使用实例介绍
2014/06/09 Javascript
jquery向上向下取整适合分页查询
2014/09/06 Javascript
分享28款免费实用的 JQuery 图片和内容滑块插件
2014/12/15 Javascript
JavaScript检查弹出窗口是否被阻拦的方法技巧
2015/03/13 Javascript
浅谈Sizzle的“编译原理”
2015/04/14 Javascript
详解JavaScript正则表达式中的global属性的使用
2015/06/16 Javascript
浅析C/C++,Java,PHP,JavaScript,Json数组、对象赋值时最后一个元素后面是否可以带逗号
2016/03/22 Javascript
零基础轻松学JavaScript闭包
2016/12/30 Javascript
值得分享和收藏的xmlplus组件学习教程
2017/05/05 Javascript
Node.js 实现简单的接口服务器的实例代码
2017/05/23 Javascript
微信小程序 POST请求的实例详解
2017/09/29 Javascript
jquery实现点击a链接,跳转之后,该a链接处显示背景色的方法
2018/01/18 jQuery
JavaScript函数apply()和call()用法与异同分析
2018/08/10 Javascript
微信小程序文章列表功能完整实例
2020/06/03 Javascript
JS性能优化实现方法及优点进行
2020/08/30 Javascript
[05:40]DOTA2荣耀之路6:Wings最后进攻
2018/05/30 DOTA
Zabbix实现微信报警功能
2016/10/09 Python
Python基础之getpass模块详细介绍
2017/08/10 Python
TensorFlow中权重的随机初始化的方法
2018/02/11 Python
python读取和保存视频文件
2018/04/16 Python
TensorFlow基于MNIST数据集实现车牌识别(初步演示版)
2019/08/05 Python
在Python中画图(基于Jupyter notebook的魔法函数)
2019/10/28 Python
在pycharm中实现删除bookmark
2020/02/14 Python
Python中flatten( ),matrix.A用法说明
2020/07/05 Python
HTML5适合的情人节礼物有纪念日期功能
2021/01/25 HTML / CSS
美国领先的医疗警报服务:Philips Lifeline
2018/03/12 全球购物
乌克兰时尚鞋子和衣服购物网站:Born2be
2018/05/24 全球购物
高三自我鉴定怎么写
2013/10/19 职场文书
销售副总经理岗位职责
2013/12/11 职场文书
自我鉴定写作要点
2014/01/17 职场文书
幼儿园保育员岗位职责
2014/04/13 职场文书
领导班子专题民主生活会情况想汇报
2014/09/30 职场文书
孙振耀退休感言
2015/08/01 职场文书