REALITY — Xray-core
REALITY 是 Xray 自研的替代 TLS-with-公开证书 方案:服务器在 TLS 握手 期间冒充一个真实的第三方网站,对未授权的客户端透明回落到真站点,对 授权客户端则升级为真正的代理会话。握手本身与连接到被冒充的站点完全 无法区分。
配置
streamSettings.security 为 "reality" 时,配置位于 streamSettings.realitySettings。同一个结构体同时承载服务端 (入站)与客户端(出站)字段;每一端只关注其中一半的选项。
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
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> | 入站 —— 伪装握手的目标。当客户端不是合法的 REALITY peer 时,TLS ClientHello 会被代理到此地址;这正是观察者会看到的「真实」站点。 |
type | string | (auto) | tcp | unix | 入站 —— `dest` 的后端协议。由 `dest` 的格式推断。 |
xver | uint64 | 0 | 0 | 1 | 2 | 入站 —— 转发到 `dest` 时前置的 PROXY 协议版本。 |
serverNames | []string | (required) | [<hostname>] | 入站 —— 入站接受的 TLS SNI 列表。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>] | 入站 —— 允许的 short ID 列表(hex,长度为偶数,至多 16 字符)。空条目 `""` 允许不声明 short ID 的客户端。每个授权用户通常分配一个唯一的 short 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 | 出站 —— uTLS ClientHello 指纹,决定线路上 ClientHello 的样貌。 |
serverName | string | (required) | <hostname> | 出站 —— ClientHello 中发送的 SNI。必须在服务器 `serverNames` 之列。 |
password | string | (required) | <string> | 出站 —— REALITY 口令(X25519 公钥 + 鉴权 tag 的打包形式)。可用 `xray reality` 生成。 |
publicKey | string | (unset) | <base64 X25519 public key> | 出站 —— `password` 的替代形式;直接给出服务器的 X25519 公钥。 |
shortId | string | "" | <hex string> | 出站 —— 向服务器声明的 short ID。必须在服务器 `shortIds` 列表内;服务器列表中含 `""` 时才允许空字符串。 |
mldsa65Verify | string | (unset) | <base64 verify key> | 出站 —— 与服务器 `mldsa65Seed` 配套的 ML-DSA-65 验证密钥。 |
spiderX | string | (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.com、www.microsoft.com、dl.google.com。serverNames必须包含客户端会使用的 SNI。SNI 不在列表内的流量会 被静默转发到dest—— 让 REALITY 与真站点无法区分的回落路径。shortIds用于按用户或按组区分。每个授权客户端使用列表中的一项。 若想允许不声明 short ID 的客户端,加入""(空);要严格模式则 不要加。- 推荐使用
password而非publicKey:前者将公钥与额外鉴权 tag 打包,仅有公钥也无法通过鉴权。 limitFallbackUpload/limitFallbackDownload在 REALITY 升级 之后 对授权客户端的吞吐限速。设置成与真上游带宽相近的值, 可让 REALITY 更难通过带宽指纹被检出。show: true会对每次 REALITY 握手产生大量日志 —— 仅测试使用。
跨内核说明
- sing-box 把 schema 干净地拆分为
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_internet.go:772-797 · v26.6.1 (94ffd50)
