php获取真实IP

最近在项目中看到了一段别人写的获取真实IP的代码,特意把这部分的知识记录下,部分内容来源于网络检索,若有侵权请联系我删除。

因为存在IP欺骗和代理问题,所以获取客户端的IP的真实性不能百分百准确。
1、没有使用代理的情况
REMOTE_ADDR = 客户端IP
HTTP_X_FORWARDED_FOR = 没数值或不显示
2、使用透明代理的情况
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_X_FORWARDED_FOR = 客户端真实 IP (经过多个代理服务器时,这个值类似:221.5.252.160, 203.98.182.163, 203.129.72.215)
这类代理服务器还是将客户端真实的IP发送给了访问对象,无法达到隐藏真实身份的目的.
3、使用普通的匿名代理
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_X_FORWARDED_FOR = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215)
这种情况下隐藏了客户端的真实IP,但是向访问对象透露了客户端是使用代理服务器访问它们的.
4、使用欺骗性代理服务器
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来欺骗它.
5、使用高级匿名代理服务器
REMOTE_ADDR = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 没数值或不显示,也可能是unknown

PHP 里用来获取客户端 IP 的变量有这些:
$_SERVER['HTTP_CLIENT_IP'] 未必服务器都实现了。客户端可以伪造。
$_SERVER['HTTP_X_FORWARDED_FOR'] 是有标准定义,用来识别经过 HTTP 代理后的客户端 IP 地址,格式:clientip,proxy1,proxy2。
$_SERVER['REMOTE_ADDR'] 是最后一个跟服务器握手的 IP,可能是用户的代理服务器,也可能是自己的反向代理。客户端不能伪造。
 
姑且写个demo,应该也不会特别准确
function get_real_ip()
{
    $ip = false;
    if (!empty($_SERVER["HTTP_CLIENT_IP"]) && strcasecmp($_SERVER["HTTP_CLIENT_IP"], "unknown")) {
        $ip = filter_var($_SERVER["HTTP_CLIENT_IP"], FILTER_VALIDATE_IP);
    } else if (!$ip && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) && strcasecmp($_SERVER["HTTP_X_FORWARDED_FOR"], "unknown")) {
        $ips = explode(", ", $_SERVER['HTTP_X_FORWARDED_FOR']);
        $ip = $ips[0];
        //局域网ip网段
        $re_str = "/^((192\.168|172\.([1][6-9]|[2]\d|3[01]))(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}|10(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){3})$/";
        if (!filter_var($ip, FILTER_VALIDATE_IP) || preg_match($re_str, $ip)) {
            $ip = false;
        }
    }
    $ip = $ip ? $ip : filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP);
    return !$ip ? '' : $ip;
}

 

 

posted @ 2023-09-11 09:38  carol2014  阅读(120)  评论(0编辑  收藏  举报