Как мы получали доступ к базе реестра запрещенных ресурсов

в 7:29, , рубрики: linux, openssl, реестр запрещенных сайтов, Роскомнадзор, метки: , , ,

Приветствем тебя, хабросообщество.

Самой обсуждаемой новостью текущей недели в рунете, безусловно, является принятие закона №139-ФЗ и его последствий. В силу того, что наша компания предоставляет услуги хостинга, нам понадобился доступ к полной базе реестра, чтобы своевременно реагировать на добавление ресурсов наших клиентов в базу. Это связанно с тем, что нам необходимо информировать клиентов о блокировке их ресурсов, ведь в случае, например, блокировки по ip сервера веб-хостинга, могут пострадать и остальные, ни в чем не виноватые, клиенты. К сожалению, получение такого доступа оказалось делом не самым очевидным, поэтому мы хотели бы поделиться результатом прохождения данного квеста.

Как мы получали доступ к базе реестра запрещенных ресурсов

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


В настоящий момент доступ к единому реестру запрещенных ресурсов предполагается двух видов:

  1. Для всех пользователей интернета в виде формы поиска на главной странице реестра. Каждый запрос требует ввода капчи, кроме того, форма, по сути, решает задачу получения информации о блокировке конкретного ресурса, известного заранее, т.к. если сайт забанен по url, то ввод в форму имени домена не даст никакого результата. Пример: ww.xapka.com — пусто, http://www.xapka.com/ — информация о блокировке.
  2. В виде полного дампа базы запрещенных ресурсов в разделе «операторам связи». Есть возможность доступа либо через веб-форму с необходимостью ввода капчи, либо в через SOAP-сервис. Адрес WSDL: www.zapret-info.gov.ru/services/OperatorRequest/?wsdl.

Во втором случае каждый запрос на выгрузку базы необходимо подписывать ЭЦП, в формате PKCS#7 и передавать отвязанную подпись вместе с запросом. В идеале мы представляли себе примерно такой порядок действий: покупаем ЭЦП, берем привычный нам Debian, ставим туда соответствующее ПО для автоматической подписи запросов, пишем скрипт, который общаясь с сервером zapret-info через SOAP формирует запрос, подписывает его, скачивает дамп и рядом эвристических методов проверяет, не относятся ли к нам какие-либо ресурсы из списка.

Казалось бы, все просто, но на деле оказалось несколько сложней и дольше.

ЭЦП

Сервер zapret-info не предоставляет никакой «песочницы», в которой можно было бы протестировать работу скрипта без наличия валидной ЭЦП, поэтому самым первым делом надо озаботиться ее приобритением.

Купить сертификат для создания квалифицированной электронной подписи можно в доверенном удостоверяющем центре. По умолчанию все УЦ для подписывания документов предлагают пользоваться программами из семейства КриптоПРО (КриптоАРМ, cryptcp). К сожалению, пользование этим многообразием программных продуктов омрачает несколько фактов:

  • Если в состав комплекта ЭЦП входит лицензия КриптоПРО — то скорее всего, она предназначена для Windows.
  • Сама КриптоПРО ничего не умеет подписывать, а инструменты, которые умеют — требуют отдельной лицензии и покупки.
  • Возникают еще вопросы про лицензирование (то ли нам нужна лицензия на 1 рабочее место, то ли на 1 сервер).

Поэтому быстрый поиск в интернете навел нас на информацию о том, что с помощью несложных действий с Рутокеном можно научить работать привычный нам OpenSSL. Краткий бриф наших действий такой:

  1. Экспортировать ключ в формате PKCS#12 из криптоконтейнера в Windows с помощью утилиты P12FromGostCSP
  2. Преобразовать его в PEM
  3. Прописать в конфиге openssl.conf параметры
    В самом начале, до секций:

    openssl_conf = openssl_def
    

    В конце новые секции:

    [openssl_def]
    engines=engine_section
    
    [engine_section]
    gost=gost_section
    
    [gost_section]
    engine_id=gost
    default_algorithms=ALL
    
  4. Все готово, теперь можно попробовать создать любой файл и подписать его:
    $ echo "Test" > document.txt
    $ openssl smime -sign -binary -signer ~/sign/gost.crt -inkey ~/sign/gost_nopass.key -outform PEM -in document.txt -out document.txt.sign
    

