Последние пару лет я работаю в команде, которая занимается устойчивой к DPI (Deep Packet Inspection) туннельной инфраструктурой — по сути, альтернативой классическому VPN.
Когда начинаешь заниматься этим всерьёз, довольно быстро обнаруживается неприятная вещь: шифрование само по себе давно уже не означает, что трафик нельзя распознать. Содержимое пакетов действительно можно скрыть, но пакет от этого не исчезает. У него остаются размер, направление, время появления; соединение начинается с определённой последовательности сообщений, TLS‑клиент определённым образом представляется серверу, поток ускоряется, замедляется, замирает и снова начинает передавать данные.
Для человека всё это выглядит как куча зашифрованных байтов. Для классификатора — как вполне пригодный набор признаков.
Поэтому значительная часть нашей работы в итоге свелась не к тому, чтобы «зашифровать ещё сильнее», а к более практическому вопросу: что именно видит наблюдатель снаружи и по каким признакам он может решить, что перед ним не браузерный трафик, а туннель.
Об этом и расскажу.
Что именно палит DPI
Наивное представление о DPI выглядит примерно так: где‑то у провайдера стоит коробка, которая заглядывает внутрь пакета, узнаёт запрещённый протокол и блокирует его. Но для классификации совершенно не обязательно понимать содержимое трафика. Шифрование скрывает данные, но не уничтожает форму обмена данными, а у разных протоколов эта форма разная.
OpenVPN — классический пример. Его рукопожатие имеет узнаваемую сигнатуру, и для системы, специально настроенной на обнаружение такого трафика, это удобный признак. Не обязательно долго наблюдать за соединением: характерная последовательность появляется уже в самом начале.
С WireGuard история другая. У части его служебных сообщений — handshake initiation и handshake response — фиксированный размер. Содержимое зашифровано, но наблюдатель всё равно видит сам факт появления пакетов определённой структуры и размера.
Вообще, фраза «но ведь всё зашифровано» в таких задачах помогает гораздо меньше, чем кажется. Представьте непрозрачный грузовик: посмотреть, что у него внутри, нельзя. Но если каждый день в одно и то же время из одних ворот выезжают три одинаковых грузовика, затем один возвращается, а два уходят дальше, содержимое кузовов для понимания происходящего может оказаться не самым важным признаком.
С Shadowsocks и V2Ray‑семейством всё несколько интереснее. Иногда это объясняют совсем просто: DPI якобы видит высокую энтропию и понимает, что перед ним зашифрованный туннель. Проблема в том, что TLS‑шифртекст тоже высокоэнтропиен, поэтому одна лишь «случайность» данных ничего не доказывает.
Гораздо полезнее смотреть на соединение целиком. Если протокол пытается выглядеть как TLS, насколько его рукопожатие похоже на то, что производит настоящий браузер? Что происходит после рукопожатия? Каковы размеры пакетов, их последовательность, направления, паузы между ними? Именно здесь появляется пространство для статистической классификации.
Даже при полностью зашифрованном содержимом снаружи остаётся немало метаинформации: размеры первых пакетов, направление передачи, временные интервалы, характер начала соединения, структура TLS‑рукопожатия. DPI не обязательно должен «прочитать пакет и понять, что внутри». Ему достаточно найти устойчивый паттерн и научиться отличать его от обычного сетевого трафика.
Вот с этим мы и пытались работать.
Архитектура
Мы довольно рано решили не складывать все функции системы в один универсальный сервер и разнесли роли между несколькими типами узлов.
Есть клиент, control‑узлы и exit‑узлы. Отдельно существует арбитр, который формирует и подписывает список актуальных узлов. Клиент, получив такой список, сначала проверяет подпись и только после этого начинает ему доверять.
Само по себе это разделение, конечно, ничего не маскирует. Это архитектурная основа, поверх которой уже работают остальные механизмы.
Вообще, одна из вещей, к которым мы пришли в процессе разработки, — анти‑DPI довольно плохо укладывается в представление об одном «хитром протоколе». Нет одной волшебной настройки, после которой трафик вдруг становится правильным. Есть несколько разных наблюдаемых признаков, и с каждым приходится разбираться отдельно.
Что мы пытались замаскировать
TLS‑фингерпринт
Когда браузер устанавливает TLS‑соединение, он начинает с ClientHello. В нём достаточно много параметров, причём разные реализации TLS формируют это сообщение по‑разному. В результате сам способ, которым клиент начинает рукопожатие, становится классификационным признаком.
Мы используем uTLS и копируем ClientHello реальных браузеров — Chrome, Firefox, Edge и Safari. Варианты ротируются между соединениями. Это уменьшает полезность классификации, которая опирается именно на fingerprint рукопожатия.
Разумеется, ClientHello — лишь одна часть поведения соединения, и копирование браузерного рукопожатия ещё не превращает весь трафик в браузерный. Но оставлять стабильный и легко различимый TLS‑фингерпринт собственного клиента тоже особого смысла нет.
По той же причине служебные признаки туннеля не вынесены в отдельный хорошо заметный заголовок собственного протокола. Иначе конструкция получилась бы довольно забавная: сначала тщательно стараемся начать соединение как обычный TLS‑клиент, а сразу после этого отправляем собственное «здравствуйте, я туннель».
Транспорт поверх HTTP/2 через uTLS
Сам транспорт работает поверх HTTP/2 через uTLS. Снаружи наблюдатель видит TLS‑сессию с браузероподобным ClientHello, а полезная нагрузка передаётся уже внутри установленного TLS‑канала.
Здесь полезно не смешивать два уровня. Наблюдателю доступны само TLS‑рукопожатие, размеры зашифрованных данных, направление передачи и её временной рисунок. Содержимое транспорта находится внутри.
Поэтому одного браузероподобного ClientHello недостаточно. Если после него соединение ведёт себя совершенно не так, как ожидается от обычной сетевой активности, у классификатора всё равно остаётся достаточно материала. Из этого, собственно, выросли следующие части схемы.
Decoy‑трафик
Параллельно с основным потоком клиент делает настоящие запросы к реальным CDN.
Здесь нет идеи «спрятать один пакет среди других»: отдельные соединения остаются отдельными соединениями. Речь идёт об агрегированной сетевой активности клиента. Если классификация учитывает не только один flow, но и совокупность наблюдаемого поведения, реальный фоновый трафик делает эту картину менее однозначной.
Бесплатным это, естественно, не бывает. Дополнительные запросы означают настоящие соединения, TLS, шифрование и обработку данных, поэтому decoy‑трафик заметно увеличивает нагрузку на CPU клиента. Этот компромисс мы приняли сознательно.
Вообще, после некоторого времени работы над такими системами начинаешь меньше любить слова «лучше» и «хуже». Обычно полезнее сформулировать две вещи: какой признак мы пытаемся убрать и сколько нам это стоит. В данном случае цена — дополнительная вычислительная нагрузка.
Pacing
Ещё один доступный наблюдателю признак — форма потока во времени.
Сетевой трафик редко идёт идеальной ровной линией: появляются всплески, паузы, меняется направление передачи. У туннеля тоже складывается собственный временной рисунок, и если оставить его как есть, он превращается ещё в один признак для классификатора.
Поэтому мы используем pacing — сглаживание всплесков передачи во времени. Никакой отдельной криптографии здесь нет; это просто попытка уменьшить ещё один наблюдаемый признак на транспортном уровне.
Что происходит с незнакомым запросом
Есть и совсем приземлённая часть.
Если на сервер приходит запрос, который он не распознаёт как корректный, сервер не должен отвечать чем‑нибудь в духе: «Да, вы попали куда нужно, но неправильно представились».
Для неаутентифицированного клиента такой запрос заканчивается обычным 404, то есть само обращение к адресу не подтверждает назначение сервера.
Это имеет значение при active probing, когда наблюдатель не ограничивается анализом проходящего трафика, а сам начинает обращаться к найденным эндпоинтам. В нашем случае незнакомый запрос получает максимально скучный ответ: такого ресурса здесь нет.
Во что это выливается на практике
Здесь было бы удобно показать красивый набор графиков и назвать всё это бенчмарком эффективности, но такого бенчмарка у нас нет. Мы не тестируем систему на лабораторном стенде против конкретных моделей и версий DPI‑оборудования.
У нас есть полевые наблюдения в реальных сетях нескольких крупных российских операторов: Ростелеком, Билайн, Мегафон, МТС, Теле2 и Дом.ру. Именно так к этим данным и стоит относиться: разные реальные подключения и маршруты, а не эксперимент, где можно менять один параметр за другим и аккуратно измерять влияние каждого.
Цена всей описанной выше обвязки при этом вполне реальна. По нашим наблюдениям, она добавляет примерно 40–80 мс задержки относительно прямого соединения. Decoy‑трафик заметно загружает CPU клиента — лишнее шифрование и обработка данных никуда не деваются.
Со скоростью получилось интереснее. На части маршрутов средняя скорость не уступала прямому подключению к тому же ресурсу; вероятно, здесь сказывается распределение нагрузки между несколькими exit‑каналами. Но воспринимать это как способ «ускорить Интернет» я бы точно не стал: скорее это хороший пример того, насколько итог зависит от конкретного маршрута.
Основная задача всей конструкции гораздо скромнее: уменьшить число простых и стабильных признаков, по которым зашифрованный поток удобно классифицировать как отдельный туннельный протокол. Сам трафик никуда не исчезает, и сеть, разумеется, продолжает его видеть. Мы лишь стараемся сделать наблюдаемую картину менее удобной для простой классификации.
Открытая часть
Часть проекта открыта: SDK опубликован на GitHub, и код протокола обфускации и decoy‑логики можно посмотреть непосредственно в реализации, а не только в пересказе статьи.
Мне вообще нравятся технические тексты, после которых можно открыть код и проверить, насколько написанное совпадает с тем, что на самом деле уходит в сокет. В сетевых протоколах это особенно полезно: между красивой схемой и работающей реализацией иногда помещается немало интересного.
Если есть вопросы по архитектуре — задавайте в комментариях. На то, что знаю и что могу обсуждать публично, отвечу.
Комментарии (48)

