Files
blog/content/posts/2023-04-11-xray-reality.md
T
zhengchen.tao 45a194c955
Build and Deploy Blog / build (push) Successful in 26s
docs(xray-reality): 同步 Obsidian 笔记 v26.x 更新
- 新增 §1.4 被动监听 vs 主动探测机制说明
- 安装/密钥/配置/启动全部对齐 Xray v26.x(systemctl、xray run -test、loglevel 坑)
- ShortId 用 openssl rand -hex 8 替代弱值,maxTimeDiff 默认 60000
- dest 改 microsoft.com,监听 :: 一次绑 v4/v6
- BBR 改用 sysctl 替代第三方脚本
- 客户端表刷新到 2026,补 ALPN/Mux/Insecure 字段
2026-05-18 17:37:16 +08:00

17 KiB
Raw Blame History

title, date, lastmod, slug, tags, categories, description, draft
title date lastmod slug tags categories description draft
Xray Reality 协议:消除 TLS 指纹的现代代理方案 2023-04-11 2026-05-18 xray-reality
TLS
Xray
VLESS
Reality
X25519
代理协议
网络协议
REALITY 协议通过 TLS 1.3 key_share 字段嵌入身份标记 + 主动探测时透明回放真站,从协议层消除 TLS 指纹特征。本文从协议设计到服务端 / 客户端完整搭建。 false

