获取客户端IP地址分析

2018-02-23 16:34:00
linefo
原创
930


前言


保证能获取客户端真实IP,是不可能的。


目前获取IP的机制主要有两种:

第一种是访问服务器时,服务器记录的访问IP,该IP是真实的,但不代表一定是客户端IP;因为如果经过了代理,就是访问服务器时的代理IP;

第二种是HTTP头部信息的一些值,这些值可以随意伪造。我们假设客户端发起访问请求时,在头部信息写入了其真实的IP,并且即使经过代理时,代理也保留了该值,那么服务器取到的值就是客户端真实IP,但客户端或者代理都可以随意更改该值。


项说明


一般我们通过下面的项去获取IP;


REMOTE_ADDR:该值由服务器提供(所以不可伪造),代表访问服务器的IP,如果是客户端直接访问即客户端真实IP,如果是经过代理访问的,即是直接访问服务器的那个代理的真实IP。

HTTP_CLIENT_IP:该值由客户端或代理提供(可以伪造),指客户端IP

HTTP_X_FORWARDED_FOR:该值由客户端或代理提供(可以伪造),指客户端IP


PS:还有一些其他不常用的项,可能也会记录客户端ip(但值由客户端或代理提供,可以伪造),包括但不限于HTTP_X_FORWARDED、HTTP_X_CLUSTER_CLIENT_IP、HTTP_FORWARDED_FOR、HTTP_FORWARDED


获取思路


先判断是否有HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR这类值;

没有上述值的话,再去判断REMOTE_ADDR的值。

因为非REMOTE_ADDR获得的值可以伪造,所以要将获取的值做合法性判断,比如127.0.0.1这种肯定不是外网IP。


其他


PHP中把上述值放在$_SERVER数组中


介绍一个PHP获取IP的函数:

(filter_var是一个变量过滤函数,通过提供特定的参数可以直接实现IP的合法性判断)


function get_client_ip()
{
    foreach (array(
                'HTTP_CLIENT_IP',
                'HTTP_X_FORWARDED_FOR',
                'HTTP_X_FORWARDED',
                'HTTP_X_CLUSTER_CLIENT_IP',
                'HTTP_FORWARDED_FOR',
                'HTTP_FORWARDED',
                'REMOTE_ADDR') as $key) {
        if (array_key_exists($key, $_SERVER)) {
            foreach (explode(',', $_SERVER[$key]) as $ip) {
                $ip = trim($ip);
                //会过滤掉保留地址和私有地址段的IP,例如 127.0.0.1会被过滤
                //也可以修改成正则验证IP
                if ((bool) filter_var($ip, FILTER_VALIDATE_IP,
                                FILTER_FLAG_IPV4 |
                                FILTER_FLAG_NO_PRIV_RANGE |
                                FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
    }
    return null;
}
文章分类
联系我们
联系人: Mr.Chen
QQ: 185391277