notsee
08.08.2026 08:16Ты зачем ркн помогаешь?

notsee
08.08.2026 08:16В качестве пояснения. Я уехал в глубинку нашей необъятной. Тут ркн местный интернет использует как полигон. В рандомный день инет перестает работать, они обкатывают новые способы блокировки. Но учитывая что чаще всего, перестает работать даже то, что должно и через пару часов откатывают назад, они знатные рукожопы. А ты им инструкцию выкатил, как делать правильно.

si_12345
08.08.2026 08:16Я тоже уехал в глубинку нашей необьятной
И у меня бесплатный тор как работал, так и продолжает работать

dmitry__ilyin Автор
08.08.2026 08:16Все, что они смогут накопать, они накопают. Устойчивы только технологии, на которые накопать нельзя. Или очень сложно. "Защита незнанием" никогда не была эффективной.

notsee
08.08.2026 08:16Я предпочту когда они накопают позже, чем я найду способ обойти.

aldekotan
08.08.2026 08:16Тоже раньше так думал. Но для себя решил, что лучше помочь нуждающимся ещё хотя бы раз выйти на связь в свободном интернете, чем помешать РКНу его отобрать, скрывая эту информацию. Ну и да. Не забывайте, что распространение информации о способах обхода блокировок РКНу по барабану, иначе бы закон не продвигали, запрещающий такого рода статьи с объяснением способов обхода.