整理自 bandwh.com(原文 2023-04-11),本文于 2026-05 根据 Xray-core v26.x 重新整理。
适用系统:Debian 11 / Ubuntu 22.04+ | Xray 版本:>= 1.8.0(当前 latest 见 Xray-core releases2024 起改用 CalVer,例如 v26.3.27 = 2026-03-27
文中所有 UUID / X25519 密钥均为示例值,实际部署务必使用 xray uuid / xray x25519 重新生成。


一、背景与原理

1.1 为什么需要 Reality

传统 v2ray 方案需要购买域名并生成 TLS 证书,通过各种流量伪装来规避检测。然而随着 DPI 检测能力的升级,v2ray 的 TLS/XTLS 协议特征已可被精准识别,导致 VPS 的 443 端口频繁被封锁或阻断。

Xray 1.8.0 版本推出了全新的 REALITY 协议,配合此前的 Vision 流控,组成了当前最新的协议组合:

VLESS + Vision + uTLS + REALITY

1.2 REALITY 的核心优势

特性 说明
消除 TLS 指纹 消除服务端 TLS 指纹特征,令流量与真实网站无异
前向保密 仍保有 TLS 前向保密性,历史流量无法被解密
抗证书链攻击 证书链攻击无效,安全性超越常规 TLS
无需域名 指向他人网站的 SNI,无需自己购买域名或配置 TLS
中间人防御 即使客户端配置泄露,审查方也无法进行有效中间人攻击
SNI 阻断消失 据实测,使用 Reality 后 SNI 阻断现象消失

1.3 使用前提

  • 一台可访问的 VPS(无需域名)
  • 服务端与客户端 Xray 均需 >= 1.8.0 版本
  • 443 端口不被 Nginx、Caddy 等其他程序占用
  • 不支持 CDN 代理(如 Cloudflare 橙云,会终止 TLS 让 Reality 的端到端伪装失效)。CF 灰云(DNS only 只做 DNS 解析、不接管流量,等价于直连 VPS,可正常使用

官方 GitHubhttps://github.com/XTLS/REALITY


1.4 被动监听 vs 主动探测:Reality 的抗检测机制

Reality 的伪装效果,要分「被动监听」和「主动探测」两种检测场景看才能讲清楚。

1.4.1 被动监听:完整握手时序

假设客户端配置 serverNames: ["www.microsoft.com", "microsoft.com"],连接 VPSIP 203.0.113.10)的过程:

客户端动作 检测方观察到 VPS 动作
① DNS 查询 VPS 对应的域名(若客户端直接填 IP 则跳过) 一次明文 DNS 请求;若走 DoH/DoT 加密 DNS 则看不到
② TCP 解析到 203.0.113.10,发起 TCP SYN 到 203.0.113.10:443 客户端跟某境外 IP 建立 TCP 连接 accept
③ TLS ClientHello 发送 ClientHelloSNI = www.microsoft.com,并在 key_share 字段藏入基于 Reality 公钥派生的标记 TLS 1.3 握手开始,目标看起来是 www.microsoft.comuTLS Chrome 指纹与真 Chrome 无差别 Xray 验证标记 ✓ → 接管连接
④ 后续 TLS 握手完成,进入 VLESS 加密流量 TLS 1.3 握手完成 + 加密流量,与正常访问 microsoft 无可区分特征 解密 VLESS,按 outbound 转发到目标

各被动观察手段实际看到的:

观察手段 看到的内容 能否识别?
DNS 监听(明文) 客户端查询某域名 → 203.0.113.10 普通的境外域名解析
TCP/IP 层 客户端直连 203.0.113.10:443 境外 IP 直连 443 完全合法
TLS 握手 SNI SNI = www.microsoft.com 看起来在访问 microsoft
TLS 指纹(JA3 / JA4 uTLS 模拟的 Chrome / Firefox 指纹 与真实浏览器无差别
流量大小 / 时序 TLS 1.3 + 加密流量,包大小分布跟正常 HTTPS 一致 没有 v2ray 那种规律性特征

1.4.2 主动探测:透明回放真站

Reality 真正的杀手锏是抗主动探测。检测方如果怀疑某个 IP 是代理,会主动发探测请求看看回应。三方角色:探测方 VPS (Xray Reality) 真 www.microsoft.com

  1. 探测方 → VPS:443:发送 TLS ClientHelloSNI = www.microsoft.com,但没有 Reality 标记(探测方没有服务端私钥,无法构造)
  2. VPS Xray:验证 Reality 标记失败 ✗ → 不当作合法客户端,把这条 TCP 连接透明转发dest = www.microsoft.com:443
  3. VPS → 真 www.microsoft.com:443:原样转发 ClientHello(VPS 不解密、不修改)
  4. 真 www.microsoft.com → VPS → 探测方microsoft 返回 ServerHello + 真证书 + 真页面,VPS 原样回放给探测方
  5. 探测方最终看到的:完整 TLS 1.3 握手 + microsoft 的真证书(CA 可校验) + microsoft 的真实页面内容 → 结论:这就是 microsoft 的某个边缘节点

实战验证Reality 配好后,用浏览器 IP 直连 https://<VPS-IP> 应该看到「证书 CN 是 www.microsoft.com,但浏览器报 CN 与 IP 不匹配」的警告 —— 这正是 Reality 回放在工作的铁证。能看到 microsoft 的真证书就说明回落机制 OK,反之要查 dest 出站连通性。

跟传统 v2ray + TLS 方案的关键差别

  • 传统方案v2ray + WebSocket + TLS + Nginx 反代):被探测时,VPS 上的 Nginx 用自己的证书回包。即便配了「伪装站」(反代 nginx 默认页或某个真站),证书是 nginx 自签或某个非 microsoft 域名的证书,CA 签发机制就拦住了 —— 你不可能拿到 microsoft.com 的真证书。一对比就看穿。
  • Reality 方案:不返回任何自己生成的内容。直接把探测请求中继给真 microsoft,回包就是 microsoft 自己生成的(证书 / 签名 / 内容全真),跟「客户端访问真 microsoft」一字不差。

二、服务端搭建

2.1 安装 Xray

通过官方脚本安装最新版本(必须 sudo,脚本会 self-check root):

sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

不传 --version 安装 latest;想钉版本可改为 @ install --version 1.8.0
安装完成后,Xray 可执行文件位于 /usr/local/bin/xray,配置文件位于 /usr/local/etc/xray/config.jsonsystemd 单元 xray.service(以 nobody 运行,已授 CAP_NET_BIND_SERVICE,可绑 443)。

2.2 生成 UUID + X25519 + ShortId

三件套一次出,建议合并执行避免漏:

echo '---uuid---';     sudo /usr/local/bin/xray uuid
echo '---x25519---';   sudo /usr/local/bin/xray x25519
echo '---shortid---';  openssl rand -hex 8
  • UUID:客户端身份认证
  • PrivateKey(私钥):填入服务端配置,务必保密
  • PublicKey(公钥):填入客户端配置,可多端共享。v26.x 输出写成 Password (PublicKey): ...,含义不变
  • Hash32v26.x 新增):可选 fingerprint 校验,基础 Reality 配置不需要,可忽略
  • ShortId:客户端校验位。不要写 "88" "888888" 这种弱值(容易被批量扫探到),用 openssl rand -hex 8 生成 16 字节随机十六进制

2.3 编写服务端配置文件

关键要求: 回落目标网站(dest)必须支持 TLSv1.3,建议使用国外知名大站,本例使用 www.microsoft.com。预先验证:

curl -sI --tlsv1.3 --max-time 5 https://www.microsoft.com -o /dev/null -w 'http=%{http_code}\n'   # 200 即可用

配置文件参数说明:

