Master
Модератор
update 11.12.2016
Список IP госорганов обновлен.
Обновлены скрипты.
Появился скрипт для тестирования (test.php, пример здесь).
Добавлена админка для кодировки windows-1251 (файл в архиве admin_win1251.php).
update 07.10.2016
Скрипт и список IP госорганов обновлены.
Появилась админка.
------
Подобный скрипт уже существует - Котозапрет от Antizapret.info. Их скрипт проверяет IP по диапазонам ip-адресов госорганов и выводит фотографию котика, если вхождение найдено. Но Котозапрет нам показался не оптимальным, поэтому мы решили сделать собственный.
Что же не так в Котозапрете?
Во-первых, мало ip-адресов - у нас получилось на порядок больше. Во-вторых, алгоритм не оптимальный, что может тормозить работу посещаемых сайтов. И в-третьих, сомнительное решение повысить производительность скрипта за счет кэширования госоргановских IP.
	
	
	
		
Может есть смысл заносить в лог госоргановские IP, чтобы понимать, какие органы проверяют сайт, но кэшировать с целью снижения нагрузки - сомнительная затея, ведь мы ориентированы на пользователей, а не на госорганы, зачем для них нам нагрузку снижать.
Непонятно также почему частота обновления файла с данными выставлена в 30 минут, когда списки диапазонов обновляются раз в паятилетку. Мы выставили примерно в 5 дней, но можно и реже.
Скрипт Роскомсос.
Скрипт реализован в виде класса Roscomsos, который только определяет принадлежность IP к госорганам. В случае попадания можете показывать котиков или Сашу Грей, а лучше отдать измененный, незапрещенный контент. Например, если у вас киносайт, то госорганам вы можете показывать трейлеры фильмов, а остальным пользователям фильмы целиком.
В целях повышения производительности скрипт использует два файла: в одном файле собраны только первые два байта госовских айпи, а в другом полный список всех известных диапазонов. Проверка осуществляется в три этапа: сначала ищем совпадение двух байтов IP в первом файле (большинство пользователей отфильтруется уже на этом этапе, что снизит нагрузку на сервер), затем, если IP похож на госовский, то ищем первые три байта в полном списке, далее, если совпадений не найдено, IP ищется в диапазонах, но не во всех, а только с такими же первыми двумя байтами.
Сам класс:
	
	
	
		
Этот код нужно вставить на сайте (в файл index.php).
	
	
	
		
Не забудьте установить права на запись для следующих файлов: gosip.data, gosip_short.data, gosiplog.txt.
Файл с актуальными диапазонами IP госорганов и Роскомнадзора теперь находится по ссылке: https://roscenzura.com/roscomsos/gosip.txt.
Для получения дополнительной информации пишите нам в ЛС.
Ссылка на скачивание скрипта: https://roscenzura.com/roscomsos/roscomsos.zip
Тестирование: https://roscenzura.com/roscomsos.php
								Список IP госорганов обновлен.
Обновлены скрипты.
Появился скрипт для тестирования (test.php, пример здесь).
Добавлена админка для кодировки windows-1251 (файл в архиве admin_win1251.php).
update 07.10.2016
Скрипт и список IP госорганов обновлены.
Появилась админка.
------
Подобный скрипт уже существует - Котозапрет от Antizapret.info. Их скрипт проверяет IP по диапазонам ip-адресов госорганов и выводит фотографию котика, если вхождение найдено. Но Котозапрет нам показался не оптимальным, поэтому мы решили сделать собственный.
Что же не так в Котозапрете?
Во-первых, мало ip-адресов - у нас получилось на порядок больше. Во-вторых, алгоритм не оптимальный, что может тормозить работу посещаемых сайтов. И в-третьих, сомнительное решение повысить производительность скрипта за счет кэширования госоргановских IP.
		PHP:
	
	    /*
  * @brief производится загрузка базы и запись ip адреса блокируемого при включеном файловом кэшировании (с целью снижения нагрузки на разбор массива, так как is_file быстрее)
     *
     */
    public function parseBase($ip, $store = 0) {
        $networks = explode("::", file_get_contents($this->cache_path . "/" . $this->cache_file));
        foreach ($networks AS $network) {
            if (self::match($network, $ip)) {
                if ($store)
                    file_put_contents($this->cache_path . "/" . $ip, "");
                self::goBlock();
            }
        }
    }
	Непонятно также почему частота обновления файла с данными выставлена в 30 минут, когда списки диапазонов обновляются раз в паятилетку. Мы выставили примерно в 5 дней, но можно и реже.
Скрипт Роскомсос.
Скрипт реализован в виде класса Roscomsos, который только определяет принадлежность IP к госорганам. В случае попадания можете показывать котиков или Сашу Грей, а лучше отдать измененный, незапрещенный контент. Например, если у вас киносайт, то госорганам вы можете показывать трейлеры фильмов, а остальным пользователям фильмы целиком.
В целях повышения производительности скрипт использует два файла: в одном файле собраны только первые два байта госовских айпи, а в другом полный список всех известных диапазонов. Проверка осуществляется в три этапа: сначала ищем совпадение двух байтов IP в первом файле (большинство пользователей отфильтруется уже на этом этапе, что снизит нагрузку на сервер), затем, если IP похож на госовский, то ищем первые три байта в полном списке, далее, если совпадений не найдено, IP ищется в диапазонах, но не во всех, а только с такими же первыми двумя байтами.
Сам класс:
		PHP:
	
	<?PHP
