Не так давно в нашей любимой стране начали заставлять не пускать пользователей оператора связи на отдельные сайты. Оставим в стороне дискуссию о целесообразности данного мероприятия и сосредоточимся на выполнении данных требований.
И так, после долгих размышлений на тему фильтрации, производительности (если пустить в фильтр весь 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 ресурсах.
Запускаю download.pl — результат:
29-01-2014 14:07:45 error request файл запроса не соответствует требуемому формату
29-01-2014 14:07:45 codestring file not found
В чем может быть проблема?
Не правильно подготовлен файл request.xml
Проблема с кодировкой была, все теперь работает. Спасибо!
с какой производительностью скрипт редиректора работает?
с достаточной, он примитивный и согласно конфига запускается в 10 потоков… вопрос скорее будет не в скрипте, так как ему передаются 4 параметра и ожидается один ответ, а в производительности платформы под сквид…
Как решается проблема с HTTPS-сайтами, которые требуют проверки клиентского сертификата?
Не тестировал, так как не встречалось заблокированных в реестре сайтов, которые имеют те же ip-адреса что и сайт с которым требуется работать с авторизацией по сертификату. Но как я подозреваю ни каких проблем быть в такой ситуации не должно…
Уведомление: Фильтрация трафика по реестру Роскомнадзора. Изменения 1 августа 2014 года. | Записки администратора
Подскажите в чем может быть проблема? Запросы скриптом создаются и выгружается реестр, но при этом
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/фильтрация-трафика-по-реестру-роском/ )
Сеть небольшая, до гигабита/с на выходе ещё расти и расти. Циски нет. В этой связи нубский вопрос: нет ли описания настройки прозрачного прокси без редиректов на циску? А то в вопросе плаваю и адаптировать статью под свой случай затрудняюсь.
В вашем случае можно обойтись и без cisco, надо всего лишь на freebsd организовать forward портов на squid по таблицам в которые загружать списки ip адресов. Но производительность будет не очень
Юрий подскажите а как заставить редиректор не быть чувствителен к регистр букв, а то в списках ркн в поле url иногда бывают ошибки, записи могут начинаться с заглавной буквы а для редиректора это уже не тот url.
надо в скрипте xml-parser.pl сделать приведение к нижнему регистру url, полученных из роскомнадзора…
править по тексту sub _url {
и перед print сделать приведение $url к нижнему регистру.
А вообще если честно моя позиция такая — база данных с ошибками и актуальной информацией эта их проблема, они за это наши деньги получают 🙂 потому подход чисто формальный — как внесено, так и проверяем 🙂
Да я сперва тоже так подумал что можно и url сразу преобразовать в нижний регистр, но тогда youtube-ские url-ы будут работать не корректно, то есть страница блокировки не будет грузится. А по поводу эта их проблема я конечно согласен, но зачем лишние разбирательства, тем более что в основном они, судя по судебной практики, выигрывают дела.
И всё же может можно как-то заставить squid не обращаться внимание на регистр, ведь есть же ключ при acl url_regex -i.
Юрий подскажите пожалуйста у меня ещё один вопрос, почему то url со знаком # тоже не блокируются
Нашёл временное решение, отрезать от url всё что после знака # вместе с этим знаком, и url блокируется.
ошибка 400 при обработке редиректором
вообщето отрезать диез — это единственный спосособ обработать такой запрос. В урле ходящем по сети не бывает #. диез это чисто браузерная часть. А дальше браузер сделает или переход по ссылке или какой локальный скрипт типа аякса. Да, по значению после # браузер может чтото дополнительно загрузить, но без анализа кода страницы мы никогда не узнаем что именно. Посему (если нет желания с проверяющими или в суде искать в тспдампе диезы и доказывать что верблюды те кто такой урл ляпнул в базу) то только резать.
Спасибо огромное!
Очень помогли скрипты! А то надоело выгружать руками!
Добрый День.
При выполнение 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 файл?
Спасибо.
Здравствуйте! Воспользовались вашим скриптом, но постоянно вылетают ошибки. Не могли бы помочь, а то пока пользуемся этой версией http://www.carbonsoft.ru/products/carbon-reductor-5/?