参数 必填 说明
id 客户端 UUID,由 xray uuid 生成
flow 使用 TCP 时填 xtls-rprx-visionH2 协议留空
dest 回落的真实境外网站,格式 域名:443
serverNames 客户端可用的 SNI 列表,需与 dest 匹配
privateKey 服务端私钥(Private key
shortIds 客户端 ID 列表,十六进制,长度为 2 的倍数,上限 16 位。openssl rand -hex 8 生成,别用弱值
maxTimeDiff 允许的最大时间差(ms),0 为不限。生产建议 6000060s),既宽容时钟漂移又防重放
show 是否输出调试信息,默认 false,排查问题时改为 true

完整配置示例(监听 :: 一次绑 v4 + v6):

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "listen": "::",
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "94b60beb-a0fd-4aff-9c7c-9a36f74022db",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "show": false,
          "dest": "www.microsoft.com:443",
          "xver": 0,
          "serverNames": [
            "www.microsoft.com",
            "microsoft.com"
          ],
          "privateKey": "<PRIVATE_KEY_FROM_xray_x25519>",
          "minClientVer": "",
          "maxClientVer": "",
          "maxTimeDiff": 60000,
          "shortIds": [
            "<openssl_rand_hex_8_output>"
          ]
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "tag": "direct"
    },
    {
      "protocol": "blackhole",
      "tag": "blocked"
    }
  ]
}

2.4 写入配置并启动

写入配置文件(heredoc 写法避免编辑器缩进问题):

sudo tee /usr/local/etc/xray/config.json > /dev/null <<'EOF'
{ ... 上方 JSON ... }
EOF
sudo /usr/local/bin/xray run -test -config /usr/local/etc/xray/config.json   # 必跑:先校验 JSON
sudo systemctl enable xray --now                                              # 启用并立即启动(开机自启已内置)

常用服务管理命令

sudo systemctl restart xray
sudo systemctl status xray
sudo journalctl -u xray -f          # 跟踪日志
sudo ss -tlnp | grep 443            # 验证监听

2.5 排错方法

v26.x 一个常见坑:默认 loglevel: warning 不打印 listening,启动后用 journalctl 只能看到 Xray 26.x started 然后就没下文了,看起来「started 但没在 listen」。这是假象 —— ss -tlnp | grep 443 能看到就 OK。要肉眼确认,把 logleveldebug 跑前台:

# 配置检查(v26.x 用 run -test,旧版的 xray test 已废弃)
sudo /usr/local/bin/xray run -test -config /usr/local/etc/xray/config.json

# 临时改 debug 跑前台,看到 [Info] transport/internet/tcp: listening TCP on [::]:443 才算 OK
sudo sed -i 's/"loglevel": "warning"/"loglevel": "debug"/' /usr/local/etc/xray/config.json
sudo timeout 5 /usr/local/bin/xray run -config /usr/local/etc/xray/config.json
# 排错完改回 warning,重启服务

常见问题排查:

  • 客户端测试超时但服务端没日志 → 流量根本没到 xray。用 sudo tcpdump -i any 'tcp port 443' -nn 看是否收到 SYN
    • 收不到 SYN → 链路问题(云防火墙没开、客户端代理设置错),跟 xray 无关
    • 收到 SYN 但客户端重传 SYN 看不到 ACK → 服务器 SYN-ACK 在回程被丢弃
    • 收到完整三次握手但 xray 日志显示 REALITY: processed invalid connection: server name mismatch → 客户端 SNI / 公钥 / shortId 不匹配
  • 客户端导入 URL 后连不上但手动填字段就好:部分 iOS 客户端(如 Shadowrocket)对 vless:// 里的 pbk sid flow 字段解析有时丢字段,优先手动填而非 URL 导入
  • 检查 443 端口占用:sudo ss -tlnp | grep 443
  • 检查 JSON 格式:sudo /usr/local/bin/xray run -test -config /usr/local/etc/xray/config.json
  • 确认 dest 支持 TLSv1.3curl -sI --tlsv1.3 https://www.microsoft.com200 即可用)
  • AWS Lightsail / GCP / 阿里云等带云防火墙的实例,OS 层 ufw 通了不算,云控制台里的实例防火墙也要单独开 443(IPv4 + IPv6 都要)

三、可选:BBR 加速

VPS 到客户端链路丢包高时,BBR 拥塞控制能显著提升 TCP 吞吐。Linux kernel ≥ 4.9 已内置 BBRUbuntu 22.04 / Debian 11 都满足),不需要第三方脚本,直接 sysctl 开启:

sudo tee /etc/sysctl.d/99-bbr.conf > /dev/null <<'EOF'
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
sudo sysctl --system

