Фильтрация трафика по реестру Роскомнадзора.

Не так давно в нашей любимой стране начали заставлять не пускать пользователей оператора связи на отдельные сайты. Оставим в стороне дискуссию о целесообразности данного мероприятия и сосредоточимся на выполнении данных требований.

И так, после долгих размышлений на тему фильтрации, производительности (если пустить в фильтр весь http-трафик, то фильтрация должна осуществляться на скоростях более гигабита в секунду), была выбрана следующая схема :

Схема построения

Трафик HTTP и HTTPS, выходящий из облака нашей сети ( в примере VLAN90) через наш бордер CISCO, мы будем сравнивать с ACL, содержащим IP-адреса, извлеченные из списка Роскомнадзора. В случае совпадения, мы отправляем трафик по протоколу WCCP (Web Cache Communication Protocol) на сервер(а)  SQUID. Данная схема позволит нам избежать анализа всего трафика и анализировать только тот, который идет на заявленные IP, что не может не сказаться положительно на общей производительности системы. Из минусов данной связки следует, что допустим если внесенный в реестр ресурс с IP=3.3.3.3, доменом=bad.xxx и URL=http://www.bad.xxx/1.jpg переезжает на другой IP, то фильтр работать не будет. Но с другой стороны актуализация списков блокировки, это не наша проблема. Данный подход позволит нам с одной стороны не тратится на дорогостоящие системы анализа проходящего трафика, с другой стороны исключить «пионерский» подход блокировки всего ресурса по IP, а блокировать только указанный в реестре Роскомнадзора контент. Связку по WCCP лучше поднимать на приватных адресах, что бы не писать лишние ACL в SQUID .

И так, приступим к реализации. Для начала нам надо вытащить электронную подпись с рутокена, полученного в роскомнадзоре. Для этого воспользуемся вот это вот утилитой, и экспортируем подпись в формате PKSC#12.

P12FromGostCSP

Если экспорт удался, то можем перейти далее к построению системы. Если экспорт не удался (у меня в одном случае из четырех было именно так), то автоматическая загрузка реестра Роскомнадзора будет не доступна, и Вам придется файл качать и выкладывать реестр руками.

Берем любой сервер на базе FreeBSD (я предпочитаю данную ОС, но ничего не мешает Вам сделать по образу и подобию на любой *NIX машине), на котором мы будем заниматься загрузкой базы Роскомнадзора, ее обработкой и у меня этот же сервер как правило обеспечивает анализ и фильтрацию контента. Так как системный OpenSSL в FreeBSD не поддерживает шифрование ГОСТ, ставим свежую версию из портов. Это не затрагивает работоспособность всей системы, и портовый OpenSSL прекрасно существует параллельно системному :

# which openssl
/usr/bin/openssl
# openssl version
OpenSSL 0.9.8y 5 Feb 2013
# /usr/local/bin/openssl version
OpenSSL 1.0.1e 11 Feb 2013
#

Находим файл /usr/local/openssl/openssl.cnf и пишем в конец файла :

[openssl_def]
engines = engine_section
[engine_section]
gost = gost_section
[gost_section]
default_algorithms = ALL
engine_id = gost
#dynamic_path = /usr/local/lib/engines/libgost.so
CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet

В начало этого файла пишем :

openssl_conf = openssl_def

Копируем на сервер наш сертификат в формате PKSC#12 и конвертируем его в формат PEM :

/usr/local/bin/openssl pkcs12 -in p12.pfx -out cert.pem -nodes -clcerts

Подготавливаем структуру директорий для работы наших скриптов и копируем туда сконвертированный сертификат:

mkdir /var/db/zapret-info/
mkdir /var/db/zapret-info/cfg
mkdir /var/db/zapret-info/arch
cp cert.pem /var/db/zapret-info/cfg/
mkdir /tftpboot

Создаем файл запрос в соответствии с требованиями Роскомнадзора (где данные между тэгами изменены на данные вашей фирмы) :

echo '<operatorName>ООО "РОГА И КОПЫТА"</<operatorName>' > /var/db/zapret-info/cfg/request.xml
echo '<inn>00XXXXXXXXXX</inn>' >> /var/db/zapret-info/cfg/request.xml 
echo '<ogrn>XXXXXXXXXXXXX</ogrn>' >> /var/db/zapret-info/cfg/request.xml
echo '<email>info@rogaikopita.ru</email>' >> /var/db/zapret-info/cfg/request.xml

В зависимости от раскладок системной консоли полученный файл /var/db/zapret-info/cfg/request.xml необходимо сконвертировать в кодировку WINDOWS-1251.

Скачиваем нижеприложенные скрипты. Скрипт download.pl был найден мной на просторах Интернета и  упрощен, в оригинале он был чуток более замороченный. Задача данного скрипта — создать, подписать и отправить запрос в Роскомнадзор и загрузить реестр после отправки.

