PHP get real IP (proxy detection)

谁都会走 提交于 2019-11-30 04:18:16

If the proxy sends a header then you can fetch the original IP of the client. If the proxy doesn't, then you can't. Unfortunately (Or maybe fortunately depending on your perspective) it's as simple as that.

What I did at our intranet, is redirect "intranet.mydomain.com" to "intranet" on the webserver, the latter doesn't use the proxy due to out internal network/DNS configuration ... Don't know what you want to do, but this may be useful.

You can also set an exclude list in the browser...

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'];
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!