и проверить его через форму на госуслугах (раздел «отсоединенная, в формате PKCS#7»). Если подпись проходит проверку — можно двигаться дальше.

Формируем запрос

Тут тоже оказалось не все так гладко, как хотелось бы. Все дело в том, что на любую проблему выдается малоинформативное вида: «Ошибка! Файл запроса не соответствует требуемому формату». Но методом проб и ошибок были выяснены следующие требования к файлу запроса:

  • Важен точный порядок следования элементов XML-документа, как в примере.
  • Кодировка xml-документа исключительно windows-1251.
  • XML declaration string должен полностью соответствовать примеру (т.е. нельзя ни порядок аттрибутов менять, ни лишнего пробела между аттрибутами добавлять, ни двойные кавычки на одинарные поменять).

После формирования запроса подписываем его и получаем подпись. Дальше либо отправляем их через метод SOAP sendRequest(), изначально закодировав в base64 содержание файлов запроса и файла подписи, либо отправляем их через форму. Получаем идентификатор запроса, ждем около минуты и проверяем результат обработки запроса (метод getResult(), либо вторая форма на странице запроса).
Кстати, и тут у нас с первого раза не все прошло так гладко. На странице появилась еще одна надпись:

Ошибка! неверный формат ЭП (информация по обратной связи для разрешения проблем приведена в Памятке оператору связи в разделе www.zapret-info.gov.ru/tooperators/)

Тут уже наши догадки закончились и мы написали на почту поддержки: support@rsoc.ru, откуда через несколько часов пришел ответ, что в алгоритм проверки ЭЦП были внесены корректировки и нам нужно попробовать еще раз. Со второго раза проверка прошла успешно и нам был выдан zip-архив, в котором находились дамп реестра и его ЭЦП.

Автоматизация

После всех описанных действий, никаких проблем с автоматизацией у нас не возникло. Алгоритм работы примерно такой:
1. проверяем, не изменился ли таймстамп базы;
2. если изменился — формируем запрос, генерируем подпись, отправляем запрос;
3. периодически опрашиваем сервис на предмет готовности результата;
4. если результат есть — получаем архив дампа, разархивируем его и проверяем список ресурсов на принадлежность нашим клиентам.
Пара советов:
Для питона самой удобной реализацией SOAP-клиента оказался модуль suds
lxml.builder ставит одиночные в xml declaration string, поэтому у нас генерация xml запроса выглядит как-то так:

from datetime import datetime
from dateutil.tz import tzlocal
from lxml import etree
from lxml.builder import E

request_xml = E.request(
    E.requestTime(datetime.now(tzlocal()).isoformat()),
    E.operatorName(settings.NETANGELS_OPERATOR_NAME),
    E.inn(settings.NETANGELS_INN),
    E.ogrn(settings.NETANGELS_OGRN),
    E.email(settings.NETANGELS_EMAIL),
)
# Роскомнадзор не умеют работать с одиночными кавычками и utf-8 :-(
request_str = etree.tostring(request_xml, xml_declaration=True, encoding='windows-1251').replace("'", '"')

Выводы

  • При словах linux в контексте вопроса: «Каким ПО мы можем подписать документ из скрипта?» все удостоверяющие центры впадают в ступор и предлагают ознакомиться с решениями для Windows :-)
  • Мониторинг реестра запрещенных ресурсов можно и нужно автоматизировать, если ваша деятельность связана с хостингом.
  • При запуске любых сервисов необходимо предоставлять разработчикам «песочницу», где можно проверить базовую интеграцию с ними.
  • Иногда задача связанная с работой с государственными структурами может заступориться в совершенно неожиданном месте.

Автор: NetAngels

Источник

Поделиться

* - обязательные к заполнению поля