🔐 VLESS Encryption: собственное постквантовое шифрование протокола

О чём заметка

Разбор VLESS Encryption (vlessenc, шифрование VLESS, mlkem768x25519plus) — слоя шифрования, который в сентябре 2025 года появился внутри самого протокола VLESS и снял его историческую зависимость от внешнего TLS. Здесь: что делает команда xray vlessenc, как читается длинная строка параметра, какая под этим криптография, что она защищает, а что нет, и главный практический вопрос — помогает ли она обходить блокировки в России и Китае (короткий ответ: напрямую нет, и RPRX — автор Xray-core, VLESS и XTLS — пишет об этом прямым текстом). Разбор слоёв стека и матрица совместимости «что с чем работает» — в карте слоёв VLESS-стека.

TL;DR

  • VLESS Encryption — отдельный шифрующий слой между протоколом VLESS и транспортом. Он не заменяет ни REALITY, ни TLS, ни Vision: те прячут соединение от цензора, а он защищает содержимое от того, кто это соединение всё-таки видит (CDN, промежуточный узел, будущий квантовый компьютер).
  • Появился в PR #5067 автора RPRX (влит 28 августа 2025). Код вышел уже в пре-релизе v25.8.29, но практический минимум — v25.9.5 от 5 сентября 2025: это первый стабильный релиз, и только в нём появился генератор xray vlessenc, а между двумя релизами формат дважды менялся несовместимо.
  • Внутри — два независимых обмена ключами: аутентификация сервера (X25519 или ML-KEM-768 — на выбор) и эфемерный гибрид ML-KEM-768 + X25519, который и даёт forward secrecy с постквантовой стойкостью.
  • Автор прямо пишет: «это шифрование не предназначено для прямого прохода через стену». Внешний вид соединения оно не меняет, поэтому против блокировок по TLS-отпечатку, SNI, IP и белым спискам эффект нулевой.
  • Настоящие сценарии применения — CDN (спрятать UUID и адрес назначения от Cloudflare), транзит через чужой узел, связка без внешнего TLS вообще, а также постквантовая защита «сверх» той, что уже есть в REALITY.
  • Побочный, но важный для практики эффект: с VLESS Encryption Vision перестал требовать прямого TCP и стал доступен поверх XHTTP, WebSocket и gRPC.
  • Главные ограничения: несовместим с fallbacks (Xray просто не стартует), не поддерживается ядром sing-box (а значит Hiddify, NekoBox, Karing), и требует обновлённого Xray-core на обоих концах.

Проблема, которую решает: у VLESS никогда не было своего шифра

Исторический факт, с которого всё начинается: сам протокол VLESS ничего не шифрует. Он передаёт версию, UUID пользователя, команду и адрес назначения открытым текстом и рассчитывает, что конфиденциальность обеспечит слой под ним — обычный TLS или REALITY. Это было сознательным решением: собственное шифрование VMess оказалось и медленнее, и заметнее для DPI, чем настоящий TLS 1.3, поэтому преемник от него отказался (подробнее — в разборе протокола VLESS).

Пока туннель идёт напрямую «клиент → сервер», такая схема работает: внешний TLS шифрует всё, включая заголовок VLESS. Проблемы начинаются там, где между клиентом и сервером появляется кто-то, кто легально расшифровывает внешний TLS.

Самый массовый такой случай — CDN. Когда VLESS заворачивают в WebSocket или XHTTP и пускают через Cloudflare, TLS-сессия обрывается на границе CDN: дальше до вашего сервера идёт отдельное соединение, а сама Cloudflare видит содержимое кадров. А в содержимом лежит открытый заголовок VLESS — 16 байт UUID, тип и адрес назначения, порт, и следом весь проксируемый поток, включая SNI сайтов, на которые вы ходите. Формально это не «утечка» — вы сами выбрали пропускать трафик через посредника, — но фактически посредник знает и кто вы, и куда вы ходите.

Проще говоря: внешний TLS защищает участок от вас до ближайшего узла, который этот TLS терминирует. Если такой узел — ваш собственный сервер, всё в порядке. Если это CDN, чужой релей или транзитный VPS, то до сервера ваш VLESS-заголовок доезжает в открытом виде.

Второй сценарий — связка вообще без внешнего TLS: транзит по внутренней сети, где HTTP/TLS запрещены или бессмысленны, или окружения вроде иранского открытого HTTP. Раньше в такой конфигурации VLESS было просто нечем защитить.