Ox2A
08.08.2026 08:16Стратегия помогать друг-другу эффективнее, чем стратегия эгоиста. Это можно отследить и по развитию опенсурса, и по миру, который за исключением отдельных стагнирующих стран стремится к сотрудничеству и глобализации. И в даже в биологии у каких-нибудь бактерий есть механизмы горизонтального переноса генов, когда они делятся друг с другом случайными участками ДНК, потому что это увеличивает приспособленность и выживаемость всего их вида. А вот стратегия эгоиста - ни с кем не делиться информацией, спрятаться и не отсвечивать выгодна только РКН. И при такой стратегии даже твой личный маленький секрет они когда-нибудь раскроют и ты останешься у разбитого корыта.

Kenya-West
08.08.2026 08:16Security through obscurity так или иначе приводит к тупику. Вдобавок, это изначально вредная практика. Она полезна лишь в некоторых узких случаях.

liquidgel
08.08.2026 08:16Все что сейчас работает лежит в открытом доступе с доступным кодом и документацией, весь трафик виден, кто куда ходит видно. Все хостеры кроме совсем подвальных известны и не скрываются. Вопрос всегда был лишь в том что они могут с этой информацией сделать и насколько готовы ломать для достижения целей. Доступность информации для них проблемой никогда не была и не будет

