Ответить в теме

[QUOTE="netcenzure222, post: 4608, member: 362"]

А если я туда запишу "666.666.666.666"? :p

Если уж брать ip, то из HTTP_CF_CONNECTING_IP, предварительно проверив, что запрос исходит от их сервера:


[PHP]if (isset($_SERVER['HTTP_CF_CONNECTING_IP']) and filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP)) {

    $memcacheD = new Memcached;

    $memcacheD->addServer('localhost', 11211);


    $cfips = $memcacheD->get('cloudflare_iplist');

    if(empty($cfips)){

        $c = file_get_contents('https://www.cloudflare.com/ips-v4');

        $cfips = preg_split("#[\r\n]+#u", $c);

        if(!empty($cfips)){

            $memcacheD->set('cloudflare_iplist', $cfips, 3600 * 4);

        }

    }


    if(!empty($cfips)){

        foreach($cfips as $range){

            if(cidr_match($_SERVER['REMOTE_ADDR'], $range)){ // если ip принадлежит CloudFlare

                $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];

                break;

            }

        }

    }

}[/PHP]


Подразумевается, что Memcached установлен, если хостинг не позволяет его активировать, тогда кэш придётся держать на диске. Писал на скорую руку, конечно же

надо заменить file_get_contents на curl и сделать обработку исключений, но это уже каждый сам пусть допиливает для себя.


Чуть не забыл, cidr_match с небольшими поправками:


[PHP]function cidr_match($ip, $range)

{

    $e = explode('/', $range);

    if (empty($e[1])) {

        if ($ip === $range) { // если указан один ip, а не диапазон

            return true;

        }

      

        $ips = explode('-', $range);

        if(!empty($ips[1])){    // если диапазон

            $ip_long = sprintf("%u", ip2long($ip));

            $ip_long_start = sprintf("%u", ip2long($ips[0]));

            $ip_long_end = sprintf("%u", ip2long($ips[1]));

            return ($ip_long >= $ip_long_start and $ip_long <= $ip_long_end);

        }

    } else { // если CIDR

        list ($subnet, $bits) = $e;

        $ip_long = ip2long($ip);

        $subnet = ip2long($subnet);

        $mask = -1 << (32 - $bits);

        $subnet &= $mask;

        return ($ip_long & $mask) == $subnet;

    }

    return false;

}[/PHP]

[/QUOTE]

Сверху