class Roscomsos {
    public $time_update='5'; // Обновляем список каждые 5 дней, можно поставить и 10 и 30
  //  public $url_update='https://roscenzura.com/roscomsos/'; // Если урл не указан, то обновление данных не происходит
    public $file_ip='gosip.data'; // Полный массив данных
    public $file_short='gosip_short.data'; // Сокращенный массив данных с первыми двумя байтами госовских IP для предварительной проверки
    public $file_log='gosiplog.txt'; // Закомментируйте, если не хотите логировать IP госорганов
    public $d; // директория скрипта
    public $ip;
    public function __construct()
    {
        $this->d = $_SERVER['DOCUMENT_ROOT'].'/roscomsos/'; // не забудьте назначить права 0777 на папку
    }
    public function update_data()
    {
     $file=$this->d.$this->file_ip;
     if ($this->url_update=='') return;
     if (!is_file($file) or (filemtime($file)+ $this->time_update * 24 * 3600 < time()) )
     {
       file_put_contents($file, file_get_contents($this->url_update.$this->file_ip));
        file_put_contents($this->d.$this->file_short, file_get_contents($this->url_update.$this->file_short));
       if (!is_file($file)) die('Установите права для записи на папку ' . $this->d);
     }
    }
    // Ищем IP в диапазоне, например, таком 155.39.133.161-155.39.133.174
    public function find_range($range)
    {
    $range=explode('-', $range);
    if (!isset($range[1])) return false;
    return ( ip2long($this->ip)>=ip2long($range[0]) && ip2long($this->ip)<=ip2long($range[1]) );
    }
    // Ищем IP в подсети, например, 151.224.182.0/23
    public function find_subnet($range)
    {
     list ($subnet, $bits) = explode('/', $range);
     $ip = ip2long($this->ip);
     $subnet = ip2long($subnet);
     $mask = -1 << (32 - $bits);
     $subnet &= $mask;
     return ($ip & $mask) == $subnet;
    }
    // Проверяем IP в три этапа
    public function check_ip($ip=false, $log=true)
    {
     if ($ip) $this->ip=$ip;
     if ($this->ip != long2ip(ip2long($this->ip))) return; // Если IP6, отметаем
     if (!is_file($this->d.$this->file_short)) $this->update_data(); else if( date("d") % $this->time_update == 0) $this->update_data(); // Если файл данных не найден или давно не обновлялся - обновляем
     $bytes=explode('.', $this->ip);
    // var_dump(file_get_contents($this->d.$this->file_short));
     if (strpos(file_get_contents($this->d.$this->file_short), '|'.$bytes[0].'.'.$bytes[1].'|' )===false) return false; // Ищем первые два байта в первом списке, большинство негосовских IP отфильтруется здесь
     $file=file_get_contents($this->d.$this->file_ip);
  
     if (strpos($file, '|'.$bytes[0].'.'.$bytes[1].'.'.$bytes[2].'.')!==false) return $this->logGosIp($log);  // Жесткий режим блокировки: если три байта совпадают, блокировать
     $find_m='||'.$bytes[0].'.'.$bytes[1].'||';
     // Берем диапазон только с такими же первыми двумя байтами, чтобы не прогонять по всему списку
     $file=substr($file, strpos($file, $find_m)+strlen($find_m) );
     $file=substr($file, 0, strpos($file, '||') );
     // Проверяем вхождение IP в диапазоны
     $ip_c=explode('|', $file); $check=false;
     foreach ($ip_c as $i=>$gip)
     {
        if (strpos($gip, '/')) $check=$this->find_subnet($gip); else $check=$this->find_range($gip);
        if ($check==true) return $this->logGosIp($log);
     }
    }
    // Сохраняем IP госорганов
    public function logGosIp($log=false)
    {
        if ($log) file_put_contents($this->d.$this->file_log, $this->ip.chr(13).chr(10), FILE_APPEND);
        return true;
    }
}
?>
	
		PHP:
	
	require_once($_SERVER['DOCUMENT_ROOT']."/roscomsos/roscomsos.php");
$Roscomsos=new Roscomsos();
$check_gos_ip=$Roscomsos->check_ip($_SERVER['REMOTE_ADDR']); // Если true, то IP вероятно принадлежит диапазону адресов госорганов
if ($check_gos_ip)
{
   echo 'Доступ на сайт запрещен';
}
	Файл с актуальными диапазонами IP госорганов и Роскомнадзора теперь находится по ссылке: https://roscenzura.com/roscomsos/gosip.txt.
Для получения дополнительной информации пишите нам в ЛС.
Ссылка на скачивание скрипта: https://roscenzura.com/roscomsos/roscomsos.zip
Тестирование: https://roscenzura.com/roscomsos.php
								
									Последнее редактирование модератором: