PHP get real IP (proxy detection)

后端 未结 2 1212
我在风中等你
我在风中等你 2020-12-28 23:20

I do get track the \"real\" IP of an user, if he has an proxy wich sends the header of the real IP... does any of have a better solution, or even more headers?

Sinc

2条回答
  •  猫巷女王i
    2020-12-29 00:14

    the regex validation would fail for ipv6 addresses; so I would rather remove that (or try to find a better RegEX).

    also stripos($proxy_header_temp, ':') would lead to a not expected behaivour for example for "::1" (localhost, ipv6).

    my suggestion with mentioned modifications:

    function getIp()
    {
        $proxy_headers = array(
            'CLIENT_IP',
            'FORWARDED',
            'FORWARDED_FOR',
            'FORWARDED_FOR_IP',
            'HTTP_CLIENT_IP',
            'HTTP_FORWARDED',
            'HTTP_FORWARDED_FOR',
            'HTTP_FORWARDED_FOR_IP',
            'HTTP_PC_REMOTE_ADDR',
            'HTTP_PROXY_CONNECTION',
            'HTTP_VIA',
            'HTTP_X_FORWARDED',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED_FOR_IP',
            'HTTP_X_IMFORWARDS',
            'HTTP_XROXY_CONNECTION',
            'VIA',
            'X_FORWARDED',
            'X_FORWARDED_FOR'
        );
        $regEx = "/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/";
        foreach ($proxy_headers as $proxy_header) {
            if (isset($_SERVER[$proxy_header])) {
                /* HEADER ist gesetzt und dies ist eine gültige IP */
                return $_SERVER[$proxy_header];
            } else if (stristr(',', $_SERVER[$proxy_header]) !== false) {
                // Behandle mehrere IPs in einer Anfrage
                //(z.B.: X-Forwarded-For: client1, proxy1, proxy2)
                $proxy_header_temp = trim(
                    array_shift(explode(',', $_SERVER[$proxy_header]))
                ); /* Teile in einzelne IPs, gib die letzte zurück und entferne Leerzeichen */
    
                // if IPv4 address remove port if exists
                if (preg_match($regEx, $proxy_header_temp)
                    && ($pos_temp = stripos($proxy_header_temp, ':')) !== false
                ) {
                    $proxy_header_temp = substr($proxy_header_temp, 0, $pos_temp);
                }
                return $proxy_header_temp;
            }
        }
    
        return $_SERVER['REMOTE_ADDR'];
    }
    

提交回复
热议问题