Vision (xtls-rprx-vision): зачем нужен flow
Reality прячет рукопожатие, но остаётся ещё один сигнал — паттерн самого потока. Vision (xtls-rprx-vision) — тот самый flow, который его ломает. Разбираю, что это за «TLS-в-TLS», почему он палит, и как Vision это чинит. Без команд — только механика.
Проблема, которую Reality не закрывает
Reality делает рукопожатие неотличимым от честного визита на чужой сайт. Но представь, что DPI не смотрит на хендшейк вообще, а анализирует уже установленное соединение — размеры пакетов, тайминги, ритм обмена. Здесь у классического VPN-в-TLS есть характерная сигнатура, и она никак не связана с тем, насколько красиво собрано рукопожатие.
Сигнатура берётся из простой вещи: когда ты гонишь TLS-трафик (например, HTTPS-сайт) внутри VPN, который сам обёрнут в TLS, получается двойное шифрование — TLS внутри TLS. Твой браузер шифрует запрос своим TLS, VPN оборачивает это в свой TLS. Снаружи виден TLS-record, внутри которого лежит ещё один TLS-record. И вот эта вложенность даёт узнаваемый паттерн длин: размеры внешних пакетов коррелируют с размерами внутренних предсказуемым образом, которого при обычном сёрфинге не бывает. Статистический классификатор ловит это, даже не расшифровывая ничего.
Что такое flow и откуда взялся Vision
Flow — это параметр inbound-а в VLESS, который управляет тем, как именно поток данных обрабатывается на уровне транспорта. Значение xtls-rprx-vision включает режим Vision — механизм, придуманный ровно для того, чтобы убить сигнатуру TLS-в-TLS.
Vision работает на границе между внешним TLS (тем самым, что маскируется под донора через Reality) и полезной нагрузкой. Он делает две ключевые вещи.
Первое — он не шифрует уже зашифрованное повторно. Когда Vision видит, что внутри едет TLS-трафик (а это большинство современного веба — HTTPS везде), он распознаёт внутренние TLS-records и пропускает их без второго оборачивания. Внешний слой шифрования для этих данных снимается, потому что данные и так уже зашифрованы браузером. Двойного шифрования нет — нет и коррелирующего паттерна длин. Это и есть смысл аббревиатуры: «rprx» — про перенаправление сырого потока без лишнего слоя.
Второе — он подмешивает паддинг в нужных местах. Даже после снятия двойного шифрования остаются мелкие статистические зацепки — характерные длины первых пакетов рукопожатия внутреннего соединения. Vision добавляет случайный набивочный паддинг, размывая эти длины, чтобы распределение размеров пакетов стало похоже на обычный веб-трафик, а не на туннель.
Почему Vision и Reality — это пара, а не альтернативы
Их часто путают, будто это два способа сделать одно и то же. Нет. Они работают на разных уровнях и дополняют друг друга:
- Reality отвечает за
security— то, как выглядит рукопожатие. Он прячет SNI, переиспользует чужой сертификат, делает начало соединения неотличимым от честного TLS. - Vision отвечает за
flow— то, как ведёт себя поток данных после установления соединения. Он убирает двойное шифрование и паттерн длин.
Reality без Vision закрывает хендшейк, но оставляет статистическую зацепку в потоке. Vision без Reality чистит поток, но рукопожатие светит SNI. Вместе они закрывают оба главных признака, по которым DPI ловит VPN, — рукопожатие/SNI и поведение трафика. Именно поэтому на TCP-транспорте связка security: reality + flow: xtls-rprx-vision — обязательный минимум, а не опция.
Где Vision не применяется
Важный момент, на котором легко споткнуться: Vision работает только на «сыром» TCP-транспорте (raw/tcp). На других транспортах его нет и быть не должно.
- XHTTP — транспорт поверх HTTP, у него своя механика упаковки потока, Vision там не используется. Пытаться прописать flow — ошибка, инбаунд просто не соберётся корректно.
- gRPC — мультиплекс поверх HTTP/2, тоже без Vision; поток пакуется в gRPC-вызовы, паттерн длин размывается самой природой транспорта.
- Hysteria2 — вообще QUIC/UDP, другой мир, никакого flow.
То есть Vision — специфичная штука именно для TCP-Reality. Как только ты уходишь на XHTTP или gRPC ради обхода блокировок по IP или прохода за CDN, ты меняешь модель защиты потока: там от паттерна длин защищает уже сам транспорт, а не отдельный flow. Об этом стоит помнить, когда собираешь ноду с несколькими транспортами — у TCP-инбаунда flow есть, у XHTTP/gRPC его быть не должно.
Практическая выжимка
Если свести всё к операторскому чек-листу: на TCP-Reality-инбаунде всегда ставь flow: xtls-rprx-vision на клиенте — это не украшение, а то, что реально мешает статистике вычислить твой туннель. Без него ты закрыл рукопожатие, но оставил открытым поведение потока, и под серьёзным DPI это рано или поздно вылезет. На XHTTP/gRPC/Hysteria flow не трогай — там другая защита.
Как это выглядит в реальном конфиге и где именно прописывается flow — в практических статьях по TCP-Reality. Механику ты теперь знаешь: Vision не про рукопожатие, он про то, чтобы поток данных после рукопожатия не выдавал сам себя длинами пакетов.
Следующий гайд VLESS + TLS: базовый рабочий конфиг → ↗ Не понравилась статья или что-то непонятно? Напишите мне — помогу или поправлю. @notrealvpn →