Skip to content

VLESS — Xray-core

VLESS — флагманский протокол Xray без состояния. Внутри самого протокола нет симметричного шифра; конфиденциальность и целостность обеспечивает внешний слой TLS / REALITY. Рукопожатие несёт UUID пользователя и небольшой блок «addons» (в первую очередь — алгоритм flow).

Входящий

settings для входящего с "protocol": "vless":

ПолеТипПо умолчаниюДопустимые значенияОписание
users[]json.RawMessage<user object array> | …Список учётных записей входящего; та же форма объекта, что и у `clients`. `users` — более новое имя, появившееся в свежих версиях Xray и принимаемое наряду с `clients`.
clients[]json.RawMessage(required)<user object array>Список принимаемых пользователей. Каждая запись содержит как минимум `id` (UUID) и опционально `email`, `level`, `flow`, `testseed`, `reverse`. Установка `encryption` у клиента входящего отклоняется.
decryptionstring(required)none | mlkem768x25519plus.<mode>.<seconds>.<keys>Должно быть задано явно. `none` — классический режим VLESS без шифрования. Строка на основе mlkem включает новое постквантовое шифрование — формат см. в примечаниях ниже.
fallbacks[]*VLessInboundFallback[]<VLessInboundFallback array>Резервные назначения, к которым обращаются, когда входящее рукопожатие TLS-с-VLESS не похоже на VLESS (например, случайный HTTPS-запрос). Взаимоисключимо с `decryption`, отличным от `none`.
flowstring(empty) | xtls-rprx-visionFlow по умолчанию для клиентов, не задавших собственный. `xtls-rprx-vision` включает XTLS Vision; пустое значение отключает flow.
testseed[]uint32[]<uint32 array>Значения seed для детерминированного тестового режима шифровального набора. Почти всегда опускается.

Исходный код: infra/conf/vless.go:33-40 · зафиксировано на v26.7.28 (5ca6f4b)

clients[] — объект пользователя

Объект пользователя декодируется из JSON в структуру vless.Account, опирающуюся на protobuf. Значимые поля:

ПолеТипПо умолчаниюДопустимые значенияОписание
idstring (UUID)обязательно<UUID>UUID клиента. Каноническая форма 8-4-4-4-12 или hex без дефисов.
emailstring""<string>Метка в выводе статистики / журналов.
leveluint320<level>Ищется в policy.levels.
flowstringнаследует flow"", xtls-rprx-visionПереопределение flow для конкретного пользователя.
testseed[]uint32наследуетсяПереопределение тестового seed для пользователя.
encryptionstringзапрещеноНе допускается у клиентов входящего.
reverse{tag,sniffing?}(не задано)VLessReverseConfigПривязывает пользователя к тегу реверс-прокси. sniffing внутри блока reverse у входящего не допускается.

fallbacks[]

ПолеТипПо умолчаниюДопустимые значенияОписание
namestring(unset)<TLS server name>Сопоставляется с SNI входящего TLS; пустое значение совпадает с любым.
alpnstring(unset)h2 | http/1.1 | Сопоставляется с согласованным ALPN; пустое значение совпадает с любым.
pathstring(unset)/<path>Префикс HTTP-пути, используемый при проксировании. Если непустой, должен начинаться с `/`.
typestring(auto)tcp | unix | serveПротокол бэкенда. Если опущен, выводится из `dest`: числовой порт или host:port → tcp; абсолютный путь или путь с префиксом @ → unix; `serve-ws-none` → serve.
destjson.RawMessage(required)<host:port> | <port> | <unix path>Куда пересылать рукопожатие. Голое целое число трактуется как порт на localhost.
xveruint6400 | 1 | 2Версия PROXY-протокола, добавляемая перед пересылаемым соединением. 0 — отключено.

Исходный код: infra/conf/vless.go:24-31 · зафиксировано на v26.7.28 (5ca6f4b)

Цепочка fallback проходится в порядке объявления по первому байту входящего соединения, когда оно не похоже на VLESS. Порядок полей важен: совпадения проверяются по кортежам (name, alpn, path), побеждает первое совпадение. Разбор dest см. в infra/conf/vless.go:149-200.

Исходящий

settings для исходящего с "protocol": "vless":