Sulerad
08.08.2026 08:16Часть проекта открыта: SDK опубликован на GitHub, и код протокола обфускации и decoy‑логики можно посмотреть непосредственно в реализации, а не только в пересказе статьи.
А где опубликован-то? В статье нет ни ссылки, ни названия проекта.

dmitry__ilyin Автор
08.08.2026 08:16Вот: https://shortnerdcat.navlink.net А SDK на GitHub: https://github.com/kostiakhait/tunnelcat-sdk

exeonid
08.08.2026 08:16А какая роль у вас в этом проекте?
<!-- Copyright (C) Konstantin Khait & Claude Code For IT Partners Solutions and Freedom and Rights 2026 -->
Rub_paul
08.08.2026 08:16Главный архитектор тут очевидно Клод, а кожаный мешок нужен чисто гит пушить и статьи на Хабр писать :))

TheHost
08.08.2026 08:16да клод и сам умеет пушить и пайплайны запускать/трекать. Я сомневаюсь, что тут и текст человек писал, вон даже в комментах промахивается и пишет в общий тред. На днях был такой же другой "вчера" зареганный выдавший 3 поста за пару часов и отвечающий на комменты лонгридами через минуту. Хабр чет как-то вообще не фильтрует ИИ слоп и ботов

dmitry__ilyin Автор
08.08.2026 08:16Автор поста - Дмитрий, я работаю аналитиком блокировок в проекте. К нам стекается масса данных из России, их приходится обрабатывать и анализировать (не без нейросетей). А код, чего уж скрывать, действительно во многом пишет Клодик :)

dmitry__ilyin Автор
08.08.2026 08:16Сейчас узлов 17, к концу квартала (примерно через три месяца) по плану будет около сотни. И это не статичный набор — состав активных узлов постоянно ротируется, а не сидит годами на одних и тех же адресах.

dmitry__ilyin Автор
08.08.2026 08:16Судя по описанному, это, скорее всего, не отключение интернета целиком, а включение белых списков — когда доступен только ограниченный набор разрешённых сервисов, а остальное просто не идёт. Для таких случаев есть варианты, в том числе у нас.

Quqas
08.08.2026 08:16забивание гвоздей микроскопом
банальный wg, на наперечёт известные ip протонов\варпов отлично работает с простецкой quic маскировкой
самое сложное выяснить но не спалить при этом кашерные sni
а если wg ip незафаршмачен, то и банальные j 3-1-3 работают

liquidgel
08.08.2026 08:16Это все рандом. У кого-то до сих пор даже OVPN работает, а у кого-то со всеми ухищрениями серваки отлетают.

Quqas
08.08.2026 08:16вот именно.но по неясной причине чебуроды сагрились на xray и т.п. активном зондировании. ищут аномалии в tls и т.д. и при этом же wg банальщину лишь по верхам прикрыли. а впновцы отвечают взаимностью и продолжают усложнять вместо того чтоб упростить

mgnhabrauser
08.08.2026 08:16Позавчера openvpn в первый раз отлетел на дом.ру, при этом wg работает. А до этого пару дней не работал wg на мобильном интернете, а потом заработал)

