Самой обсуждаемой новостью текущей недели в рунете, безусловно, является принятие закона №139-ФЗ и его последствий. В силу того, что наша компания предоставляет услуги хостинга, нам понадобился доступ к полной базе реестра, чтобы своевременно реагировать на добавление ресурсов наших клиентов в базу. Это связанно с тем, что нам необходимо информировать клиентов о блокировке их ресурсов, ведь в случае, например, блокировки по ip сервера веб-хостинга, могут пострадать и остальные, ни в чем не виноватые, клиенты. К сожалению, получение такого доступа оказалось делом не самым очевидным, поэтому мы хотели бы поделиться результатом прохождения данного квеста.
В статье мы бы хотели сфокусироваться на техническом аспекте и избежать обсуждения этическо-политической стороны вопроса, т.к. любой активный пользователь уже успел высказать свое недовольство по данной теме, пожалеть рутрекер с луркоморьем и подумать на тему обхода запрета ресурсов ранее.
В настоящий момент доступ к единому реестру запрещенных ресурсов предполагается двух видов:
- Для всех пользователей интернета в виде формы поиска на главной странице реестра. Каждый запрос требует ввода капчи, кроме того, форма, по сути, решает задачу получения информации о блокировке конкретного ресурса, известного заранее, т.к. если сайт забанен по url, то ввод в форму имени домена не даст никакого результата. Пример:
ww.xapka.com— пусто,http://www.xapka.com/— информация о блокировке. - В виде полного дампа базы запрещенных ресурсов в разделе «операторам связи». Есть возможность доступа либо через веб-форму с необходимостью ввода капчи, либо в через SOAP-сервис. Адрес WSDL: www.zapret-info.gov.ru/services/OperatorRequest/?wsdl.
Во втором случае каждый запрос на выгрузку базы необходимо подписывать ЭЦП, в формате PKCS#7 и передавать отвязанную подпись вместе с запросом. В идеале мы представляли себе примерно такой порядок действий: покупаем ЭЦП, берем привычный нам Debian, ставим туда соответствующее ПО для автоматической подписи запросов, пишем скрипт, который общаясь с сервером zapret-info через SOAP формирует запрос, подписывает его, скачивает дамп и рядом эвристических методов проверяет, не относятся ли к нам какие-либо ресурсы из списка.
Казалось бы, все просто, но на деле оказалось несколько сложней и дольше.
ЭЦП
Сервер zapret-info не предоставляет никакой «песочницы», в которой можно было бы протестировать работу скрипта без наличия валидной ЭЦП, поэтому самым первым делом надо озаботиться ее приобритением.
Купить сертификат для создания квалифицированной электронной подписи можно в доверенном удостоверяющем центре. По умолчанию все УЦ для подписывания документов предлагают пользоваться программами из семейства КриптоПРО (КриптоАРМ, cryptcp). К сожалению, пользование этим многообразием программных продуктов омрачает несколько фактов:
- Если в состав комплекта ЭЦП входит лицензия КриптоПРО — то скорее всего, она предназначена для Windows.
- Сама КриптоПРО ничего не умеет подписывать, а инструменты, которые умеют — требуют отдельной лицензии и покупки.
- Возникают еще вопросы про лицензирование (то ли нам нужна лицензия на 1 рабочее место, то ли на 1 сервер).
Поэтому быстрый поиск в интернете навел нас на информацию о том, что с помощью несложных действий с Рутокеном можно научить работать привычный нам OpenSSL. Краткий бриф наших действий такой:
- Экспортировать ключ в формате PKCS#12 из криптоконтейнера в Windows с помощью утилиты P12FromGostCSP
- Преобразовать его в PEM
- Прописать в конфиге openssl.conf параметры
В самом начале, до секций:
openssl_conf = openssl_def
В конце новые секции:
[openssl_def] engines=engine_section [engine_section] gost=gost_section [gost_section] engine_id=gost default_algorithms=ALL
- Все готово, теперь можно попробовать создать любой файл и подписать его:
$ 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 🙂
- Мониторинг реестра запрещенных ресурсов можно и нужно автоматизировать, если ваша деятельность связана с хостингом.
- При запуске любых сервисов необходимо предоставлять разработчикам «песочницу», где можно проверить базовую интеграцию с ними.
- Иногда задача связанная с работой с государственными структурами может заступориться в совершенно неожиданном месте.
ссылка на оригинал статьи http://habrahabr.ru/post/158891/
Добавить комментарий