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设计模式之命令模式的应用详解
May 21 PHP
mcrypt启用 加密以及解密过程详细解析
Aug 07 PHP
PHP缓存机制Output Control详解
Jul 14 PHP
PHP实现支持SSL连接的SMTP邮件发送类
Mar 05 PHP
php实现模拟登陆方正教务系统抓取课表
May 19 PHP
基于CakePHP实现的简单博客系统实例
Jun 28 PHP
php实现zip文件解压操作
Nov 03 PHP
CI(CodeIgniter)框架实现图片上传的方法
Mar 24 PHP
关于php 高并发解决的一点思路
Apr 16 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
Aug 20 PHP
PHP中16个高危函数整理
Sep 19 PHP
Laravel框架实现即点即改功能的方法分析
Oct 31 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
提取HTML标签
2006/10/09 PHP
用PHP制作静态网站的模板框架(四)
2006/10/09 PHP
PHP 数据结构 算法 三元组 Triplet
2011/07/02 PHP
php利用curl抓取新浪微博内容示例
2014/04/27 PHP
php获取远程图片并下载保存到本地的方法分析
2016/10/08 PHP
PHP 实现页面静态化的几种方法
2017/07/23 PHP
Thinkphp整合阿里云OSS图片上传实例代码
2019/04/28 PHP
JavaScript Sort 表格排序
2009/10/31 Javascript
选择器中含有空格在使用示例及注意事项
2013/07/31 Javascript
js中的布尔运算符使用介绍
2013/11/20 Javascript
jQuery使用$.get()方法从服务器文件载入数据实例
2015/03/25 Javascript
javascript常用正则表达式汇总
2015/07/31 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
2015/12/09 Javascript
jQuery Dialog对话框事件用法实例分析
2016/05/10 Javascript
JS中使用变量保存arguments对象的方法
2016/06/03 Javascript
Bootstrap实现input控件失去焦点时验证
2016/08/04 Javascript
bootstrap flask登录页面编写实例
2016/11/01 Javascript
Vue2组件tree实现无限级树形菜单
2017/03/29 Javascript
webpack踩坑之路图片的路径与打包
2017/09/05 Javascript
浅谈Webpack打包优化技巧
2018/06/12 Javascript
微信小程序之裁剪图片成圆形的实现代码
2018/10/11 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
Node使用Nodemailer发送邮件的方法实现
2020/02/24 Javascript
python计算最小优先级队列代码分享
2013/12/18 Python
python实现支持目录FTP上传下载文件的方法
2015/06/03 Python
python利用lxml读写xml格式的文件
2017/08/10 Python
python实现切割url得到域名、协议、主机名等各个字段的例子
2019/07/25 Python
基于python实现的百度音乐下载器python pyqt改进版(附代码)
2019/08/05 Python
力学专业毕业生自荐信
2013/11/17 职场文书
扬州个园导游词
2015/02/06 职场文书
西安大雁塔导游词
2015/02/10 职场文书
2015个人简历自我评价语
2015/03/11 职场文书
集结号观后感
2015/06/08 职场文书
小学思品教学反思
2016/02/20 职场文书
python之基数排序的实现
2021/07/26 Python
MyBatis核心源码深度剖析SQL语句执行过程
2022/05/20 Java/Android