download.pl

В задачи скрипта xml-paser.pl входит обработка полученного реестра и подготовка двух файлов — block.acl и denied.conf. Файл block.acl содержит правила для нашей cisco и как правило загружается по tftp. Файл denied.conf содержит URL для редиректора SQUID. Скрипт анализирует, префикс http или https указан в URL и в соотвествии с данным префиксом генерирует ACL для CISCO. Для ресурсов с множественныйми IP и/или URL, скрипт генерирует два ACL — как по порту www, так и по порту 443 (так как реестр сам по себе сырой, и такие записи не предусматривают однозначной трактовки какой протокол на каком IP использовать).

 xml-parser.pl

В начале данного файла надо установить значение переменных, в соответсвии с Вашими настройками. Переменная $tftp_root должна быть установлена в соответствии с настройками Вашего tftp-сервера, переменная $query_ip должна содержать  IP-адрес интерфейса сервера, через который посылается в Интернет фильтрованный трафик, для исключения образования кольцевой обработки запросов.

Для работы скриптов нам требуется установить следующие порты :

cd /usr/ports/net/p5-SOAP-Lite; make install 
cd /usr/ports/converters/p5-MIME-Base64; make install
cd /usr/ports/sysutils/p5-Sys-Syslog; make install
cd /usr/ports/textproc/p5-XML-Simple; make install
cd /usr/ports/devel/p5-Data-Dumper; make install
cd /usr/ports/converters/p5-Encode; make install
cd /usr/ports/net/p5-URI; make install
cd /usr/ports/converters/p5-Text-Iconv; make install

На данном этапе мы реализовали получение и разбор реестра Роскомнадзора в требуемый для нас вид. Переходим к настройке нашего железа.

Конфигурируем CISCO для работы с сервером SQUID по WCCP. Группа 0 используется для отсылки http-трафика, группа 70 — для отсылки https-трафика.

ip wccp 0 redirect-list WCCP_REDIRECT group-list 10 accelerated
ip wccp 70 redirect-list WCCP_REDIRECT group-list 10 accelerated
access-list 10 remark +++ WCCP_SQUID_PROXY +++
access-list 10 permit 1.1.2.2

Создаем пользователя, который будет грузить access-листы и настраиваем rsh.

username blocker privilege 15 password password
no ip rcmd domain-lookup
ip rcmd rsh-enable
ip rcmd remote-host blocker 1.1.2.2 root enable

Ставим из портов SQUID. При выборе опций обязательно контролируем, что WCCP и WCCP2 протоколы включены. Создаем конфиг (в примере для версии 3.2) /usr/local/etc/squid/squid.conf

http_port 1.1.2.2:9090
http_port 1.1.2.2:3128 transparent
https_port 1.1.2.2:3129 transparent ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/usr/local/etc/squid/squid.pem
always_direct allow all
ssl_bump allow all
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
sslcrtd_program /usr/local/libexec/squid/ssl_crtd -s /var/squid/ssl_db -M 4MB
icp_port 0
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
cache deny QUERY
acl apache rep_header Server ^Apache
cache_mem 1 MB
cache_swap_low 90
cache_swap_high 95
maximum_object_size 1 KB
maximum_object_size_in_memory 50 KB
cache_replacement_policy heap LFUDA
cache_dir ufs /var/squid/cache 1 1 1 no-store
logfile_rotate 7
dns_nameservers 8.8.8.8 8.8.4.4
hosts_file /etc/hosts
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern . 0 20% 4320
quick_abort_min 0 KB
quick_abort_max 0 KB
half_closed_clients off
acl purge method PURGE
acl CONNECT method CONNECT
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443 # https
acl Safe_ports port 1025-65535 # unregistered ports
http_access allow manager localhost
http_access deny manager
http_access allow purge localhost
http_access deny purge
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost
http_access allow all
http_reply_access allow all
icp_access allow all
cache_mgr info@my.domain
cache_effective_group proxy
memory_pools off
log_icp_queries off
cachemgr_passwd q1w2e3r4 all
client_db off
buffered_logs on
wccp2_router 1.1.2.1
wccp2_forwarding_method 2
wccp2_return_method 2
wccp2_assignment_method 2
wccp2_service dynamic 0
wccp2_service_info 0 protocol=tcp flags=dst_ip_hash,dst_port_hash priority=240 ports=80
wccp2_service dynamic 70
wccp2_service_info 70 protocol=tcp flags=dst_ip_hash,dst_port_hash priority=240 ports=443
wccp2_address 1.1.2.2
redirect_program /usr/local/etc/squid/redirector.pl
url_rewrite_children 20 startup=10 idle=1 concurrency=0

