Когда антибот притворяется Роскомнадзором: ложные срабатывания и локальный Web UI в rkn-block-checker 0.6.0
Инструменты проверки блокировок иногда ошибаются не из-за проблем в сетевой диагностике, а из-за слишком буквальной интерпретации ответа сайта. Именно такая ситуация произошла с Avito: сервис внезапно оказался отмечен как недоступный, причем программа уверенно сообщила о якобы действующей заглушке Роскомнадзора.
Речь шла о контрольном списке ресурсов, которые должны открываться при штатном подключении: Госуслуги, Яндекс и другие популярные сайты. В очередном запуске рядом с Avito появился статус:
```text
avito ✗ HTTP_STUB
```
Дополнительное пояснение выглядело еще убедительнее: "На Avito обнаружена заглушка провайдера о блокировке РКН", а вероятность ошибки оценивалась как высокая.
Почему антибот приняли за блокировку
Причина оказалась в простой проверке по ключевым словам. В ранней версии анализатор искал в HTML характерные фразы, которые обычно встречаются на страницах провайдерских заглушек. Среди таких маркеров была формулировка "доступ ограничен".
Однако Avito действительно активно защищается от автоматизированных запросов. Если клиент обращается к сайту без накопленных cookies и прочих признаков обычного браузера, система защиты может расценить запрос как подозрительный. Даже корректный User-Agent, имитирующий Chrome, не всегда меняет результат.
Вместо нормальной страницы сервер вернул ответ:
```text
HTTP 429 Too Many Requests
```
В теле страницы присутствовало сообщение о временном ограничении доступа по IP. Проверяющий модуль увидел знакомую фразу, сопоставил ее с шаблонами заглушки и сделал неправильный вывод: будто ресурс заблокирован оператором связи.
На практике это была реакция самого сайта на слишком частые или неестественные обращения. Ни магистральная фильтрация, ни решение регулятора здесь ни при чем.
Как отличить заглушку провайдера от ответа сайта
Проверка текста страницы без учета HTTP-контекста недостаточна. Одни и те же слова могут использоваться в совершенно разных ситуациях: на странице блокировки, при срабатывании WAF, во время показа CAPTCHA или при временном ограничении частоты запросов.
Провайдерские заглушки в российских сетях обычно имеют несколько характерных признаков. Нередко соединение завершается ответом `200 OK`, хотя вместо оригинального содержимого пользователю подставляется информационная страница. В других случаях используется статус `451 Unavailable For Legal Reasons`.
Коды `429` и `403` сами по себе не указывают на цензурную блокировку. Первый обычно означает превышение лимита запросов, а второй может быть связан с CAPTCHA, WAF, отсутствием нужных cookies или иной политикой безопасности самого сервиса.
В версии 0.6.0 логика диагностики была переработана: проверка теперь разделяет сетевую фильтрацию и защиту целевого сайта. Ответ с кодом 429 не должен автоматически превращаться в вердикт о блокировке. Для итоговой оценки учитываются одновременно статус, заголовки, содержимое страницы, особенности DNS и поведение соединения.
Почему одной проверки HTTP недостаточно
Надежная диагностика должна рассматривать результат как совокупность признаков. Например, нужно выяснить, куда разрешилось доменное имя, удалось ли установить TCP-соединение, завершился ли TLS-handshake и какой сертификат был получен.
Важны также:
- фактический HTTP-статус;
- наличие перенаправлений;
- заголовки сервера;
- размер и содержимое ответа;
- время выполнения отдельных этапов;
- повторяемость результата при нескольких запросах;
- отличие поведения сайта в разных сетях.
Такой подход помогает отделить блокировку на уровне провайдера от временной ошибки, перегрузки, антибот-фильтра или некорректной настройки сервера.
Зачем консольному инструменту веб-интерфейс
Изначально `rkn-block-checker` создавался как консольная утилита. Для массовой проверки этого достаточно: команда запускается, список адресов обрабатывается параллельно, а итог выводится в терминал.
Но спорные случаи требуют большего количества деталей. Если ресурс то открывается, то получает ошибку, пользователю важно увидеть не только финальный статус, но и последовательность событий: сколько занял DNS-запрос, как долго устанавливался TCP, успешно ли прошел TLS и на каком этапе возникла проблема.
Кроме того, графический интерфейс удобнее для тех, кто редко работает с командной строкой. В браузере проще выбрать нужный сайт, добавить собственный адрес, повторить проверку и изучить подробный отчет.
Локальный Web UI без тяжелого стека
Разработчики сознательно отказались от FastAPI, Flask, Uvicorn и клиентских сборщиков. Главная цель проекта - быстрое развертывание в чистом системном Python через `pip`, без Node.js, дополнительных пакетов и внешних CDN.
Локальный интерфейс построен на стандартных средствах:
- сервер использует `http.server.ThreadingHTTPServer`;
- клиентская часть представляет собой один HTML-файл;
- JavaScript и CSS написаны без фреймворков и сборки;
- интерфейс работает локально и по умолчанию доступен на `127.0.0.1:7777`.
Запуск выполняется отдельной командой:
```text
rkn-check startweb
```
Такой вариант удобен для диагностики на рабочей станции: интерфейс не публикуется во внешнюю сеть и не требует настройки отдельного веб-сервера.
Как результаты поступают в браузер
Проверка нескольких десятков адресов может занимать заметное время. Если ждать завершения всех задач, пользователь будет видеть пустой экран до окончания процесса. Поэтому результаты передаются по мере готовности, как это происходит в консольном режиме с использованием `as_completed()`.
Для обмена выбран обычный HTTP-стриминг в формате NDJSON - по одному JSON-объекту на строку. Сервер начинает отдавать данные сразу после завершения очередной проверки, а браузер читает поток через стандартный `ReadableStreamDefaultReader`.
Это позволило обойтись без WebSocket и постоянного polling. Архитектура осталась простой, а интерфейс при этом получает обновления почти в реальном времени: строки появляются по мере обработки адресов, а не после завершения всей очереди.
Что появилось в версии 0.6.0
В новый релиз вошли несколько заметных изменений:
1. полноценный локальный Web UI с графиками и интерактивным списком результатов;
2. переключение между русским и английским языками;
3. добавление произвольных URL непосредственно из браузера;
4. более точное распознавание антибот-ответов;
5. исключение HTTP 429 из автоматической классификации как провайдерской заглушки;
6. экспорт полного отчета в JSON одним нажатием;
7. сохранение подробностей по этапам сетевого подключения.
Экспорт особенно полезен для повторного анализа. JSON-файл можно приложить к внутреннему отчету, сравнить с результатами предыдущей проверки или обработать другим инструментом.
Как правильно трактовать спорные результаты
Одиночный отрицательный ответ еще не доказывает наличие блокировки. Сначала стоит повторить запрос через несколько секунд, проверить другой URL того же домена и сравнить результат с обычным браузером.
Если возвращается `429`, наиболее вероятна реакция антибот-системы. При `403` следует проверить наличие CAPTCHA, cookies и редиректов. Если сервер отдает `200`, но содержимое явно не связано с запрошенным сайтом, нужно анализировать подмену страницы и сетевой маршрут.
Настоящую блокировку обычно подтверждает совокупность признаков: стабильный результат, характерный статус или содержимое заглушки, одинаковое поведение при повторных запросах и отсутствие признаков ответа самого сервиса.
Итог
История с Avito показала, почему сетевой анализ нельзя строить только на поиске отдельных фраз в HTML. Антибот может вернуть страницу с формулировкой "доступ ограничен", но это не означает, что ресурс заблокирован регулятором или оператором.
В `rkn-block-checker 0.6.0` эти сценарии разделены, а результаты стали доступнее благодаря локальному веб-интерфейсу. При этом инструмент сохранил главное преимущество - минимальное количество зависимостей и быстрый запуск в обычном Python-окружении. Исходный код распространяется под лицензией MIT, а установить или обновить пакет можно стандартной командой:
```text
pip install rkn-block-checker --upgrade
```
Теперь утилита помогает не только обнаружить проблему, но и понять, где именно она возникла: в DNS, соединении, TLS, сетевой фильтрации, настройках сервера или антибот-защите.