nidalee
08.08.2026 08:16"У меня такая же нога и она не болит". Мы рады, что у вас работает. Не привыкайте!

lazarus_net
08.08.2026 08:16Что-то автор открыл Америку через форточку… вроде как необходимость шифровать весь поток и лить пустые данные при необходимости чтобы избежать статистического анализа - это базовые вещи. Оказывается это теперь глубокое экспертное знание?

hellosamurai
08.08.2026 08:16Все это несомненно очень интересно и уже разобрано в других статьях, но по факту вы чуть позади. Сейчас вопрос по большей части стоит касаемо устойчивости к белым спискам, да сами по себе белые списки очень грубой метод, который на практике показал результат неотличимый от отключения интернета вообще, но все же тенденции ведут именно к такому методу блокировок. Уже есть готовые решения с обходом через turn-сервера, однако жизнеспособность метода в будущем под большим вопросом (разумеется "паразитный" трафик, создаваемый этими тунелями, компаниям, через которые этот транзит производится, определённо не нравится).

Manson
08.08.2026 08:16Не согласен с постоянной сменой HeloClient фингерпринта, это сам по себе признак КВН, ибо люди используют один браузер. В тексте не указаны примеры обхода сибирской блокировки. Не описан признак наличия КВН, когда после установления связи куча программ или закладок браузера массово начинают долбиться по одному адресу. Не указано, что это все не работает против БС. Для большей надёжности надо точнее эмулировать работу браузера - создать с десяток каналов к разным sni, трафик распределять между ними, периодически закрывается каналы и открывая новые. Не указано, как обходится блокировка внешнего exit узла , если его определили (мой не блокируется)…

xenon
08.08.2026 08:16люди используют один браузер
Довольно смелое утверждение.
Некоторые люди используют 3-4 браузера, + видимо еще придется ставить какой-то гадки яндекс-браузер с сертификатом минцифры. А еще - curl, wget. А еще - python/requests и всякие новые модные асинхронные либы.
А еще, люди используют просто какие-то приложения (не браузеры), но эти приложения что-то качают по сети (например, запускаешь приложение на телефоне для оплаты эл.энергии - и оно же тоже общается с сервером). Это не браузер, но HTTP клиент.
Rub_paul
08.08.2026 08:16DPI в первую очередь смотрит на корреляцию между фингерпринтом ClientHello и последующей формой трафика, поэтому простое количество браузеров на хосте его мало волнует

BSOZ
08.08.2026 08:16Развертывание и постоянная поддержка инфраструктуры для обхода ограничений (будь то кастомные VPS, обфускация трафика или постоянный поиск новых протоколов) — это колоссальный и нерациональный расход девелоперского ресурса.
С точки зрения архитектуры и продуктовой стабильности, мы инвестируем время в заведомо нестабильные “костыли”, которые могут сломаться после очередного обновления ТСПУ. В то же время отечественный стек и локальные платформы за последние годы закрыли практически все базовые B2B и B2C потребности — от облачной инфраструктуры и систем оркестрации до корпоративных мессенджеров и медиасервисов.
Гораздо эффективнее один раз мигрировать на стабильные локальные альтернативы с гарантированным SLA, чем содержать инфраструктурную “черную дыру”, требующую ежедневного тушения пожаров ради доступа к зарубежным аналогам.

Rub_paul
08.08.2026 08:16Посмотрю я на вашу продуктовую стабильность, когда в отечественном облаке внезапно отвалится блочное хранилище вместе со всеми бекапами

ion_nsk_region
08.08.2026 08:16это колоссальный и нерациональный расход девелоперского ресурса.
Это если про работу, и если человек не имеет связей за пределами нашей родины.
А если у человека родственники, бывшие коллеги и друзья в разных странах, в том числе и объявленных недружественными. Всех на отечественные продукты не переведёшь.
У моего дяди внук родился, а дядя даже не может созвониться с дочерью, поздравить и порадоваться.
Иными словами, если вы не видите рационального смысла, это ещё не значит, что его нет. Это как стринги с фонариком на рыбалку брать.