Третий — «harvest now, decrypt later» («сейчас запишем — потом расшифруем»): наблюдатель сохраняет зашифрованный трафик сегодня в расчёте расшифровать его будущим квантовым компьютером.

VLESS Encryption закрывает все три, добавляя шифрование внутри протокола — независимо от того, есть ли что-то снаружи.

Что это технически: ещё один conn поверх открытого VLESS

Реализация устроена нарочито просто, и это стоит понимать, потому что из устройства следуют почти все ответы про совместимость. RPRX формулирует принцип так: шифрование — это «дополнительный слой соединения поверх открытого протокола VLESS, не связанный с внутренним протоколом, его легко реализовать и легко заменить».

То есть в стеке появляется новая прослойка:

приложение (браузер, его собственный TLS до сайта)

протокол VLESS (версия, UUID, адрес назначения)

VLESS Encryption      ← новый слой: шифрует всё, что выше

транспорт: RAW TCP / XHTTP / WebSocket / gRPC / mKCP

слой безопасности: TLS, REALITY или none

Из этой схемы следуют два неочевидных вывода.

Криптографической связи с внешним TLS/REALITY нет. Ключи VLESS Encryption выводятся только из его собственных параметров: ни привязки к TLS-сессии (channel binding), ни экспортёра ключей в коде нет. Практический смысл: скомпрометированный CDN или подменённый сертификат снаружи не ломают конфиденциальность внутреннего слоя — это самодостаточный контур. Обратное тоже верно: внешний слой не подтверждает подлинность внутреннего и наоборот, слои просто ничего не знают друг о друге.

Ограничений на транспорт нет. Слой навешивается на любое соединение, поэтому в документации Xray прямо записано: «VLESS Encryption: no underlying transport restrictions» — никаких ограничений на нижележащий транспорт. Именно отсюда взялось важное следствие про Vision (см. раздел ниже).

Строка параметра: как читать mlkem768x25519plus.native.600s...