# 验证
sysctl net.ipv4.tcp_congestion_control   # 应输出 bbr
lsmod | grep bbr                          # 应看到 tcp_bbr

立即生效,无需重启。


四、客户端配置

4.1 客户端通用参数

连接服务端时需填写以下关键参数:

参数 说明
地址(Address VPS 的 IPv4 或 IPv6v6 用 [2600:...]:443 这种带方括号格式)
端口(Port 443
用户 ID 服务端配置中的 UUID
流控(Flow xtls-rprx-vision
加密(Encryption none
传输协议(Network/Transport tcp 或「原始/none」(不要套 ws/grpc
安全类型(Security reality
SNI 与服务端 serverNames 一致,如 www.microsoft.com
公钥(PublicKey 服务端生成的 Public keyv26.x 输出里叫 Password (PublicKey)
ShortId 服务端 shortIds 中的任意一项
uTLS 指纹(Fingerprint 建议填 chromefirefox
ALPN 默认 h2,http/1.1 或留空都行(不影响 Reality 握手)
多路复用(Mux 关闭Vision 与 Mux 不兼容)
TLS「允许不安全」/ Insecure 关闭Reality 自带证书校验逻辑)

4.2 客户端速查

2026 年主流客户端基本都内置了支持 Reality 的 Xray-core,下载最新版即可,无需手动切 Pre-Release

平台 客户端 下载
Windows V2rayN https://github.com/2dust/v2rayN/releases
macOS V2rayU / FoXray https://github.com/yanue/V2rayU/releases
Android V2rayNG https://github.com/2dust/v2rayNG/releases
iOS Shadowrocket(付费)/ Streisand App Store
OpenWrt PassWall2 / SSR Plus+ OpenWrt 仓库(任意 2023 年后编译版都支持)
通用核心 sing-box / Clash.Metamihomo 各发行版仓库或 GitHub

iOS Shadowrocket 注意URL 导入有时会丢字段(特别是 pbk sid fp),导致测试延迟超时但客户端不报错。遇到测速失败优先手动按 4.1 字段表填,不要依赖 URL 导入。


五、安全性深度解析

5.1 为什么使用公私钥而非仅 UUID?

传统方案若使用对称密钥(UUID),攻击者一旦获取客户端配置,即可实施中间人攻击。

REALITY 使用 X25519 非对称密钥 + TLSv1.3 key_share 机制:

  • 即使攻击者获取到客户端公钥,也无法验证某条连接是否属于 REALITY
  • 更无法进行有效的中间人攻击

REALITY 的设计原则是:默认假设客户端配置已泄露,将安全边界收敛至服务端私钥。只要服务端私钥不泄露,流量就是安全的。即使私钥泄露,攻击者也无法直接解密历史流量(前向保密),只能尝试中间人攻击,但中间人需要持有 Reality 私钥才能伪装服务端,这做不到。

建议:定期更换公私钥对,公钥可在多个客户端间安全共享。

5.2 如何解决 TLS in TLS 问题?

「TLS in TLS」指内层 TLS 握手特征暴露的问题(即加密套娃特征)。

REALITY 本身就是 TLS,可直接复用 XTLS Vision 的成熟解决方案:Vision 会对内层 TLS 握手包进行填充处理(不加密,直接发送),从而消除 TLS 套 TLS 的可识别特征。

此外,HTTP/2 与 gRPC 自带多路复用,也可配合 REALITY 使用,进一步优化网络性能。


六、注意事项

  • Reality 不支持 CDN 代理(如 Cloudflare 橙云),请勿将域名套 CDN 代理使用;CF 灰云(DNS only 仅做 DNS 解析不接管流量,等同直连 VPS,可以用(CF 在链路里只起 DNS 提供商作用)
  • dest 目标网站必须支持 TLSv1.3,建议选用 www.microsoft.comwww.icloud.comwww.apple.com 等国际知名站点。避开 Cloudflare 系(CF 站点的 TLS 指纹本身就跟检测方频繁交互,伪装效果打折)
  • 服务端 443 端口在使用期间不能被其他程序(Nginx、Caddy 等)占用,80 端口无特殊要求
  • ShortId 不要用弱值88 888888 这种),用 openssl rand -hex 8 生成 16 位随机;maxTimeDiff 别留 0,设 6000060s)防重放又宽容时钟漂移
  • 技术持续更新,请关注 Xray 官方仓库(https://github.com/XTLS/Xray-core/releases)与官方 wikihttps://xtls.github.io/)获取最新版本信息

本文最初整理自 bandwh.com2023-04,对应 Xray 1.8.0),2026-05 根据 Xray-core v26.x 全面更新。