Alex-ZiX
08.08.2026 08:16Такие решения хорошо работают, когда у них пользователей пару сотен. РКН на такие мелкие сервисы просто не обращает внимания, так как заткнуть каждую дырку не получится. Когда вдруг пользователей станет миллионы, они быстро направят свои усилия на конкретно этот сервис и найдут, что с ним сделать. Сервис полежит месяцок и число пользователей снова опустится до пары сотен - никто не захочет ждать, когда решаться проблемы.

Rub_paul
08.08.2026 08:16Чтоб decoy трафик не сжирал процессор, можно генерить фейковые запросы через легковесные горутины, направляя их в cdn-ноды с минимальной задержкой

dmitry__ilyin Автор
08.08.2026 08:16Спасибо, отличная идея! Действительно, лёгкие горутины вместо тяжёлых запросов - разумный способ снизить нагрузку decoy-трафика на CPU. Обязательно подниму этот вопрос на ближайшем проектном митинге.

slinkinone
08.08.2026 08:16У статьи нет структуры. Возникает вопрос - какую проблему вы решаете? Обход блокировок трафика или скорость работы сервиса при обходе таких блокировок?
Если первое, то тогда интересно иметь входные данные - для каких сервисах проводились тесты, у каких операторов они были заблокированы, затем вы меняете какие-то характеристики поведения вашего сервиса (например задержка, CDN флуд) и получаете результаты у какого провайдера сервисы "разбловировались". В статье же перечислены интересные метрики чтобы их покрутить, но совершенно не понятно как они в итоге влияют на классификацию.
Если же вы хотите раскрыть потенциал скорости обходов блокировок с помощью вашего подхода, тогда нужно в самом начале иметь референсные значения других сервисов позволяющих обходить блокировки и в итогах сравнить показатели с вашим решением.

altairvpn
08.08.2026 08:16Было бы интересно увидеть сравнение описанного подхода с VLESS + XHTTP + REALITY и с AmneziaWG в тех же сетях и при одинаковых условиях. В частности, насколько отличаются устойчивость к DPI и active probing, характерные признаки трафика и накладные расходы по latency и CPU. Интересно, какой подход лучше показывает себя на практике.

dmitry__ilyin Автор
08.08.2026 08:16Прямых бенчмарков против VLESS + XHTTP + REALITY и AmneziaWG у нас нет, поэтому здесь могу дать только качественную оценку. По устойчивости мы, думаю, выигрываем за счёт самой архитектуры: сеть распределённая, есть несколько типов узлов, активный состав ротируется, а клиент получает подписанный список узлов, поэтому единой точки отказа нет. По задержке, наоборот, скорее проигрываем - у нас больше хопов через control/exit и есть дополнительный decoy-трафик. По CPU всё менее однозначно: нагрузка сильно зависит от конкретного режима и условий, поэтому без нормального сравнительного теста я бы не стал утверждать, что кто-то здесь заведомо лучше. В общем, наш основной размен - дополнительная сложность и latency в обмен на устойчивость к блокировке инфраструктуры.

Nemoumbra
08.08.2026 08:16Для неаутентифицированного клиента такой запрос заканчивается обычным
404Может, лучше 401?
MountainGoat
Это всё красиво, но как решать другой ракурс проблемы – что добрая половина всего трафика идёт неизвестным протоколом на один, ну два, ну три одних и тех же сервера?
poige
и так далее, по индукции. ;)
MountainGoat
Ни у кого бабца не хватит, столько серверов держать. А через копеечные прокси очень падает качество соединения. А узлы для перенаправления держать - это снова сервера.
dmitry__ilyin Автор
Серверов у нас много, но мы направляем основной трафик пользователей P2P, как делал старый Skype. Всех перебить сложно.
Harkonnen
Скайп из-за этого нехило трафик выедал, когда ещё платили за мегабайты. Может стать проблемой на телефонах, они тоже в P2P участвуют?