ПолеТипПо умолчаниюДопустимые значенияОписание
address*Address(unset)<host>Упрощённая форма — имя хоста или IP сервера. Если задано, `vnext` строится внутренне, а верхнеуровневые `id`, `flow` и т. д. читаются напрямую.
portuint16(required with address)<port>Порт сервера (упрощённая форма).
leveluint320<uint32>Уровень пользователя (упрощённая форма) — ключ в таблице политик.
emailstring(unset)<string>Идентификатор пользователя, отображаемый в статистике.
idstring(required with address)<UUID>UUID пользователя (упрощённая форма). Принимается и каноническая форма, и hex без дефисов.
flowstring(empty) | xtls-rprx-vision | xtls-rprx-vision-udp443Алгоритм flow.
seedstring(unset)<string>Seed шифрования (зарезервировано). Сейчас разбирается, но не применяется — оставлено для прямой совместимости.
encryptionstring(required)none | mlkem768x25519plus.<mode>.<rtt>.<keys>Должно быть `none` или строка шифрования mlkem. Всё остальное отклоняется.
reverse*VLessReverseConfig(unset)VLessReverseConfigНеобязательная привязка тега реверс-прокси для обратных туннелей на стороне исходящего.
testpreuint320<uint32>Счётчик предварительных проверок для детерминированного тестового режима.
testseed[]uint32[]<uint32 array>Значения seed для детерминированного тестового режима.
vnext[]*VLessOutboundVnext(use simplified shape)[{address,port,users:[user]}]Полная форма — должна содержать ровно один сервер с ровно одним пользователем. Для нескольких конечных точек используйте по одному исходящему на сервер и балансировщик.

Исходный код: infra/conf/vless.go:245-258 · зафиксировано на v26.7.28 (5ca6f4b)

Упрощённая форма vs. vnext

Исходящий принимает либо упрощённую верхнеуровневую форму (address, port, id, flow, ...), либо полную форму vnext — но не обе сразу. Упрощённая форма внутренне переписывается в массив vnext из одного элемента (infra/conf/vless.go:251-259). Полная форма должна содержать ровно один сервер с ровно одним пользователем; для многосерверных схем используйте несколько исходящих VLESS и балансировщик маршрутизации.

Примеры

Минимальный входящий с одним пользователем и XTLS Vision:

json
{
  "inbounds": [
    {
      "tag": "vless-in",
      "listen": "0.0.0.0",
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [
          { "id": "a3482e88-686a-4a58-8126-99c9df64b7bf", "flow": "xtls-rprx-vision" }
        ],
        "decryption": "none"
      },
      "streamSettings": { "network": "tcp", "security": "tls" }
    }
  ]
}

Упрощённый исходящий:

json
{
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "address": "example.com",
        "port": 443,
        "id": "a3482e88-686a-4a58-8126-99c9df64b7bf",
        "flow": "xtls-rprx-vision",
        "encryption": "none"
      },
      "streamSettings": { "network": "tcp", "security": "reality", "realitySettings": { /* ... */ } }
    }
  ]
}

Примечания

  • decryption и encryption обязательны. Их отсутствие даёт ошибку please add/set "decryption":"none" to every settings (infra/conf/vless.go:140) или соответствующую ошибку исходящего.
  • Строка шифрования на основе mlkem разбирается встроенным замыканием в Build (infra/conf/vless.go:95-137 — входящий, 321-357 — исходящий). Формат: mlkem768x25519plus.<mode>.<seconds-or-rtt>.<keys-and-padding>, где mode — native, xorpub или random; seconds — <from> или <from>-<to> (входящий) либо 1rtt/0rtt (исходящий); ключи — значения по 32 или 1184 байта в base64 (URL-safe), а короткие строки используются как заполнение.
  • Единственное значение flow, принимаемое текущим исходным кодом, — xtls-rprx-vision; исходящий дополнительно принимает суффикс -udp443.
  • fallbacks нельзя сочетать с decryption, отличным от none (infra/conf/vless.go:145-147).
  • fallbacks[].xver > 2 отклоняется. Принимаются только версии 0/1/2 PROXY-протокола.

Сравнение с другими ядрами

  • sing-box использует users[].uuid вместо clients[].id в Xray и users[].name вместо email. См. VLESS — sing-box.
  • mihomo имеет единственную форму исходящего (в YAML нет асимметрии входящий/исходящий); UUID пользователей хранятся прямо на объекте прокси, а не в массиве clients. См. VLESS — mihomo.

Исходный код: infra/conf/vless.go:24-258 · v26.7.28 (5ca6f4b)

Core Tutorial от Argsment