Skip to content

REALITY — sing-box

sing-box реализует обе стороны REALITY. Входящий (подблок reality: внутри встроенного блока tls:) выдаёт себя за сторонний сайт во время TLS-рукопожатия; исходящий (также вложенный в tls:) содержит лишь публичную половину ключа и short ID.

Входящий reality

Располагается в tls.reality. У входящего и tls.enabled, и tls.reality.enabled должны быть равны true.

ПолеТипПо умолчаниюДопустимые значенияОписание
enabledboolfalsetrue | falseВключить REALITY для этого входящего. При true обычное TLS-рукопожатие заменяется рукопожатием REALITY.
handshakeInboundRealityHandshakeOptions(required)InboundRealityHandshakeOptionsЦель маскировки. Неавторизованные соединения (неверный SNI / неверный short_id) прозрачно проксируются на этот адрес, так что наблюдатель видит трафик к легитимному сайту.
private_keystring(required)<base64 X25519 private key>Приватный ключ X25519 сервера. Генерируется командой `sing-box generate reality-keypair`.
short_idbadoption.Listable[string][][<hex string>]Список разрешённых short ID (hex, чётная длина, ≤ 16 символов). Одна запись `""` разрешает клиентов без short ID.
max_time_differencebadoption.Duration0 (no limit)<duration>Максимально допустимое расхождение часов клиента и сервера. Соединения вне этого окна отклоняются. 0 отключает проверку.

Исходный код: option/tls.go:193-199 · зафиксировано на v1.13.15 (3708fa1)

handshake

Подблок handshake встраивает ServerOptions (server, server_port) и DialerOptions для маскировочного апстрима:

json
"handshake": {
  "server": "www.cloudflare.com",
  "server_port": 443,
  "bind_interface": "eth0"
}

Исходящий reality

Располагается в tls.reality внутри встроенного блока tls: исходящего.

ПолеТипПо умолчаниюДопустимые значенияОписание
enabledboolfalsetrue | falseВключить REALITY для этого исходящего.
public_keystring(required)<base64 X25519 public key>Публичный ключ X25519 сервера. Составляет пару с `private_key` на сервере.
short_idstring""<hex string>Short ID, объявляемый серверу. Должен совпадать с одной из записей `short_id` на сервере (или быть пустым, если сервер это разрешает).

Исходный код: option/tls.go:234-238 · зафиксировано на v1.13.15 (3708fa1)

Генерация ключей

sh
$ sing-box generate reality-keypair
PrivateKey: <base64-private-key>
PublicKey:  <base64-public-key>

Приватный ключ помещается в private_key на сервере; публичный — в public_key у клиентов. Short ID — произвольные hex-строки, которые вы назначаете каждому клиенту.

Примеры

Сервер — VLESS поверх REALITY, маскирующийся под www.cloudflare.com:

json
{
  "inbounds": [{
    "type": "vless",
    "tag": "vless-reality",
    "listen": "::",
    "listen_port": 443,
    "users": [{ "uuid": "...", "flow": "xtls-rprx-vision" }],
    "tls": {
      "enabled": true,
      "server_name": "www.cloudflare.com",
      "reality": {
        "enabled": true,
        "handshake": {
          "server": "www.cloudflare.com",
          "server_port": 443
        },
        "private_key": "<base64-private-key>",
        "short_id": ["", "0123456789abcdef"]
      }
    }
  }]
}

Клиент:

json
{
  "outbounds": [{
    "type": "vless",
    "server": "your.server.example",
    "server_port": 443,
    "uuid": "...",
    "flow": "xtls-rprx-vision",
    "tls": {
      "enabled": true,
      "server_name": "www.cloudflare.com",
      "utls": { "enabled": true, "fingerprint": "chrome" },
      "reality": {
        "enabled": true,
        "public_key": "<base64-public-key>",
        "short_id": "0123456789abcdef"
      }
    }
  }]
}

Примечания

  • handshake.server и handshake.server_port вместе образуют цель маскировки — в Xray это называется dest. Неавторизованные соединения прозрачно проксируются на этот адрес, поэтому картина в канале выглядит как обращение к этому сайту.
  • Исходящий намеренно минимален — только public_key и short_id. Всё остальное (SNI, ALPN, отпечаток) берётся из объемлющего блока tls.
  • tls.utls почти всегда задаётся вместе с tls.reality на исходящем. Без uTLS у ClientHello отпечаток стандартной библиотеки Go, который не похож на браузерный и сводит маскировку на нет.
  • max_time_difference — окно отклонения по расхождению часов. Задавайте его с запасом (например, 1 минута) там, где серверы и клиенты не используют общий источник NTP.

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

  • Xray-core держит все поля REALITY в одной структуре REALITYConfig (серверные и клиентские поля вместе). Цель маскировки — поле dest. См. REALITY — Xray-core.
  • mihomo разделяет структуры на входящую/исходящую и использует kebab-case в именах полей (public-key, private-key, short-id, server-names). См. REALITY — mihomo.

Исходный код: option/tls.go:193-238 · v1.13.15 (3708fa1)

Core Tutorial от Argsment