Обратите внимание на строки wccp2_router и wccp2_address. Соответственно тут должны быть адреса на интерфейсе со стороны CISCO и SQUID. Трафик на сервер SQUID посылается путем замены MAC-адреса, без организации дополнительного GRE-тунеля.

Скрипт редиректора копируется в  /usr/local/etc/squid/:

redirector.pl

В начале данного файла мы должны установить значение переменных $db_path, $block_url, $log_file в соответствии с Вашими настройками. $db_path содержит путь до директории с файлом denied.conf и serial, $block_url должен содержать адрес страницы на которую мы перекидываем клиента при блокировании ресурса.

Что бы анализировать HTTPS-трафик, нам нужно сгенерировать самоподписанный сертификат:

cd /usr/local/etc/squid/
openssl req -new -newkey rsa:1024 -days 365 -nodes -x509 -keyout squid.pem -out squid.pem

Запускаем SQUID. Если все настроено верно, то на CISCO по команде sh ip wccp, мы увидим что-то похожее на такое:

#sh ip wccp
Global WCCP information:
 Router information:
 Router Identifier: 1.1.1.1
 Protocol Version: 2.0
Service Identifier: 0
 Number of Service Group Clients: 1
 Number of Service Group Routers: 1
...
 Redirect access-list: WCCP_REDIRECT
...
Service Identifier: 70
 Number of Service Group Clients: 1
 Number of Service Group Routers: 1
...
 Redirect access-list: WCCP_REDIRECT
...

Если соединение WCCP2 установилось, мы может попробовать запустить трафик на SQUID. Для этого в ipfw мы должны поставить правила переадресации трафика :

ipfw add 100 fwd 1.1.2.2,3128 tcp from not me to any dst-port 80 via ${wccp_intf} in
ipfw add 100 fwd 1.1.2.2,3129 tcp from not me to any dst-port 443 via ${wccp_intf} in

(где ${wccp_intf} — интерфейс для обмена wccp-трафиком)

На CISCO запускаем трафик на SQUID :

conf t
int vlan90
 ip wccp 0 redirect in
 ip wccp 70 redirect in

Для загрузки acl в CISCO поднимаем tftp-сервер, раскомментировав соответствующую строку в /etc/inetd.conf и перезапустив inetd . Проверяем загрузку правил по rsh, выполнив из консоли сервера :

( sleep 2 ; echo '' ; sleep 15 ) | rsh -l blocker 1.1.2.1 copy tftp://1.1.2.2/block.acl running-config ;

Проверяем в CISCO что правила загрузились. Если все отлично, создаем скрипт, который мы включаем в на выполнение в крон :

#!/bin/sh
. /var/db/zapret-info/cfg/loader.conf
/scripts/download.pl

if [ $? -eq 0 ];
then
 /scripts/xml-parser.pl
else 
 exit 254 ;
fi
if [ $? -eq 0 ];
then 
 ( sleep 2 ; echo '' ; sleep 15 ) | rsh -l blocker ${cisco_address} copy tftp://${tftp_address}/block.acl running-config ;
else 
 exit 253 ;
fi
exit 0;

Создадим файл конфигурации скрипта в /var/db/zapret-info/cfg/loader.conf

echo 'cisco_address="1.1.2.1"' > /var/db/zapret-info/cfg/loader.conf
echo 'tftp_address="1.1.2.2"' >> /var/db/zapret-into/cfg/loader.conf

Если Вы все сделали без ошибок и поняли идею, Вы получили работающий полностью в автоматическом режиме сервер фильтрации трафика, синхронизированный с реестром Роскомнадзора, фильтрующий ВСЕ (!) ресурсы внесенные в реестр, в том числе URI написанные на русском языке и URI на защищенных SSL ресурсах.

 

