Почему «выглядит случайно» не значит «выглядит нормально»
Интуитивно кажется, что идеал маскировки — поток, неотличимый от случайных байтов. Нет заголовков, нет опознаваемых полей, нет структуры: не за что зацепиться. На практике всё наоборот: отсутствие структуры само по себе является структурой, и именно по нему проще всего отделить необычное соединение от обычного.
Интуиция ошибается, и способ, которым она ошибается, определяет целое семейство проектных решений.
Классификация методом исключения#
Ошибка в постановке задачи. Цензору не нужно опознать ваш протокол. Ему достаточно установить, что это не один из известных разрешённых.
Исследование, представленное на USENIX Security в 2023 году, описало работающий классификатор полностью зашифрованного трафика. Он использовал признаки, которые не требуют понимания содержимого:
- доля установленных бит в первом полезном пакете;
- доля печатных ASCII-символов;
- расположение этих символов внутри пакета;
- отсутствие маркеров известных протоколов.
Логика простая: если это не TLS, не QUIC, не SSH, не DNS — и при этом выглядит высокоэнтропийным, то подозрительно.
Обычный интернет состоит из протоколов со структурой. Поток без структуры не растворяется в нём, а выделяется на его фоне.
Отсюда следует разделение целей#
Полезно различать два свойства, которые часто путают.
| Свойство | Что означает | Против чего работает |
|---|---|---|
| Устранение сигнатуры | нет фиксированных байт, по которым опознаётся протокол | сигнатурный поиск |
| Неразличимость | поток статистически похож на разрешённый класс | классификация по признакам |
Первое не влечёт второе. Протокол может не иметь ни одного постоянного байта и при этом попадать в класс «неизвестный высокоэнтропийный» с первой же попытки.
История Shadowsocks — учебный пример этого перехода. Ранние версии ловились по содержимому. После устранения содержательных признаков цензор перешёл к классификации первых зашифрованных пакетов по статистике — и продолжил ловить.
Цена ошибки для цензора#
У этой картины есть важная деталь, которая объясняет, почему такие классификаторы применяются осторожно.
Авторы того же исследования оценили: прямое применение восстановленных ими правил затронуло бы около 0,6% обычных TCP-соединений.
Полпроцента звучит немного, пока не переведёшь в абсолютные числа на масштабе страны. Это и есть базовая проблема цензора: при низкой доле искомого трафика даже точный классификатор даёт неприемлемое количество ложных срабатываний.
Отсюда практическое следствие: дорогая для цензора ошибка — ваша защита. Чем больше обычного трафика пострадает от правила, тем осторожнее оно применяется.
Разбор: как выглядит классификация методом исключения#
Логика классификатора умещается в короткое дерево. Обратите внимание, что вопроса «это прокси?» в нём нет вовсе.
первый полезный пакет соединения
│
├─ есть маркер TLS? ─да─► разбор TLS, проверка имени
├─ есть маркер QUIC? ─да─► разбор QUIC
├─ похоже на SSH? ─да─► пропустить
├─ похоже на DNS? ─да─► пропустить
│
└─ нет ни одного маркера
│
├─ доля печатных ASCII низкая? ─┐
├─ биты распределены равномерно? ─┼─► «неизвестный
└─ структуры не видно? ─┘ высокоэнтропийный»
│
▼
подозрительно
Идеально случайный поток проходит этот путь до самого низа и попадает в последнюю категорию. Не потому, что его опознали, а потому, что он не совпал ни с чем известным.
Обычный HTTPS сюда не доходит: он отсеивается на первой же ветке.
Числовой пример: почему полпроцента — это много#
Оценка ложных срабатываний в 0,6% звучит безобидно, пока не переведёшь в абсолютные величины.
| Соединений в сутки у среднего оператора | сотни миллионов |
| Доля ложных срабатываний | 0,6% |
| Затронутых обычных соединений | миллионы в сутки |
Это и есть причина, по которой такие правила применяются осторожно, а не повсеместно.
Дальше — прямое следствие для проектирования. Сравните два транспорта с точки зрения цензора:
| Транспорт | Ложных срабатываний при блокировке | Решение цензора |
|---|---|---|
| Случайный поток на выделенном порту | почти нет — класс узкий | заблокировать дёшево |
| Настоящий HTTPS на 443 | миллионы обычных сессий | заблокировать дорого |
Отсюда критерий, который полезнее «насколько хорошо мы спрятались»: сколько чужого трафика пострадает, если нас всё-таки решат заблокировать. Чем больше — тем устойчивее позиция, и это свойство архитектуры, а не качества маскировки.
Два полюса проектирования#
Из сказанного вырастают две противоположные стратегии, и обе жизнеспособны.
Полюс случайности. Поток стремится к неотличимости от случайных байтов, активное зондирование не получает подтверждающего ответа. Сильно против сигнатур и против пробирования, слабо против модели «неизвестное — подозрительно».
Полюс мимикрии. Транспорт использует настоящий массовый протокол — не имитирует его байты, а действительно им является. Цензор вынужден отличать валидное поведение разрешённого протокола от другого валидного поведения того же протокола.
Второй подход дороже в развёртывании, но у него есть свойство, которого нет у первого: цена ошибки переносится на цензора. Заблокировать плохо замаскированный поток дёшево. Заблокировать то, что неотличимо от массового веб-трафика, — значит задеть массовый веб-трафик.
Почему случайный паддинг не спасает?#
Частая ошибка — считать, что добавление случайного заполнения решает задачу. Заполнение меняет длины, но не добавляет структуры, а классификация методом исключения реагирует именно на её отсутствие.
Работа, представленная на USENIX Security в 2024 году, показала предел этого подхода: случайный паддинг разрушает точные сигнатуры размеров, но не скрывает общую форму — последовательность пачек, направления, число обменов до передачи полезных данных.
В частности, вложенное защищённое соединение внутри туннеля оставляет наблюдаемый след, переживающий разные виды заполнения. Увеличить каждый пакет на случайное число байт недостаточно, если по внешнему потоку по-прежнему видно, что внутри только что состоялось ещё одно рукопожатие.
Ловушка максимальной энтропии#
Отсюда вывод, противоречащий интуиции.
Правильная цель заполнения — не максимальная случайность, а соответствие распределению прикрытия. Равномерный случайный джиттер в диапазоне не делает поток похожим на браузерный — он делает его похожим на поток с равномерным случайным джиттером, а это отдельный опознаваемый признак.
Обобщённо: обфускация, выходящая за границу нормального поведения своего слоя, создаёт новый признак вместо сокрытия старого.
Наглядный пример из другой области — параметры маскировки, при которых мусорные пакеты превышают MTU и вызывают фрагментацию. Фрагментация редка для обычного трафика, и маскировка приводит к тому, ради чего затевалась наоборот.
Что из этого следует практически#
Формулируйте цель как «похоже на разрешённый класс», а не «непохоже ни на что». Вторая формулировка приводит к отдельному классу, который легко описать правилом.
Проверяйте не наличие сигнатуры, а различимость. Вопрос «есть ли у нас постоянные байты» отвечает не на тот вопрос. Правильный: «отличает ли простой классификатор наш поток от корпуса обычного трафика».
Начинайте с интерпретируемых моделей. Если решающее дерево на первых восьми пакетах уверенно отделяет ваш транспорт от обычного HTTPS, сложная защита преждевременна: у транспорта грубый отпечаток, и его надо убрать до всего остального.
Вывод#
«Выглядит случайно» и «выглядит нормально» — разные свойства, и второе труднее.
Случайность защищает от того, кто ищет известное. Она не защищает от того, кто ищет неизвестное — а именно эта постановка задачи оказалась и дешевле, и практичнее для цензора.
Долгосрочно устойчивее не тот транспорт, который лучше прячется, а тот, блокировка которого дороже обходится блокирующему.
Термины#
- Классификация методом исключения - подход, при котором подозрительным считается всё, что не опознано как известный протокол.
- Цена ошибки - ущерб для блокирующего от ограничения законного трафика — величина, ограничивающая жёсткость правил.
- Ловушка максимальной энтропии - состояние, при котором идеальная случайность делает поток заметнее, а не незаметнее.
FAQ: частые вопросы#
Разве случайный поток не идеальная маскировка?#
Нет. Обычный трафик не выглядит случайным, поэтому идеальная случайность попадает в категорию «неизвестное», а не «обычное».
Почему паддинг не решает задачу?#
Он меняет размеры, но не добавляет структуры. Неопознанное остаётся неопознанным, независимо от распределения длин.
Что тогда работает?#
Похожесть на разрешённый протокол вместо непохожести ни на что. Цель — попасть в известную категорию, а не остаться вне категорий.
Что читать дальше#
- Три оси формы трафика
- TLS-отпечаток и пост-квантовый переход
- Гайд по Xray-core
- Пройдите маршрут от настройки до диагностики в VPN-гайдах GigaTap.
- Выберите следующий шаг с помощью помощника VPN start.
- Импорт профиля под конкретное устройство — в хабе настройки клиентов.