Skip to content

REALITY — Xray-core

REALITY 是 Xray 自研的替代 TLS-with-公开证书 方案:服务器在 TLS 握手 期间冒充一个真实的第三方网站,对未授权的客户端透明回落到真站点,对 授权客户端则升级为真正的代理会话。握手本身与连接到被冒充的站点完全 无法区分。

配置

streamSettings.security"reality" 时,配置位于 streamSettings.realitySettings。同一个结构体同时承载服务端 (入站)与客户端(出站)字段;每一端只关注其中一半的选项。

字段类型默认值允许值描述
masterKeyLogstring(unset)<file path>供调试用的 SSLKEYLOGFILE 风格密钥导出文件。生产环境切勿启用。
showboolfalsetrue | false对每条连接打印详细的 REALITY 握手信息到错误日志。仅诊断使用 —— 会产生大量输出。
targetjson.RawMessage(use dest)<host:port>入站 —— `dest` 的别名。两者只设其一。
destjson.RawMessage(required)<host:port>入站 —— 伪装握手的目标。当客户端不是合法的 REALITY peer 时,TLS ClientHello 会被代理到此地址;这正是观察者会看到的「真实」站点。
typestring(auto)tcp | unix入站 —— `dest` 的后端协议。由 `dest` 的格式推断。
xveruint6400 | 1 | 2入站 —— 转发到 `dest` 时前置的 PROXY 协议版本。
serverNames[]string(required)[<hostname>]入站 —— 入站接受的 TLS SNI 列表。SNI 不在列表内的连接会被转发到 `dest`(伪装路径)。
privateKeystring(required)<base64 X25519 private key>入站 —— X25519 私钥。可用 `xray x25519` 生成。
minClientVerstring(unset)<semver>入站 —— 允许客户端声明的最低 Xray 版本。更旧的客户端会被拒绝。
maxClientVerstring(unset)<semver>入站 —— 允许客户端声明的最高 Xray 版本。
maxTimeDiffuint64(unset)<milliseconds>入站 —— 客户端与服务端之间容忍的最大时钟偏移(毫秒)。超出则拒绝握手。
shortIds[]string(required)[<hex string>]入站 —— 允许的 short ID 列表(hex,长度为偶数,至多 16 字符)。空条目 `""` 允许不声明 short ID 的客户端。每个授权用户通常分配一个唯一的 short ID。
mldsa65Seedstring(unset)<base64 seed>入站 —— ML-DSA-65 后量子签名种子。需要与客户端的 `mldsa65Verify` 配套使用。
limitFallbackUploadLimitFallback(unset)LimitFallback入站 —— 在授权客户端进入真代理后,对上行方向限速。可用于让 REALITY 看起来像一个慢速的真实站点。
limitFallbackDownloadLimitFallback(unset)LimitFallback入站 —— 下行方向的同等限制。
fingerprintstringchromechrome | firefox | safari | edge | 360 | qq | ios | android | random | randomized出站 —— uTLS ClientHello 指纹,决定线路上 ClientHello 的样貌。
serverNamestring(required)<hostname>出站 —— ClientHello 中发送的 SNI。必须在服务器 `serverNames` 之列。
passwordstring(required)<string>出站 —— REALITY 口令(X25519 公钥 + 鉴权 tag 的打包形式)。可用 `xray reality` 生成。
publicKeystring(unset)<base64 X25519 public key>出站 —— `password` 的替代形式;直接给出服务器的 X25519 公钥。
shortIdstring""<hex string>出站 —— 向服务器声明的 short ID。必须在服务器 `shortIds` 列表内;服务器列表中含 `""` 时才允许空字符串。
mldsa65Verifystring(unset)<base64 verify key>出站 —— 与服务器 `mldsa65Seed` 配套的 ML-DSA-65 验证密钥。
spiderXstring(unset)/<path>出站 —— 路径形式的 spider 提示,伪装握手期间模仿合法浏览行为。

源码: infra/conf/transport_internet.go:772-797 · 锚定版本 v26.6.1 (94ffd50)

生成密钥

REALITY 需要 X25519 密钥对。可用随 Xray 附带的命令生成:

sh
$ xray x25519
Private key: <base64-private-key>
Public key:  <base64-public-key>
Password:    <base64-password>

Private key 用于服务器 privateKey。客户端使用 password (推荐 —— 公钥 + 鉴权 tag 打包形式)或直接使用 publicKey

可选启用 ML-DSA-65 后量子保护:

sh
$ xray mldsa65
Seed:   <base64-seed>
Verify: <base64-verify-key>

示例

服务端(伪装为 www.cloudflare.com 的 VLESS + REALITY):

json
{
  "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"]
      }
    }
  }]
}

与上面服务端匹配的客户端:

json
{
  "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.comwww.microsoft.comdl.google.com
  • serverNames 必须包含客户端会使用的 SNI。SNI 不在列表内的流量会 被静默转发到 dest —— 让 REALITY 与真站点无法区分的回落路径。
  • shortIds 用于按用户或按组区分。每个授权客户端使用列表中的一项。 若想允许不声明 short ID 的客户端,加入 ""(空);要严格模式则 不要加。
  • 推荐使用 password 而非 publicKey:前者将公钥与额外鉴权 tag 打包,仅有公钥也无法通过鉴权。
  • limitFallbackUpload / limitFallbackDownload 在 REALITY 升级 之后 对授权客户端的吞吐限速。设置成与真上游带宽相近的值, 可让 REALITY 更难通过带宽指纹被检出。
  • show: true 会对每次 REALITY 握手产生大量日志 —— 仅测试使用。

跨内核说明

  • sing-box 把 schema 干净地拆分为 InboundRealityOptionsOutboundRealityOptions,伪装目标位于 handshake 子块下。参见 REALITY — sing-box
  • mihomo 也使用两个结构体:出站 RealityOptions(仅 public-key + short-id)与入站 RealityConfig(服务端含 destprivate-keyserver-namesshort-id 等)。参见 REALITY — mihomo

源码: infra/conf/transport_internet.go:772-797 · v26.6.1 (94ffd50)

由 Argsment 出品的 Core Tutorial