Что это за рубрика
В рубрике «Разбор Теплицы» мы в режиме реального времени разбираемся в определённой проблеме, новостях интернет-цензуры и рассказываем:
- что происходит;
- как это устроено;
- как с этим можно бороться.
Материал обновляется
Технические средства противодействия угрозам (ТСПУ) блокируют соединение по первым пакетам, иначе они не выдержат нагрузку. Таким образом мы можем обмануть их без полноценного VPN и вывода всего трафика за границу.
Мы решили проверить, какие открытые бесплатные инструменты для этого существуют: ByeDPI, zapret2, youtubeUnblock и несколько других, а также отдельно шифрование самого имени сайта через технологию ECH.
В этом разборе мы изучим только приемы, которые работают локально на устройстве пользователя (ноутбук/мобильное устройство/роутер). Обзоров VPN протоколов и клиентов как приложений здесь не будет.
Какие есть способы обмана DPI
1. Фрагментация (split, tlsrec)
Когда вы открываете, например, заблокированный instagram.com, браузер или приложение отправляет первый пакет, в котором открытым текстом в поле SNI говорит имя сайта внутри TLS-хендшейка. ТСПУ читает это поле, сравнивает со своим списком и если есть совпадение, дальше сбрасывает соединение TCP RST. Но так как ТСПУ читает трафик на лету, у этого чтения есть слабые места.
Если же первый пакет разбить на два маленьких так, что домен в SNI разорван посередине, например один кусок «instag», а следующий «ram.com» , мы обманем ТСПУ, так как они не умеют склеивать куски обратно на скорости и не видят заблокированного/запрещенного сайта/домена. Настоящий сервер instagram.com на другом конце спокойно собирает куски сам, для него это штатная работа обычного TCP-стека.
2. Десинхронизация (disorder, fake, oob)
Также мы можем подсунуть перед настоящими данными еще один, поддельный пакет. ТСПУ обычно смотрит только на первый пакет. Если перед настоящими данными отправить поддельный, с случайным или пустым содержимым, ТСПУ либо решает что все чисто, либо считает что эту сессию уже разобрал и перестает следить за трафиком этого соединения.
3. TTL-игра (—ttl, ip_ttl)
Ещё можно сыграть с временем жизни пакета (TTL). Оборудование ТСПУ стоит на пути раньше настоящего сервера. Мы можем отправить поддельный пакет с таким временем жизни, чтобы он дошел до ТСПУ, но закончился раньше, чем доберется до настоящего сервера. Таким образом ТСПУ обработает этот поддельный пакет как настоящий, а реальный с обычным TTL дойдет чуть позже и уже сброса DPI.
4. Подмена полей в поддельном пакете (rnd, dupsid, sni=)
Или можно подставить безопасный мусор в поля самого поддельного пакета. Если поддельный пакет из предыдущих пунктов все же долетит до настоящего сервера, тот должен просто откинуть его как поврежденный, а не сломаться, поэтому в него специально подставляют невалидные, но безопасные значения. Этот же прием обычно применяют и к поддельному пакету из десинхронизации (2.2), и к поддельному пакету с укороченным TTL (2.3), это не отдельный самостоятельный способ обмануть DPI, а способ сделать безопасным уже отправленный поддельный пакет.
Эти четыре приема (и их комбинации) лежат в основе почти всех изученых нами инструментов, они основаны на академической работе Geneva с конференции CCS 2019, (на неё ссылаются авторы нескольких этих утилит)
Отдельно от этих четырех способов стоит идея скрыть само имя сайта криптографически, а не обманом. Об этом дальше в разделе про ECH.
Что мы сами попробовали
ByeDPI
простой локальный SOCKS5-прокси для Windows, Linux и Android (через отдельное приложение ByeByeDPI), реализует и разрезание, и подмену пакетов, и игру с TTL. Релизы выходят регулярно, вокруг проекта сложилось активное сообщество судя по количеству открытых обсуждений на GitHub.
zapret2
преемник куда более старого zapret. У zapret2 движок переписан так, что стратегии описываются не в коде, а сценариями на Lua, это дает гибкость подстраиваться под новые способы фильтрации без пересборки программы. Поддерживает Linux, FreeBSD, OpenBSD и Windows.
youtubeUnblock
специализированный вариант того же принципа, заточенный на детекторы конкретно YouTube и предназначенный прежде всего для роутеров на OpenWrt или Entware. Автор в документации пишет что это только для YouTube, но технически движок реагирует на список любых ваших доменов в целом.
B4
инструмент с открытым кодом и удобным веб-интерфейсом, умеет сам подбирать рабочую стратегию на лету без перезапуска. Написан на Go. Судя по темпу выхода новых версий, поддерживается очень активно. Работает и на обычном Linux, и на роутерах с OpenWrt или Entware.
zapret-discord-youtube
Готовая сборка zapret именно для Windows с bat-файлами стратегий, 32 тысячи звезд на GitHub.
tg-ws-proxy — инструмент того же автора, но уже не для обхода блокировок вообще, а конкретно для работы Telegram Desktop, оно оборачивает протокол Telegram в обычное WebSocket-соединение. Но к сожалению, работает только на компьютере (Windows, macOS, Linux), для мобильного Telegram не подходит. Базовый режим не требует своего сервера, но расширенный вариант с собственным доменом уже завязан на облачный Cloudflare Worker. Теоретически можно поднять его на роутере и указать в настройках Telegram на телефоне локальный IP роутера вместо 127.0.0.1, протоколу MTProto все равно, где стоит прокси, но мы это не проверяли, это лишь теоретическая возможность, а не готовое решение.
ECH (Encrypted Client Hello).
Идея в том, что имя сайта прячем внутри зашифрованной части пакета, а снаружи виден только общий псевдоним, например у Cloudflare это cloudflare-ech.com, один и тот же для множества разных сайтов. Заблокировать по этому псевдониму точечно сложно, за ним вперемешку скрываются и разрешенные, и потенциально блокируемые сайты. Отсюда у фильтра остается только один грубый вариант: рубить вообще все соединения на cloudflare-ech.com, где такой псевдоним обнаружен, вместо того чтобы выбирать конкретные. Так произошло в ноябре 2024 года, пользователи стали жаловаться, что сайты на инфраструктуре Cloudflare с включенным ECH перестали открываться в браузере и виснут по таймауту, при этом те же самые сайты с той же машины прекрасно скачивались через wget, который ECH не поддерживает, после того как Cloudflare на время отключил у себя TLS 1.3 (это заодно выключает и ECH), сайты снова стали открываться из РФ в течение нескольких минут. Таким образом получается что ТСПУ, обнаружив ECH, обрывает соединение. Это мы и хотим проверить на своих узлах.
Как мы проверяли работу сервисов
Какие сайты брали
Те, что актуальныы для нашей аудитории с разбивкой по группам:
- Мессенджеры: WhatsApp, Signal, Discord, Telegram
- Соцсети: Instagram, Facebook
- Деловые сервисы: LinkedIn
- Приватность и обход блокировок: ProtonVPN, ProtonMail
- Независимые медиа: Meduza, Новая газета Европа, Deutsche Welle
- YouTube проверяли отдельно от остальных: заранее предполагали, что там троттлинг, а не блокировка, но по факту без инструментов домен не открывался вообще ни разу за все прогоны. Можем подтвердить, что в случае YouTube это обычная блокировка, а не деградация скорости, предположение про троттлинг не подтвердилось.
Все домены проверяли с уже настроенным шифрованным DNS (DoH). Это не отдельная переменная теста, а рабочее базовое условие.
Все тесты в этом раунде шли с одного подключения:
- ноутбук на Windows 11,
- VPN до домашнего провода в Петербурге, инструменты запускались внутри WSL2 на этом же ноутбуке с активным VPN-туннелем
Инструменты, рассчитанные в первую очередь на роутеры (youtubeUnblock, zapret2), тестировали именно в WSL2: движок у них тот же самый, netfilter и NFQUEUE, что и на OpenWrt или Entware, так можно проверить, работает ли сам прием, хотя это и не проверяет установку через opkg на конкретной модели роутера.
Отдельно смотрели на два VPS в РФ (Петербург и Москва). Полноценные тесты решили не проводить, так как на этих узлах большинство доменов из списка и так открывались без всякого инструмента, и проверить инструменты обхода на них не было возможности, паттерн поведения был бы одинаковый.
Для сравнения режимов «с обходом» и «без обхода» мы брали уже известные заблокированные адреса и прогоняли каждый по несколько раз подряд — некоторые ресурсы иногда открываются сами по себе без всякого вмешательства, и нужно понять, это определенный способ обхода или случайное совпадение.
Baseline-проверку мы повторяли перед запуском каждого нового инструмента отдельно, чтобы убедиться, что предыдущий инструмент отключился полностью и не оставил активных настроек, которые повлияли бы на результат следующего.
Что показал автоматический прогон
- Соцсети, деловые сервисы, независимые медиа и мессенджеры, кроме Telegram, открылись всеми четырьмя связками без исключений.
- Telegram остался заблокирован при всех трех протестированных инструментах.
- ByeDPI ведет себя по-разному в зависимости от стратегии. Например, с параметрами disorder_tlsrec он открывает WhatsApp и Signal, но не Meduza, а с fake_ttl8 — наоборот.
- У ProtonMail домен mail.proton.me не открылся ни одним инструментом, а account.proton.me случайно оказался рабочим через zapret2. Причем домен изначально не был в списке тестов, поэтому остальные три инструмента его не проверяли. Предполагаем, что mail.proton.me и account.proton.me сидят на разных IP и блокировка идет по конкретному адресу, а не по имени домена целиком. Впрочем отдельно (например, резолвингом IP и обращением на голый адрес) мы это не проверяли
Свод результатов по доменам и инструментам
Каждая связка домен + инструмент прогонялись по несколько раз подряд (5 раз для инструментов, 11-12 раз суммарно для baseline).
| Домен | Baseline | ByeDPI disorder_tlsrec | ByeDPI fake_ttl8 | youtubeUnblock | zapret2 |
| Мессенджеры | |||||
| Заблокирован | Доступен | Нестабильно | Нестабильно | Нестабильно | |
| Signal | Деградирует* | Доступен | Доступен | Доступен | Доступен |
| Discord | Заблокирован | Доступен | Доступен | Доступен | Доступен |
| Telegram | Заблокирован | Заблокирован | Заблокирован | Заблокирован | Заблокирован |
| Соцсети | |||||
| Заблокирован | Доступен | Доступен | Доступен | Доступен | |
| Заблокирован | Доступен | Доступен | Доступен | Доступен | |
| Деловые сервисы | |||||
| Заблокирован | Доступен | Доступен | Доступен | Доступен | |
| Приватность | |||||
| ProtonVPN | Заблокирован | Доступен | Доступен | Доступен | Доступен |
| ProtonMail | Заблокирован | Заблокирован | Заблокирован | Заблокирован | Частично** |
| Независимые медиа | |||||
| Meduza | Заблокирован | Заблокирован | Доступен | Доступен | Доступен |
| Новая газета Европа | Заблокирован | Доступен | Доступен | Доступен | Доступен |
| Deutsche Welle | Заблокирован | Доступен | Доступен | Доступен | Доступен |
| Видео | |||||
| YouTube | Заблокирован | Заблокирован | Заблокирован | Доступен | Доступен |
* curl совпадает с эталоном байт в байт, но при ручной проверке в браузере верстка страницы бьется, часть картинок не грузится.
** account.proton.me (страница входа) через zapret2 открывается, сама почта на mail.proton.me нет. Другими инструментами этот поддомен отдельно не проверялся.
Где curl расходится с ручной проверкой
Здесь хочется коротко объяснить, почему curl вообще может обманывать, дело в том что он делает один голый запрос к главному документу и не тянет картинки, скрипты и повторные соединения, как это делает обычный браузер. Поэтому деградация части ресурсов внутри страницы для него невидима и нужна ручная проверка в браузере глазами а не скриптом в терминале.
- Signal на baseline curl показывает идеальный код 200 и байт в байт совпадающее тело ответа с неподцензурным интернетом, но в браузере верстка битая, не все картинки грузятся.
- WhatsApp в целом работает, но на всех трех инструментах ByeDPI fake_ttl8, youtubeUnblock и zapret2 есть нестабильность, а Facebook и Instagram (на той же инфраструктуре Meta) работают без проблем при включенных инструментах обхода. Что-то специфичное для протокола WhatsApp или баг при реализации инструментов обхода блокировок, мы не понимаем.
Как вы можете этим всем воспользоваться?
Если вы разработчик или администратор
- Перед тем как разворачивать любой из инструментов ниже для своих пользователей, проверьте как именно блокируется нужный сайт. Если IP-адрес недоступен вообще, даже без TLS, это полный обрыв маршрута, и ни один из приемов этой статьи не поможет, нужен полноценный тоннель. Если сайт недоступен только по HTTPS, а на сам IP-адрес что-то отвечает, скорее всего это блокировка по SNI, и тогда есть смысл пробовать.
- Если у вас роутер с поддержкой OpenWrt или Entware, рекомендуем ставить youtubeUnblock, zapret2 или B4 сразу на роутер, тогда обход будет работать для всех устройств в сети сразу, без настроек на каждом отдельно. Если роутер такое не поддерживает, ставьте утилиту на каждое устройство отдельно (ByeDPI и zapret2 есть под Windows и Linux, ByeByeDPI под Android), это не так удобно, но тоже рабочий вариант
- Если вы настраиваете обход для группы людей на Windows, например для семьи или небольшой команды, проще один раз собрать готовую конфигурацию (например на основе zapret-discord-youtube) и раздать ее, чем объяснять каждому что такое флаги командной строки.
- Если вы администрируете инфраструктуру, учитывайте что WinDivert, драйвер, на котором работает большинство инструментов под Windows, может определяться антивирусами как потенциально нежелательное приложение, стоит заранее предупреждать пользователей, чтобы они не отказались из-за предупреждения антивируса или операционной системы.
Блок Б. Для пользователей
- Настроить шифрованный DNS (DoH/DoT) можно на разных уровнях, это отдельный слой, никак не связанный с приемами выше, но снимающий часть проблем с подменой DNS-ответов:
- на роутере Keenetic: раздел «Интернет-фильтры» — Настройка DNS — добавить сервер — тип сервера «DNS-over-HTTPS»;
- в Windows 11: Параметры → Сеть и Интернет → выбрать свое подключение → Свойства → напротив «Назначение DNS-сервера» нажать «Изменить» → переключить на «Вручную» и указать адрес DoH-сервера с включенным шифрованием;
- в браузере: в настройках приватности и безопасности включить «Безопасный DNS» и выбрать провайдера.
Что дальше
- Нужно проверить комбинацию нескольких приемов сразу (например разрезание пакета и игра с TTL). Этот способ может оказаться устойчивее против точечных обновлений фильтров, чем один-единственный сервис.
- За рамками этого материала остались децентрализованные и оверлейные сети (I2P, Yggdrasil, CJDNS, IPFS) и инструменты вроде Snowflake из проекта Tor. Формально они не требуют собственного арендованного сервера, но все равно оборачивают трафик в отдельную сеть целиком, а не обманывают конкретно ТСПУ. Мы их разберем отдельно в одном из следующих материалов.
- ECH. Будем отдельно проверять его по DNS-записи типа HTTPS (dig -t HTTPS домен) и посмотрим, есть ли параметр ech=, и сверим поведение с эталонным доменом cloudflare-ech.com, который существует специально для такой проверки.
Список источников
- ByeDPI: https://github.com/hufrea/byedpi
- ByeByeDPI: https://github.com/romanvht/ByeByeDPI
- zapret / zapret2: https://github.com/bol-van/zapret, https://github.com/bol-van/zapret2
- youtubeUnblock: https://github.com/Waujito/youtubeUnblock
- B4: https://github.com/DanielLavrushin/b4
- zapret-discord-youtube: https://github.com/Flowseal/zapret-discord-youtube
- tg-ws-proxy: https://github.com/Flowseal/tg-ws-proxy
- О блокировке TLS-сессий с сигнатурой ECH: https://habr.com/ru/news/856342/
- Geneva, CCS 2019: https://geneva.cs.umd.edu/papers/geneva_ccs19.pdf