黑帽联盟

 找回密码
 会员注册
查看: 1235|回复: 0
打印 上一主题 下一主题

[php] PHP获取用户客户端真实IP的解决方法

[复制链接]

852

主题

38

听众

3175

积分

白金VIP

Rank: 8Rank: 8

  • TA的每日心情
    开心
    2024-3-7 12:52
  • 签到天数: 1538 天

    [LV.Master]伴坛终老

    获取客户端ip其实不是个简单的活儿,因为存在Ip欺骗,和代理问题,所以获取客户端的IP的真实性会打折扣的,不能百分百准确.但是我们还是尽量找一个比较完善的获取客户端真正ip方法.使用php获取IP的方法能找到很多.
    1. function getIp(){
    2. if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
    3. $ip = getenv("HTTP_CLIENT_IP");
    4. else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
    5. $ip = getenv("HTTP_X_FORWARDED_FOR");
    6. else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
    7. $ip = getenv("REMOTE_ADDR");
    8. else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
    9. $ip = $_SERVER['REMOTE_ADDR'];
    10. else
    11. $ip = "unknown";
    12. return($ip);
    复制代码
    现在需要对这段代码进行解释,这里用到了两个函数,getenv()和strcasecmp(),前一个函数获取得系统的环境变量,如果能取到值,则返回该值,不能则返回false.
    $_SERVER是服务器超级全局变量数组,用$_SERVER['REMOTE_ADDR']同样可以获取到客户端的IP地址.二者的区别在于,getenv不支持IIS的isapi方式运行的php.
    strcasecmp(string1,string2)字符串函数的用法是把string1和string2进行比较,如果相等返回0,如果string1大于string2,返回大于0的数,小于则返回小于0的数.
    函数先使用客户IP,如果不成立尝试用代理的方法,如果不行,再使用REMOTE_ADDR.
    还看到过一个检测IP更详细的方法,考虑了IP的欺骗,和多重代理代码.方法相类似.
    1. function getip() {
    2. $unknown = 'unknown';
    3. if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown) ) {
    4. $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    5. } elseif ( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown) ) {
    6. $ip = $_SERVER['REMOTE_ADDR'];
    7. }
    8. /*
    9. 处理多层代理的情况
    10. 或者使用正则方式:$ip = preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown;
    11. */
    12. if (false !== strpos($ip, ','))
    13. $ip = reset(explode(',', $ip));
    14. return $ip;
    15. }
    复制代码
    一、没有使用代理服务器的PHP获取客户端IP情况:
    REMOTE_ADDR = 客户端IP
    HTTP_X_FORWARDED_FOR = 没数值或不显示

    二、使用透明代理服务器的情况:Transparent Proxies
    REMOTE_ADDR = 最后一个代理服务器 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_X_FORWARDED_FOR = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215)
    这种情况下隐藏了客户端的真实IP,但是向访问对象透露了客户端是使用代理服务器访问它们的.

    四、使用欺骗性代理服务器的情况:Distorting Proxies
    REMOTE_ADDR = 代理服务器 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_X_FORWARDED_FOR = 没数值或不显示
    无论是REMOTE_ADDR还是HTTP_FORWARDED_FOR,这些头消息未必能够取得到,因为不同的浏览器不同的网络设备可能发送不同的IP头消息.因此PHP使用$_SERVER["REMOTE_ADDR"] 、$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值可能是空值也可能是“unknown”值.

    帖子永久地址: 

    黑帽联盟 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与黑帽联盟享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和黑帽联盟的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、黑帽联盟管理员和版主有权不事先通知发贴者而删除本文

    勿忘初心,方得始终!
    您需要登录后才可以回帖 登录 | 会员注册

    发布主题 !fastreply! 收藏帖子 返回列表 搜索
    回顶部