Фильтрация трафика по реестру Роскомнадзора.: 23 комментария

  1. Запускаю download.pl — результат:
    29-01-2014 14:07:45 error request файл запроса не соответствует требуемому формату
    29-01-2014 14:07:45 codestring file not found
    В чем может быть проблема?

    • с достаточной, он примитивный и согласно конфига запускается в 10 потоков… вопрос скорее будет не в скрипте, так как ему передаются 4 параметра и ожидается один ответ, а в производительности платформы под сквид…

  2. Как решается проблема с HTTPS-сайтами, которые требуют проверки клиентского сертификата?

    • Не тестировал, так как не встречалось заблокированных в реестре сайтов, которые имеют те же ip-адреса что и сайт с которым требуется работать с авторизацией по сертификату. Но как я подозреваю ни каких проблем быть в такой ситуации не должно…

  3. Уведомление: Фильтрация трафика по реестру Роскомнадзора. Изменения 1 августа 2014 года. | Записки администратора

  4. Подскажите в чем может быть проблема? Запросы скриптом создаются и выгружается реестр, но при этом
    1codestring file not foundroot@reestr:/usr/local/openssl/zaproz # perl script2.pl 0
    print() on closed filehandle XMLREQ at script2.pl line 34.
    print() on closed filehandle XMLREQ at script2.pl line 35.
    print() on closed filehandle XMLREQ at script2.pl line 36.
    print() on closed filehandle XMLREQ at script2.pl line 37.
    print() on closed filehandle XMLREQ at script2.pl line 38.
    got new LastDumpDate version 1414753500000, try send requestunable to load signing key file
    12265:error:0606F076:digital envelope routines:EVP_PKCS82PKEY:unsupported private key algorithm:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/evp/evp_pkey.c:337:TYPE=GOST R 34.10-2001
    12265:error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/pem/pem_pkey.c:125:
    root@reestr:/usr/local/openssl/zaproz # perl script2.pl 1
    Wide character in print at script2.pl line 90.

    • По поводу :
      12265:error:0606F076:digital envelope routines:EVP_PKCS82PKEY:unsupported private key algorithm:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/evp/evp_pkey.c:337:TYPE=GOST R 34.10-2001
      12265:error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/pem/pem_pkey.c:125:
      root@reestr:/usr/local/openssl/zaproz # perl script2.pl 1
      Wide character in print at script2.pl line 90.

      Вы явно не поставили openssl из портов, а пытаетесь подписывать системным.

      Что касается предыдущих ошибок — явно не хватает прав/не создана структура каталогов для работы скрипта…

      А вообще странно что в принципе что-то выгружается при таких ошибках. И номера строк в которых выпадает ошибка отличается от номеров строк в исходниках, попробуйте скачать заново скрипты из второй часть данной статьи. ( http://www.ps-ax.ru/2014/08/27/фильтрация-трафика-по-реестру-роском/ )

  5. Сеть небольшая, до гигабита/с на выходе ещё расти и расти. Циски нет. В этой связи нубский вопрос: нет ли описания настройки прозрачного прокси без редиректов на циску? А то в вопросе плаваю и адаптировать статью под свой случай затрудняюсь.

    • В вашем случае можно обойтись и без cisco, надо всего лишь на freebsd организовать forward портов на squid по таблицам в которые загружать списки ip адресов. Но производительность будет не очень

  6. Юрий подскажите а как заставить редиректор не быть чувствителен к регистр букв, а то в списках ркн в поле url иногда бывают ошибки, записи могут начинаться с заглавной буквы а для редиректора это уже не тот url.

    • надо в скрипте xml-parser.pl сделать приведение к нижнему регистру url, полученных из роскомнадзора…
      править по тексту sub _url {
      и перед print сделать приведение $url к нижнему регистру.

    • А вообще если честно моя позиция такая — база данных с ошибками и актуальной информацией эта их проблема, они за это наши деньги получают 🙂 потому подход чисто формальный — как внесено, так и проверяем 🙂

  7. Да я сперва тоже так подумал что можно и url сразу преобразовать в нижний регистр, но тогда youtube-ские url-ы будут работать не корректно, то есть страница блокировки не будет грузится. А по поводу эта их проблема я конечно согласен, но зачем лишние разбирательства, тем более что в основном они, судя по судебной практики, выигрывают дела.
    И всё же может можно как-то заставить squid не обращаться внимание на регистр, ведь есть же ключ при acl url_regex -i.

  8. Юрий подскажите пожалуйста у меня ещё один вопрос, почему то url со знаком # тоже не блокируются

  9. Нашёл временное решение, отрезать от url всё что после знака # вместе с этим знаком, и url блокируется.

  10. вообщето отрезать диез — это единственный спосособ обработать такой запрос. В урле ходящем по сети не бывает #. диез это чисто браузерная часть. А дальше браузер сделает или переход по ссылке или какой локальный скрипт типа аякса. Да, по значению после # браузер может чтото дополнительно загрузить, но без анализа кода страницы мы никогда не узнаем что именно. Посему (если нет желания с проверяющими или в суде искать в тспдампе диезы и доказывать что верблюды те кто такой урл ляпнул в базу) то только резать.

  11. Добрый День.
    При выполнение download.pl на FreeBsd 10.3
    Получаю
    13-05-2016 09:19:47 error request файл запроса не соответствует требуемому формату
    13-05-2016 09:19:47 codestring file not found

    либо

    nxbit@zapret:/var/db/zapret-info# perl download.pl
    Use of uninitialized value $sendresult[0] in string eq at download.pl line 66.
    Use of uninitialized value $sendresult[0] in string eq at download.pl line 68.
    13-05-2016 09:26:30 codestring file not found

    При этом в ручном режиме теми же файлами все выгружается отлично.
    И можно ли как то добавить в cron perl файл?

    Спасибо.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *