← К библиотеке
Протоколы Теория

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 →
Материал носит образовательный характер и посвящён инженерии сетевой инфраструктуры. Вы отвечаете за соблюдение законов своей юрисдикции.