На Хабре уже было несколько статей по поводу трудностей, связанных с получением доступа к списку запрещенных сайтов, с его обновлением и использованием. Эта статья — логическое продолжение ранее высказанной другими (в том числе в комментариях) критики. Сразу оговорюсь, что я не являюсь сотрудником никакого провайдера.
Итак, предположим, что вы собрались предоставлять клиентам услуги доступа в Интернет, или, проще говоря, стать провайдером. Чтобы добиться лояльности клиентов, вы решили купить навороченную DPI-систему, блокировать запрещенную информацию по URL'ам и не блокировать ничего лишнего. Никакой фильтрации по доменам и IP, только по URL'ам! Все юридические, бюрократические, этические и денежные вопросы улажены, остались технические. Осталось только взять готовую автоматическую качалку списка запрещенных сайтов и настроить автоматическую загрузку этого списка в DPI-систему в том формате, который она понимает. Т.е. написать скрипт-конвертер. Так вот, вынужден вас разочаровать — написать работающий конвертер не получится. Не получится до тех пор, пока в Роскомнадзоре не пошевелятся и не поменяют формат данных, а также не исправят явные ошибки в существующих элементах списка.
Начнем с того, в каком именно формате Роскомнадзор отдает список запрещенной информации. Это XML, соответствующий XSD-схеме, опубликованной как часть Памятки оператору связи. Или, говоря проще, XML, содержащий последовательность блоков наподобие следующего:
<content id="105" includeTime="2012-11-11T15:39:37">
<decision date="2012-11-04" number="2/1/16402" org="ФСКН"/>
<url>http://go-****.com/workshop/</url>
<domain>go-****.com</domain>
<ip>62.75.***.***</ip>
</content>
При этом, согласно схеме, тегов <url> может быть от нуля до бесконечности, за ними следует ноль или один тег <domain>, а затем от одного до бесконечности тегов <ip>. Нас, очевидно, интересуют теги <url>. Итак, вроде бы, надо только закрыть доступ к перечисленному списку URL'ов.
А теперь посмотрим, какими средствами похожие задачи решались ранее и какие умные слова при этом говорились.
Доступ к URL'ам на серверах надо закрывать не только от людей, но и от роботов. Для этого служит файл /robots.txt с документированным синтаксисом. Что не менее важно, в этом же документе подробно описана и семантика, т.е. точные правила интерпретации каждой записи для решения вопроса, можно ли роботу посещать какой-либо URL:
The matching process compares every octet in the path portion of
the URL and the path from the record. If a %xx encoded octet is
encountered it is unencoded prior to comparison, unless it is the
"/" character, which has special meaning in a path. The match
evaluates positively if and only if the end of the path from the
record is reached before a difference in octets is encountered.
Т.е., чтобы запись сработала, путь в записи robots.txt должен быть префиксом пути в URL. Соответствующих правил на сайте Роскомнадзора просто нет, и это, с моей точки зрения, баг. Может, попробовать написать эти правила за них? И ведь похоже, что фильтрация по префиксу, а не по точному совпадению URL'а, более уместна и в случае блокировок контента от людей. Не будет же Роскомнадзор перечислять все URL'ы сайта, который надо заблокировать целиком!
Еще к стандарту robots.txt есть расширение Clean-Param. Оно указывает, какие GET-параметры являются незначащими, т.е. не должны учитываться при сравнении URL'ов. Само понятие значимости параметров является важным — это ведь плохо, если пользователь сможет обойти блокировку, добавив unblock_me=1& после вопросительного знака в URL'е. Только вот в случае блокировки контента от людей, правильнее будет говорить о значащих параметрах и о том, что порядок этих параметров на самом деле не имеет значения.
Итого, вырисовывается такая умозрительная схема правдоподобной интерпретации смысла URL'ов в реестре запрещенных сайтов:
- Перед применением следующих шагов как URL в реестре, так и URL, к которому обратился пользователь, должны быть нормализованы путем замены октетов, закодированных в формате %xx, на раскодированные октеты, за исключением символа "/".
- Если в списке запрещенных сайтов URL не содержит символа "?", то для того, чтобы блокировка сработала, URL в реестре должен быть префиксом URL'а, к которому обратился пользователь.
- Если в списке запрещенных сайтов URL содержит символ "?", то для того, чтобы блокировка сработала, URL в реестре и URL, к которому обратился пользователь, должны посимвольно совпадать в позициях до первого знака "?" включительно. Набор GET-параметров в URL'е из реестра должен быть подмножеством набора GET-параметров из пользовательского URL'а. Считается, что GET-параметры разделяются символом "&".
Только вот эта схема все равно является неполной. Надо ли проводить сравнение с учетом регистра? Как именно учитывать регистр — ведь у нас есть только байты в неизвестной кодировке?
И самое главное — существующие данные в реестре под эту схему не подходят. Чего только стоят вот такие записи:
<url>http://*******tube.ru/index.php</url>
<url>http://********.kiev.ua/index.php</url>
<url>http://***forum.org/index.php?s=3a95f6da301a36067be68329be6f88a8&showforum=8</url>
<url>http://****lib.net/b/27415/read#t16</url>
В первых двух случаях мне, как читателю мыслей, очевидно намерение заблокировать сайт целиком, вместо чего блокируются только URL'ы, путь которых начинается с /index.php. В третьем параметр s похож на незначащий идентификатор сессии. В четвертом вообще есть хеш-тег. В общем — исходные данные слишком грязные, чтобы схема работала.
И даже если бы она работала, я бы эту схему использовать не стал. При ее написании я произвел слишком много попыток что-то угадать, и все это сильно напоминает попытку написать очередной клон libastral. При интерпретации законов такие действия недопустимы.
Итак, если кто-то пытается вам продать систему фильтрации по URL'ам на основе официальных данных с zapret-info.gov.ru, не верьте ему — это однозначно развод. Пока Роскомнадзор не сделает свои данные по-настоящему машиночитаемыми и однозначно интерпретируемыми, такие решения просто не могут работать. На сей день тег <url> в XML-дампе реестра годится только как справочная информация для проверки обоснованности включения сайта в реестр. Нужны на самом деле не URL'ы, а правила фильтрации.
Теперь поговорим о том, что Роскомнадзор мог бы сделать для исправления ситуации, когда люди говорят о принципиальной возможности URL-фильтрации по его спискам, а на деле такой возможности нет.
Самый простой (и, на мой взгляд, самый правильный) способ — это оставить все как есть, но публично признать, что информация в реестре запрещенных сайтов непригодна и не может быть пригодна для фильтрации по URL'ам. Тег <url> оставить — как уже было сказано, он полезен для проверки решений о блокировках и тем самым для обеспечения прозрачности процесса.
Способ посложнее — написать правила интерпретации содержимого тега <url> (как я пытался сделать выше) и подогнать под них существующее содержимое базы.
Еще способ — переделать структуру XML. Сделать вместо одного тега <url> конструкцию, способную хранить префикс, обязательные параметры и, возможно, другую информацию, способную описать группу связанных URL'ов. Тогда ее можно будет превратить в регулярное выражение для «acl aclname url_regex» в SQUID или в glob для «match protocol http url» в Cisco NBAR.
А вот почему я считаю первый способ самым правильным. В Роскомнадзоре, похоже, внедрена такая схема работы: приходит жалоба с URL'ом противоправного контента, модераторы ее проверяют и вносят тот же URL в базу. В этом процессе нет места для преобразования URL'а, на который пожаловались, в машиночитаемые правила фильтрации. И если пытаться внести этот (существенно ручной) шаг, то надо искать людей, способных его выполнить. Это же надо объяснить исполнителям, что машина не умеет читать мысли. Это же надо найти людей, которые и психологически устойчивы, и способны поставить себя на место машины и проверить, действительно ли правило работает, как надо. Тяжелая задача для отдела кадров! Ну и если оставить тег <url> чисто информационным и явно сказать об этом, то у провайдеров не будет возникать желания потратить деньги на навороченную DPI-систему, которую по факту все равно не получится использовать по назначению.
Автор: AEP