REALITY — Xray-core
REALITY — разработанная в Xray альтернатива TLS с публичным сертификатом: во время TLS-рукопожатия сервер выдаёт себя за реальный сторонний сайт, работая прозрачным прокси для неавторизованных клиентов и поднимая авторизованных до настоящей прокси-сессии. Само рукопожатие неотличимо от подключения к имитируемому сайту.
Конфигурация
Задаётся в streamSettings.realitySettings, когда streamSettings.security равно "reality". Одна и та же структура содержит поля и сервера (входящее подключение), и клиента (исходящее); на каждой стороне значима только своя половина параметров.
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
masterKeyLog | string | (unset) | <file path> | Дамп ключей в стиле SSLKEYLOGFILE для отладки. Не включайте в боевой среде. |
show | bool | false | true | false | Печатать подробную информацию о рукопожатии REALITY в журнал ошибок при каждом соединении. Только для диагностики — вывод очень объёмный. |
target | json.RawMessage | (use dest) | <host:port> | Входящее подключение — псевдоним для `dest`. Задавайте одно из двух, не оба. |
dest | json.RawMessage | (required) | <host:port> | Входящее подключение — цель маскировочного рукопожатия. TLS ClientHello проксируется на этот адрес, когда клиент не является легитимным пиром REALITY; это тот «настоящий» сайт, который увидят наблюдатели. |
type | string | (auto) | tcp | unix | Входящее подключение — протокол бэкенда для `dest`. Выводится из формы `dest`. |
xver | uint64 | 0 | 0 | 1 | 2 | Входящее подключение — версия PROXY protocol, добавляемая при пересылке на `dest`. |
serverNames | []string | (required) | [<hostname>] | Входящее подключение — SNI-имена TLS, которые оно принимает. Соединения с другим SNI пересылаются на `dest` (маскировочный путь). |
privateKey | string | (required) | <base64 X25519 private key> | Входящее подключение — закрытый ключ X25519. Генерируется командой `xray x25519`. |
minClientVer | string | (unset) | <semver> | Входящее подключение — минимальная версия Xray, которую может объявить клиент. Более старые клиенты отклоняются. |
maxClientVer | string | (unset) | <semver> | Входящее подключение — максимальная версия Xray, которую может объявить клиент. |
maxTimeDiff | uint64 | (unset) | <milliseconds> | Входящее подключение — максимально допустимое расхождение часов клиента и сервера в миллисекундах. Большее расхождение приводит к отказу в рукопожатии. |
shortIds | []string | (required) | [<hex string>] | Входящее подключение — список разрешённых коротких ID (hex, чётной длины, до 16 символов). Пустая запись `""` разрешает клиентов, не объявляющих короткий ID. Обычно каждому авторизованному пользователю выдают уникальный короткий ID. |
mldsa65Seed | string | (unset) | <base64 seed> | Входящее подключение — сид постквантовой подписи ML-DSA-65. Сочетается с `mldsa65Verify` у клиентов. |
limitFallbackUpload | LimitFallback | (unset) | LimitFallback | Входящее подключение — ограничение скорости в направлении отдачи после перехода авторизованного клиента на реальный прокси. Помогает сделать REALITY неотличимым от медленного легитимного сайта. |
limitFallbackDownload | LimitFallback | (unset) | LimitFallback | Входящее подключение — то же для направления загрузки. |
fingerprint | string | chrome | chrome | firefox | safari | edge | 360 | qq | ios | android | random | randomized | Исходящее подключение — отпечаток ClientHello uTLS. Определяет, как ClientHello выглядит на проводе. |
serverName | string | (required) | <hostname> | Исходящее подключение — SNI, отправляемый в ClientHello. Должен совпадать с одним из `serverNames` сервера. |
password | string | (required) | <string> | Исходящее подключение — пароль REALITY (открытый ключ X25519 плюс тег аутентификации). Генерируется командой `xray reality`. |
publicKey | string | (unset) | <base64 X25519 public key> | Исходящее подключение — альтернатива `password`; открытый ключ X25519 сервера напрямую. |
shortId | string | "" | <hex string> | Исходящее подключение — короткий ID, объявляемый серверу. Должен входить в список `shortIds` сервера. Пустая строка допустима, только если сервер указал `""`. |
mldsa65Verify | string | (unset) | <base64 verify key> | Исходящее подключение — ключ проверки ML-DSA-65, соответствующий `mldsa65Seed` сервера. |
spiderX | string | (unset) | /<path> | Исходящее подключение — подсказка-путь для «паука», имитирующая легитимное поведение браузера во время маскировочного рукопожатия. |
Исходный код: infra/conf/transport_security.go:27-52 · зафиксировано на v26.7.28 (5ca6f4b)
Генерация ключей
REALITY требует пары ключей X25519. Сгенерируйте её встроенной командой Xray:
$ xray x25519
Private key: <base64-private-key>
Public key: <base64-public-key>
Password: <base64-password>Private key попадает в privateKey сервера. Клиенты используют либо password (рекомендуется — упаковывает открытый ключ вместе с тегом аутентификации), либо напрямую publicKey.
Для постквантовой защиты ML-DSA-65 (необязательно):
$ xray mldsa65
Seed: <base64-seed>
Verify: <base64-verify-key>Примеры
Сервер (VLESS + REALITY, имитирующий www.cloudflare.com):
{
"inbounds": [{
"tag": "vless-reality",
"listen": "0.0.0.0",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [{ "id": "<UUID>", "flow": "xtls-rprx-vision" }],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.cloudflare.com:443",
"xver": 0,
"serverNames": ["www.cloudflare.com"],
"privateKey": "<base64-private-key>",
"shortIds": ["", "0123456789abcdef"]
}
}
}]
}Клиент, соответствующий серверу выше:
{
"outbounds": [{
"tag": "vless-reality",
"protocol": "vless",
"settings": {
"address": "your.server.example",
"port": 443,
"id": "<UUID>",
"flow": "xtls-rprx-vision",
"encryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"fingerprint": "chrome",
"serverName": "www.cloudflare.com",
"password": "<base64-password>",
"shortId": "0123456789abcdef"
}
}
}]
}Примечания
dest— это цель маскировки. Выберите реальный сайт с публично доверенным TLS-сертификатом; для неавторизованных клиентов наблюдатели видят трафик, идущий к этому сайту. Частые варианты:www.cloudflare.com,www.microsoft.com,dl.google.com.serverNamesдолжен содержать SNI, который будут использовать клиенты. Пришедший на сервер трафик с SNI не из списка молча пересылается наdest— это запасной путь, делающий REALITY неотличимым от настоящего сайта.shortIds— различение по пользователям или группам. Каждый авторизованный клиент использует одну запись из списка. Добавьте""(пустую запись), если хотите разрешить клиентов без короткого ID; для строгого режима опустите её.passwordпредпочтительнееpublicKey: он кодирует открытый ключ вместе с дополнительным тегом аутентификации, так что одного украденного открытого ключа недостаточно для аутентификации.limitFallbackUpload/limitFallbackDownloadограничивают пропускную способность авторизованных клиентов после перехода на REALITY. Подгонка этих значений под полосу реального апстрима затрудняет обнаружение REALITY по «отпечатку» пропускной способности.show: trueвыдаёт подробные журналы каждого рукопожатия REALITY — используйте только для тестирования.
Сравнение с другими ядрами
- sing-box аккуратно разделяет схему на
InboundRealityOptionsиOutboundRealityOptions, а цель маскировки вложена в под-блокhandshake. См. REALITY — sing-box. - mihomo тоже использует две структуры: исходящую
RealityOptions(толькоpublic-key+short-id) и входящуюRealityConfig(серверная сторона сdest,private-key,server-names,short-id, …). См. REALITY — mihomo.
Исходный код: infra/conf/transport_security.go:27-52 · v26.7.28 (5ca6f4b)