Настройка задаётся двумя парными полями: decryption на сервере (в settings VLESS-входа) и encryption на клиенте (в outbound или в параметре vless://-ссылки). Оба поля обязательны: пустыми их оставить нельзя, отключение пишется явно — "none".

Значение — это блоки, разделённые точками:

сервер:  метод.внешний_вид.срок_тикета[.padding.delay.padding...].ключ[.ключ...]
клиент:  метод.внешний_вид.0rtt|1rtt[.padding.delay.padding...].ключ[.ключ...]

Третий блок — единственное место, где сервер и клиент синтаксически расходятся: сервер задаёт срок жизни тикета, клиент — режим возобновления сессии.

БлокЗначенияЧто означает
Метод хендшейкаmlkem768x25519plusПока единственный. Должен совпадать у сервера и клиента. Имя оставлено «с запасом»: plus намекает на возможность подключить другие обмены ключами позже
Внешний вид (appearance)native · xorpub · randomКак выглядит трафик на проводе — разбор ниже. Должен совпадать у обеих сторон
Тикет (только сервер)600s · 100-500s · 0s600s = каждому тикету случайный срок от половины до полного, то есть 300–600 с. Диапазон задаётся явно. 0s отключает тикеты — тогда каждое соединение идёт по полному 1-RTT
Режим (только клиент)0rtt · 1rttПытаться ли возобновлять сессию по тикету или всегда делать полный обмен
Padding и delayвероятность-мин-максНабивка и задержки хендшейка, необязательный блок. Например 100-111-1111 = со 100 % вероятностью добавить 111–1111 байт; 75-0-111 = с 75 % вероятностью подождать 0–111 мс
Ключ(и)base64urlМатериал аутентификации. Несколько ключей подряд — это цепочка релеев

Если блок padding не указан, ядро подставляет свой набор — 100-111-1111.75-0-111.50-0-3333. Свой набор писать можно, но с ограничениями на первую набивку: документация требует вероятность 100 % и длину «больше нуля», а код жёстче — и минимум, и максимум первой набивки должны быть не меньше 35 байт (сообщение об ошибке так и звучит: first padding length must not be smaller than 35). Суммарный padding при этом не превышает 65553 байт.

Вот как выглядят реальные строки — именно то, что печатает генератор:

"decryption": "mlkem768x25519plus.native.600s.<X25519 PrivateKey>"
"encryption":  "mlkem768x25519plus.native.0rtt.<X25519 Password>"

В официальных примерах документации обе строки заканчиваются одинаковым ключом

На странице конфига inbound и outbound приведены примеры с одним и тем же base64-значением в конце. Это плейсхолдер, а не рабочая пара: на сервере в последнем блоке лежит приватный ключ X25519 (или seed ML-KEM-768), у клиента — публичный материал (X25519 Password или ML-KEM-768 Client). Копировать пример «как есть» в обе стороны нельзя.

Криптография: два обмена ключами, а не один

Здесь легко ошибиться, потому что в описаниях фигурирует «гибрид ML-KEM-768 + X25519», и его принимают за один механизм. На деле обменов два, и они независимы — как и в REALITY.

nfsKey — аутентификация сервера (not forward secret, «не обладающий прямой секретностью»). Это тот самый ключ из последнего блока конфига. Он бывает двух видов, на выбор, а не одновременно: либо X25519 (32 байта, компактно, но не постквантово), либо ML-KEM-768 (клиентский ключ занимает 1184 байта — на килобайт длиннее, зато квантово-стойко). Его задача — доказать клиенту, что на том конце действительно ваш сервер.

pfsKey — эфемерный сессионный обмен (perfect forward secrecy, «совершенная прямая секретность»). Вот он всегда гибридный: ML-KEM-768 и X25519 выполняются оба, их секреты склеиваются. Именно этот обмен делает записанный сегодня трафик нерасшифровываемым завтра.

Дальше оба результата склеиваются в unitedKey (96 байт), из которого функция BLAKE3 выводит все рабочие ключи. Трафик шифруется AEAD-шифром — AES-256-GCM или ChaCha20-Poly1305, выбор автоматический: клиент смотрит, есть ли у процессора аппаратное ускорение AES, а сервер при неудачной расшифровке первого блока молча переключается на второй вариант. Вариантов со 128-битным ключом нет сознательно — раз конструкция целится в постквантовую стойкость, ключи только 256-битные.

Проще говоря: один ключ отвечает за вопрос «тот ли это сервер», второй — за вопрос «сможет ли кто-нибудь расшифровать это через десять лет». Первый можно выбрать коротким, второй постквантов в любом случае.

Первое соединение: 1-RTT

RTT (round-trip time) — один полный обмен «туда-обратно». «1-RTT» означает, что перед передачей полезных данных нужен один такой круг:

  1. Клиент отправляет 16 байт случайного IV и материал nfs-обмена, затем — уже зашифрованные на nfsKey длину, свой эфемерный публичный ключ ML-KEM-768+X25519 и набивку.
  2. Сервер отвечает своим эфемерным публичным ключом (тоже под nfsKey), а под общим unitedKeyтикет (16 байт, в первых двух зашита длительность жизни) и набивку.
  3. Дальше сразу идут данные внутреннего VLESS под unitedKey — отдельного «предъявления тикета» в первом соединении нет, клиент просто запоминает выданный тикет на будущее.

Последующие соединения: 0-RTT

Получив тикет, клиент может открывать новые соединения без круга согласования: он сразу предъявляет тикет и пишет данные, а сервер отвечает шестнадцатью случайными байтами и зашифрованным внутренним протоколом. Это заметно ускоряет открытие вкладок, где каждое TCP-соединение обычно требовало собственного рукопожатия.

Тут есть тонкость, которую часто передают неверно: при 0-RTT переиспользуется только эфемерный pfsKey, а nfs-обмен выполняется заново в каждом соединении. Поэтому фактический ключ шифрования у каждого соединения свой — RPRX подчёркивает это как преимущество перед схемами, где возобновление сессии означает буквально тот же ключ.

Срок жизни тикета задаёт сервер; генератор ставит 600s, а рекомендация RPRX — около десяти минут. Захардкоженного значения по умолчанию нет.

Защита от повторов без синхронизации часов

У VMess защита от replay-атак (повторной отправки перехваченного соединения) строилась на временных метках, из-за чего клиент и сервер должны были иметь синхронные часы — расхождение ломало связь. Здесь механика другая: по тикету за одно обращение находится сессия, а сам повтор ловится вторым множеством — сервер помнит уже виденные nfsKey внутри этой сессии и на совпадении возвращает replay detected.

Часы не нужны вообще. Долгосрочный повтор отсекается двумя способами: тикет истекает, а при перезапуске Xray все тикеты становятся недействительными — состояние намеренно не сохраняется на диск.

Что защищено, а что нет

Это самая ценная часть для практики, потому что вокруг неё больше всего преувеличений.

Утечка приватного ключа сервера не позволяет расшифровать ранее записанный трафик — за это отвечает эфемерный обмен. Но позволяет провести MITM будущих соединений: злоумышленник с этим ключом может выдать себя за сервер. Оговорка про гранулярность: прямая секретность действует с точностью до окна тикета (до десяти минут), потому что pfsKey всё это время живёт в памяти сервера. Компрометация памяти работающего процесса — это не то же самое, что утечка ключа из конфига.

Утечка клиентского конфига (той самой vless://-ссылки) не даёт расшифровать ни прошлый, ни будущий трафик и не даёт возможности MITM. Причина простая: в клиентском конфиге лежит только публичный материал сервера. Это принципиальное отличие от Shadowsocks и VMess, где ключ общий: там, заполучив конфиг с вашего телефона, можно расшифровать трафик и с вашего ноутбука.

Но три вещи утечка конфига по-прежнему выдаёт полностью, и об этом стоит помнить всем, кто раздаёт ключи из публичных каналов:

  • доступ к прокси — утёкшая ссылка это рабочий клиент, чужой человек просто пользуется вашим сервером;
  • адрес и порт сервера — то есть цель для блокировки и активного зондирования;
  • при варианте аутентификации на X25519 — отложенный квантовый риск: имея конфиг, будущий квантовый компьютер сможет восстановить приватный ключ сервера и выдать себя за него. Вариант с ML-KEM-768 этого не допускает ценой лишнего килобайта в конфиге.

Три внешних вида трафика: native, xorpub, random

Параметр appearance (второй блок) определяет, как хендшейк и записи выглядят на проводе.

  • native — «как есть». Публичные ключи в хендшейке идут в открытом виде, а каждая запись данных предваряется пятибайтовым заголовком 17 03 03 LL LL — тем самым, что у записи TLS 1.3. Это сделано не для маскировки соединения целиком, а чтобы наблюдатель не заметил момент, когда Vision переходит в сквозной режим передачи.
  • xorpub — то же самое, но публичные ключи в хендшейке замаскированы XOR-гаммой. Важно понимать границу: гамма выводится из публичного ключа сервера, то есть это обфускация, а не конфиденциальность — в коде это помечено комментарием прямым текстом.
  • random — вдобавок XOR-ит пятибайтовые заголовки записей потоковым шифром AES-256-CTR, и на проводе не остаётся никакой структуры. Лишних байтов он не добавляет — заголовок есть во всех трёх режимах, — а дополнительной работы получается около 0,06 % от объёма потока: это те самые 5 байт на запись размером до 8 КБ, которые приходится прогонять через шифр.

У random есть неочевидная цена: он выключает splice

Режимы native и xorpub оставляют соединение «пробиваемым» — Vision может уйти в zero-copy передачу через ядро (splice). Режим random оборачивает соединение в отдельный XOR-слой, и ядерный splice становится невозможен: данные обязаны пройти через процесс. Для нагруженного сервера это заметная разница, а выигрыш в незаметности, как показано ниже, спорный.

Важная оговорка, которая часто теряется: «пробиваемость» native и xorpub работает только когда под шифрованием лежит голый TCP без внешнего слоя безопасности. Если под VLESS Encryption лежат TLS или REALITY, ядро запрещает splice — под шифрованием уже не сырой сокет.

И теряется не только он. В коде стоит защита «avoids double penetration»: сняв слой VLESS Encryption, Vision перестаёт разворачивать внешний TLS или REALITY и пишет прямо в них. Значит, на классической схеме TCP + REALITY + Vision включение VLESS Encryption отнимает сразу две вещи — ядерный splice и сквозной проход без второго шифрования: REALITY снова шифрует проксируемый поток, чего до этого не делал. Экономия остаётся только на AEAD самого слоя Encryption. Полная таблица условий — в карте слоёв.

Как включить

Ключи не собирают вручную — для этого есть генератор. Появился он не одновременно с самой функцией, а неделей позже, отдельным PR #5078, и попал в релиз v25.9.5:

xray vlessenc

Команда печатает две готовые пары сразу: одну с аутентификацией на X25519, вторую на ML-KEM-768, с подписью «выберите одну, не смешивайте; эфемерный обмен постквантов в любом случае». Каждая пара — это строка decryption для сервера и парная encryption для клиента.

Рядом живут более низкоуровневые команды: xray x25519 (пара X25519, используется и в REALITY), xray mlkem768 (постквантовая пара для VLESS Encryption) и xray mldsa65 — последняя относится к постквантовым подписям REALITY, а не к шифрованию VLESS, и их часто путают.

Дальше строка decryption кладётся в settings VLESS-входа на сервере, а encryption — в outbound клиента либо в параметр encryption= share-ссылки. Формат ссылок при этом менять не пришлось: параметр encryption зарезервирован в стандарте vless:// (обсуждение #716) ещё пять лет назад, допустимые значения — none либо mlkem768x25519..., а пустой строкой он быть не может.

flow при этом лучше не выключать

Частый вопрос: раз VLESS Encryption сам шифрует, нужен ли ещё flow=xtls-rprx-vision? В сентябре 2025 его задали RPRX напрямую — в контексте связки с XHTTP, — и ответ был односложным: «рекомендуется включать». Логика в том же PR: XTLS избавляет от повторного шифрования уже зашифрованного потока, то есть без него вы платите за двойную работу. Пустой flow вдобавок означает, что набивка внутреннего рукопожатия не применяется вовсе.

Генерируется один раз на вход, а не на пользователя

Пара decryption/encryption описывает криптографию входа, а не конкретного клиента — пользователи по-прежнему различаются своими UUID. Панелям и ботам, которые выдают ключи, не нужно вызывать xray vlessenc при создании каждого пользователя: строка генерируется один раз при создании входа и затем подставляется во все ссылки этого входа.

Ограничения и совместимость

fallbacks использовать нельзя. Если в VLESS-входе одновременно заданы fallbacks и непустой decryption, Xray не запускается: конфиг не проходит сборку с ошибкой "fallbacks" can not be used together with "decryption". Это не «работает хуже», а полный отказ старта, что для боевого сервера означает падение всех входов из этого конфига. Практическое следствие: вход с маскировкой под настоящий сайт через nginx придётся либо перестроить, либо развести с зашифрованным входом по разным портам.

Поддержка клиентами разделилась по ядрам, а не по названиям приложений.

ЯдроПоддержка VLESS EncryptionЧто это за клиенты
Xray-core v25.9.5+Даv2rayN, v2rayNG, v2RayTun, Happ, Streisand, V2Box, OneXray
mihomo v1.19.13+Да, поле encryptionmihomo и клиенты на нём
sing-box (upstream)Нет (проверено на v1.13.16 и v1.14.0-beta.8, август 2026)Hiddify, NekoBox for Android
sing-box-extendedДа, и клиент, и серверсборки на этом форке
Форк ядра KaringXВ коде ядра клиентская часть есть (с 26 мая 2026), но подтверждения, что приложение её использует, нетKaring
Собственные ядраShadowrocket — нет по состоянию на конец 2025; остальные проверятьShadowrocket, Stash, Loon

Ключевое здесь — версия ядра, а не версия приложения. Параметр encryption графические клиенты на Xray протаскивали из ссылки в конфиг задолго до появления шифрования, потому что поле зарезервировано в стандарте ссылок давно; работать или нет решает бинарник Xray внутри. Отсюда типичная ловушка: приложение обновилось, а ядро в нём осталось прошлогодним. Мультиядерные клиенты (Throne, NekoRay на десктопе) поддерживают шифрование на профилях, идущих через Xray, и не поддерживают на профилях через sing-box.

Любопытная деталь: mihomo получил поддержку раньше самого Xray — 27 августа 2025, портировав код прямо из непринятого ещё PR.

Лишнее поле encryption может уронить всю подписку в upstream sing-box

Оригинальный sing-box от SagerNet разбирает конфигурацию строго: разбор идёт с запретом неизвестных полей, поэтому незнакомое поле ломает весь JSON-документ, а не один узел. Единственный профиль с VLESS Encryption в общей подписке способен оставить пользователя вообще без профилей. Две оговорки: это касается подписок, которые отдаются в формате конфига sing-box (клиент, самостоятельно разбирающий vless://-ссылку, лишний параметр просто отбросит), и это свойство любого неизвестного поля, а не конкретно encryption.

Форки ведут себя иначе, и их надо разделять. sing-box-extended от shtorm-7 поддерживает VLESS Encryption полноценно, с обеих сторон: в его option/vless.go есть и клиентское поле encryption в outbound, и серверное decryption в inbound, плюс отдельный пакет protocol/vless/encryption. То есть на нём можно и подключаться к зашифрованному входу, и поднимать такой вход самому. Поддержка появилась в феврале 2026 (первый стабильный релиз с ней — v1.13.11-extended-2.0.0 от 29 апреля 2026), а код происходит из Xray-core через промежуточный форк starifly/sing-box.

С Karing сложнее: в его форке ядра клиентское поле действительно добавили 26 мая 2026, но в списке изменений приложения об этом ни слова, а профильный запрос на эту функцию мейнтейнер закрыл со словами «функции ядра — в sing-box, Karing занимается интерфейсом». Так что записывать Karing в поддерживающие рано.

На подписку всё это влияет напрямую: конфиг с полем encryption extended-сборка съест нормально, а upstream — нет. Осторожность нужна с Hiddify и NekoBox for Android (там upstream), а не со всем, что называется sing-box.

Старый клиент против нового сервера не «покажет ошибку», а зависнет или молча оборвётся. Поведение зависит от типа ключа. При аутентификации X25519 сервер ждёт 48 байт, разбирает обычный VLESS-заголовок как хендшейк и мгновенно рвёт соединение — в логах видны ошибки расшифровки, для пользователя это выглядит как «подключилось и сразу отвалилось». При аутентификации ML-KEM-768 сервер ждёт 1104 байта, которых старый клиент не пришлёт, — соединение просто висит до таймаута, и в логе сервера при этом не появляется ничего. Второй случай особенно неприятен при диагностике: жалоба «не работает» не подкреплена никакими записями.

security: "none" разрешён не всегда. С версии v26.7.11 (июль 2026) Xray отказывается собирать конфигурацию, где VLESS идёт без транспортного шифрования на неприватный адрес: vless without TLS or other encryption is prohibited unless the server address is a private IP or domain. Включённый VLESS Encryption снимает этот запрет — он официально признан заменой транспортного TLS для транзитных и non-TLS сценариев.

Две границы этого запрета стоит знать точно. Во-первых, проверка применяется только к исходящим соединениям — то есть падает конфиг клиента, а серверный вход с security: none по-прежнему стартует. Во-вторых, v26.7.11 и более поздние сборки помечены как пре-релизы: последний релиз со стабильной меткой на 6 августа 2026 — v26.3.27 от 27 марта 2026, и в нём этой проверки ещё нет.

Этот запрет — часть объявленного плана, и важно понимать его границы

RPRX формулирует этот курс дважды. 28 августа 2025 года: «постепенно ограничивать по умолчанию незашифрованный трафик в публичной сети необходимо — это даёт пользователям гарантию безопасности и защищает от случайной ошибки в конфиге; кто точно понимает, что делает, сможет включить обход сам, а новичок просто не получит незашифрованный узел». 23 декабря 2025 года — уже с этапами: «первый шаг — добавить предупреждение, в том числе для Shadowsocks, VMess и insecure; второй шаг — блокировать незашифрованный трафик в публичной сети, обойти смогут только конфигурации, которые нельзя расшарить ссылкой».

Мишень здесь — security: none вместе с encryption: none, то есть VLESS, у которого нет вообще никакой защиты. Обычный encryption=none поверх TLS или REALITY под это не подпадает и остаётся официально поддерживаемой схемой: документация прямо описывает два равноправных варианта — внешний защищённый транспорт либо VLESS Encryption. Подтверждённой даты, когда encryption=none перестанет работать в связке с TLS/REALITY, не существует.

Главный вопрос: помогает ли это против ТСПУ и GFW

Короткий ответ: само по себе — нет, и это позиция RPRX, автора и самого VLESS, и этого шифрования, а не осторожная оценка со стороны.

В описании PR #5067 стоит прямая фраза: «особо обратите внимание, это шифрование не предназначено для того, чтобы вы напрямую проходили стену; подобные протоколы давно не годятся для прямого прохода — для этого следует использовать REALITY, XHTTP, Vision». В сравнительной таблице того же PR есть строка «годится для прямого обхода», и напротив VLESS Encryption там стоит , а напротив VLESS+REALITY/TLS — ✔️.

Механика объясняет, почему так, лучше ссылки на авторитет. VLESS Encryption лежит под протоколом и над транспортом. Всё, на что смотрит российский ТСПУ (Технические Средства Противодействия Угрозам) или китайский GFW снаружи, — TLS-отпечаток клиента, SNI, IP и ASN сервера, число соединений и их тайминги — определяется внешним слоем и от включения внутреннего шифрования не меняется. Соответственно против блокировок по фингерпринту, по подсети и по белым спискам (а именно так устроены зафиксированные в России схемы, см. разбор схемы ограничений) эффект нулевой.

Точности ради: собственный внешний вид у VLESS Encryption есть — это те самые native, xorpub и random плюс настраиваемая набивка рукопожатия. Он просто расположен внутри туннеля, поэтому виден лишь тому, кто уже снял внешний слой. Единственный сценарий, где эта настройка выходит наружу, — конфигурация вообще без внешнего TLS. Любопытно, что сам RPRX в ноябре 2025 года, разбирая российские блокировки, предлагает вложить VLESS Encryption с настраиваемой набивкой внутрь REALITY именно как способ поменять признаки трафика без правки кода — то есть рассматривает его и как рычаг влияния на форму, хотя от прямого обхода отговаривает.

Про Китай и режим random: распространённая ошибка

Логика «включу random, трафик станет случайным и неотличимым» в китайских условиях работает против пользователя. GFW с 2021 года применяет классификатор полностью зашифрованного трафика: он смотрит на первый пакет с данными и пропускает соединение, если срабатывает хотя бы одно из пяти исключений — доля единичных битов выходит за пределы 3,4–4,6 на байт; первые шесть или больше байт печатные; больше половины байтов печатные; есть цепочка длиннее двадцати подряд идущих печатных байт; начало похоже на TLS или HTTP. Случайные данные не удовлетворяют ни одному условию — и попадают под блокировку (работа USENIX Security 2023, PDF). Сам RPRX это подтверждает: «GFW уже занёс полностью случайный внешний вид в чёрный список».

native тоже не спасает от этого классификатора

Соблазнительно решить, что раз native «менее случаен», он безопаснее. Но классификатор GFW анализирует только первый пакет с данными, а первый пакет VLESS Encryption во всех трёх режимах начинается с 16 байт случайного IV и материала обмена ключами. TLS-подобный заголовок 17 03 03 в начало первого пакета не попадает: в режиме 1-RTT он появляется только со следующей записи, а в 0-RTT лежит внутри того же пакета, но уже за материалом рукопожатия — примерно на сотом байте. Правило, дающее освобождение по сигнатуре TLS, смотрит именно на начало, а на общую энтропию пять байт не влияют. Поэтому по энтропии native, xorpub и random для классификатора выглядят одинаково. Это вывод из кода и опубликованного алгоритма, а не результат измерения: опубликованных замеров VLESS Encryption против GFW нет.

Масштаб угрозы стоит понимать точно, потому что его легко и преувеличить, и преуменьшить. Блокировка применяется вероятностно — примерно к 26 % соединений, идущих к уже затронутым диапазонам адресов, а не к четверти всего трафика: если ваш сервер попал под правило, повторные попытки быстро добьют оставшееся. Действует это только на TCP-трафик из Китая наружу и только для части адресов — заметно затронуты ASN хостеров, а Cloudflare и Akamai нет. Блокируется тройка «клиент — сервер — порт» на 120 или 180 секунд. Основные измерения относятся к ноябрю 2021 — сентябрю 2022, но авторы отдельно отмечают, что 16 февраля 2023 перепроверили эксперименты и все правила детекта подтвердились. Данных за 2026 год нет.

Что реально даёт VLESS Encryption пользователю из России

Три конкретных выигрыша, каждый со своей оговоркой.

Vision стал доступен на любом транспорте. Раньше выбор был жёстким: либо xtls-rprx-vision на прямом TCP, либо CDN-транспорт вроде XHTTP и WebSocket — но без Vision. Документация Xray теперь описывает две ситуации, в которых XTLS доступен: TCP + TLS/REALITY и VLESS Encryption — причём во втором случае «ограничений на нижележащий транспорт нет». Оговорка: на не-TCP транспорте пропадает ядерный splice — но не весь выигрыш по скорости. Документация формулирует это так: если нижний транспорт не TCP, ядро «пробивает только слой Encryption, экономя его накладные расходы»; на TCP дополнительно пробует splice. То есть один полный проход шифрования по всему потоку снимается в любом случае. Подробности комбинаций — в карте слоёв.

CDN больше не читает, кого и куда вы проксируете. Это ровно тот сценарий, ради которого шифрование и создавалось: «применимо к CDN (избежать раскрытия UUID и проксируемого SNI), к транзиту, к non-TLS». Оговорка обязательная: CDN по-прежнему видит адрес вашего сервера, объёмы и тайминги, и располагает собственными эвристиками детекта туннелей — то есть корректно говорить «CDN не может прочитать содержимое», а не «CDN видит только шум».

Постквантовая защита сверх той, что уже есть. Здесь важно не преувеличить: утверждение «REALITY не постквантов» на 2026 год неверно. REALITY поддерживает гибридный обмен X25519MLKEM768 (если его поддерживает сайт-донор) и с июля 2025 — опциональную постквантовую подпись ML-DSA-65. Так что VLESS Encryption даёт не закрытие дыры, а эшелонирование: его преимущество в том, что сам обмен ключами зашифрован (у TLS и REALITY key share лежит на проводе открытым), и в том, что защита не зависит от того, поддерживает ли ваш донор нужные алгоритмы.

Задокументированных случаев блокировки именно VLESS Encryption нет — как и подтверждений, что связка с ним живёт дольше. Проверка форума net4people/bbs и русскоязычных публикаций за 2026 год не дала ни одного наблюдения в ту или другую сторону. Любые утверждения вида «с vlessenc не блокируют» на сегодня — домыслы.

Как мигрировать существующий парк ключей

Отдельная практическая тема: включить VLESS Encryption на новом входе просто, а вот перевести сотню уже выданных ключей — операция с реальным риском. Ключевое свойство, из которого всё следует: уже скопированная пользователем строка vless:// не изменится сама. После серверной миграции старая ссылка перестаёт соответствовать входу, и клиент обязан заново получить ссылку — из бота, панели или обновлением подписки.

Отсюда порядок, который снимает большинство граблей:

  • Разделить входы на три группы: совместимые (можно мигрировать), с fallbacks (мигрировать нельзя, Xray не стартует) и legacy, которые решено не трогать.
  • Не менять UUID пользователей, адрес, порт, SNI и параметры REALITY — миграция должна затрагивать только decryption на сервере и encryption в ссылках, иначе отладка превращается в гадание.
  • Проверить, что идентификаторы входов не вычисляются из изменяемых полей. Если панель или бот выводит числовой ID из тега входа, правка тега порвёт связи между базой, ключами и клиентами внутри Xray — признак совместимости лучше хранить отдельной пометкой, а тег оставить прежним.
  • Снять свежий план прямо перед применением и проверить, что состав клиентов не изменился с момента планирования, — если ключи выдаются параллельно, устаревший план затрёт новых пользователей.
  • Сделать резервную копию базы до изменений и проверить её целостность, а не просто скопировать файл.
  • После применения сверить сохранённую конфигурацию с реально загруженным состоянием Xray: перезапуск не должен потерять ни одного клиента.
  • Проверить не только конфиг, но и живое подключение существующим пользовательским ключом — через публичный адрес и порт, до реального HTTPS-ресурса.
  • Предупредить пользователей, что нужно переимпортировать ссылку, и отдельно — что владельцам клиентов на sing-box переходить нельзя.

Как это выглядит на практике

Опыт живой миграции трёх боевых входов (89 ключей, август 2026): связка TCP + REALITY + VLESS Encryption + flow=xtls-rprx-vision работает — реальные подключения существующими ключами прошли на всех трёх узлах, состав клиентов после перезапуска Xray совпал с сохранённым до единицы. А вот вход с gRPC + TLS и настоящими fallbacks пришлось оставить в старом формате: совместить его текущую схему с decryption без перестройки транспорта нельзя.

Стоит ли включать

Практический вывод

Включать имеет смысл там, где есть посредник или отсутствует внешний TLS: связки через CDN, транзит через чужой узел, каскады, конфигурации с security: none. Для классической схемы TCP + REALITY + Vision напрямую с клиента на свой сервер VLESS Encryption не обязателен: конфиденциальность там уже обеспечена, а прибавка — эшелонированная постквантовая защита ценой совместимости и, что менее очевидно, ценой двух вещей сразу: ядерный splice на этой схеме перестанет включаться, а REALITY снова начнёт шифровать проксируемый поток, который до этого проходил насквозь.

Чего делать не стоит — массово менять encryption=none на существующих ключах без подготовки. Клиенты на sing-box отвалятся полностью, а входы с fallbacks вообще не поднимутся. Правильный порядок — отдельный новый вход или проверенная поэтапная миграция по чек-листу выше.

📚 См. также


🤖 Эти статьи открыты — можно обучать на них ИИ

При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование и скачивание всего репозитория одним zip-архивом доступны в Forgejo: исходник этой заметки · весь репозиторий.