TIP观前提醒
本文仅给出重要的配置示例,阅读需具备相关知识
本教程基于
Xray 服务端 + Caddy 反代 + Xray 客户端构建本教程几乎全程手敲命令,不借助 3x-ui 此类面板,需要一定耐心
如果想一键部署,很遗憾,本文不适合你
XHTTP 五合一指的是在同一台 VPS 的 443 端口实现了五个出站节点:
点击查看 适用场景
(此处部分引用 @Benjamin1919 大佬的教程原文案)
出站 1:XTLS(Vision) + REALITY 直连
- 客户端 GUI 不支持 XHTTP
- 不想开启 TCP 多路复用
- 想要尽可能低的延迟与尽可能高的上下行速度
出站 2:XHTTP + REALITY 直连
- VPS 去程和回程的线路都比较好
- 想要尽可能低的延迟与尽可能高的上下行速度
出站 3:上行 XHTTP + TLS(ECH) + CDN | 下行 XHTTP + REALITY(上下行不同 SNI)
- 去程(客户端 → VPS)线路较差,回程(VPS → 客户端)线路较好
- 日常使用更偏重下载,很少上传
- 隐藏上行 SNI 防探测封锁
出站 4:XHTTP + TLS(ECH) 过 CDN
- VPS 去程和回程的线路都很差
- 不希望 VPS 的 IP 暴露在公网
- VPS 的 IP 已被墙
- 隐藏 SNI 防探测封锁
出站 5:上行 XHTTP + REALITY | 下行 XHTTP + TLS(ECH) + CDN(上下行不同 SNI)
- 去程(客户端 → VPS)线路较好,回程(VPS → 客户端)线路较差
- 日常使用更偏重上传,很少下载
- 隐藏下行 SNI 防探测封锁
目录
1. 准备工作
在开始之前,请准备好以下内容:
- 一个个人域名
- 一个通过支付验证的 Cloudflare 账号
- 一台拥有 root 完全访问权限的 VPS
NOTE为避免纠纷,本文不提供任何 VPS 商家推荐或购买指导,请自行选择。
本方案属于 Xray 前置、REALITY 回落到本机 Caddy,不需要配置
limitFallbackUpload,本文中的
<VPS_IP>、<YOUR_USER>、<YOUR_DOMAIN>均为占位符,实际操作时请替换为你的真实 IP、用户名和域名。SSH 端口以
<SSH_PORT>表示(示例为54321),请根据实际部署修改。
2. Cloudflare 配置
2.1 添加 DNS 记录
将域名托管到 Cloudflare,添加 DNS 解析记录:
| 记录类型 | 子域名 | 值 | 小黄云(Proxy) | 用途 |
|---|---|---|---|---|
| A | cdn.<YOUR_DOMAIN> | VPS IPv4 | 开启 | CDN 回源 |
| A | REALITY.<YOUR_DOMAIN> | VPS IPv4 | 关闭 | REALITY 握手直连 |
如果需要双栈,可额外添加 AAAA 记录,可复用同一个子域名。
2.2 SSL/TLS 设置
面板左侧 -> SSL/TLS -> 概述 -> 配置 -> 加密模式和源连接设置 -> 加密模式设置为 完全(严格)
面板左侧 -> SSL/TLS -> 边缘证书 -> 开启 TLS 1.3
面板左侧 -> 网络 -> 开启 gRPC
2.3 缓存规则设置
为避免 XHTTP 请求被缓存,创建缓存规则:
面板左侧 -> 缓存 -> Cache Rules -> 创建缓存规则:
- 名称:随意
如果传入请求匹配…-> 选择自定义筛选表达式-> 点击编辑表达式- 输入(替换为你的域名和路径):
(http.host eq "cdn.<YOUR_DOMAIN>") or (http.request.uri.path contains "/<YOUR_XHTTP_PATH>")缓存资格→ 设置为绕过缓存
3. 安装 Xray-core 与 Caddy
3.1 安装 Xray-core
通过官方脚本裸装(Bare-metal)并使用 systemd 管理:
推荐安装 Pre-release 版本,目前 Stable 版本还停留在 v26.3.27,新版本包含 XHTTP 修复和功能修复等
发版策略说明
RPRX(Owner):
忘公开说明一下了,关于 Xray-core 的发版策略, pre-release 有可能是实际意义上的 stable,而 latest 也不等于“没有 bug”
没标 latest 通常是因为我觉得下个 stable 该包含什么但它还没有包含,
或者单纯懒得写 release notes 那就算了下次吧,感觉比写代码都麻烦
sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install --beta如果你依然偏向
Stable,把命令的--beta去掉即为下载“正式版”
安装完成时会默认启动服务,需要先暂停:
sudo systemctl stop xray3.2 生成凭据
生成 UUID(需要两组,分别用于 Vision 和 XHTTP):
# 执行两次,得到两个不同的 UUIDxray uuidxray uuid分别记为 UUID_01 和 UUID_02,保存待用。
生成 REALITY 密钥对:
xray x25519保存输出的 Private key 和 Public key,私钥填在服务端的 config.json,公钥填在本地客户端里。
生成 shortID:
openssl rand -hex 83.3 写入 Xray 配置文件
TIP请在本地的文本编辑器,将以下代码块中的占位符替换为你自己的真实信息。替换完成后,粘贴到 VPS 终端中并回车
NOTE占位符说明:
| 占位符 | 替换为 |
|---|---|
UUID_01 | 第一组 UUID(Vision 用户) |
UUID_02 | 第二组 UUID(XHTTP 用户) |
YOUR_REALITY_PRIVATE_KEY | 刚才生成的 Private key |
YOUR_SHORT_ID | 刚才生成的 shortID |
reality.example.com | 你的 REALITY 子域名(小黄云关) |
cdn.example.com | 你的 CDN 子域名(小黄云开) |
/your-xhttp-path | 自定义路径 |
sudo tee /usr/local/etc/xray/config.json >/dev/null <<'EOF'{ "log": { "loglevel": "info" // 调试完成后可改为 "warning" }, "inbounds": [ { "listen": "0.0.0.0", // 如果需要 IPv6,改为监听 "::" "port": 443, "protocol": "vless", "settings": { "clients": [ { "id": "UUID_01", // 对应客户端出站 1 "level": 0, "email": "vision-user", "flow": "xtls-rprx-vision" }, { "id": "UUID_02", // 对应客户端出站 2/3/4/5 "level": 0, "email": "xhttp-user" } ], "decryption": "none", "fallbacks": [ { "dest": "/run/xray/xhttp_in.sock", // 处理“直连”的 XHTTP 请求 (对应客户端出站 2/3/5 的直连部分) // 当 Reality 识别出 VLESS 协议但没有 flow 时,直接丢给内部 XHTTP Socket "xver": 0 } ] }, "streamSettings": { "network": "raw", "security": "reality", "realitySettings": { "show": false, "target": "/run/caddy/tls_gate.sock", // 处理“CDN 转发”或“普通 HTTPS”请求 (对应客户端出站 3/4/5 的 CDN 部分) // 任何 Reality 不识别的流量都丢给 Caddy 处理 "xver": 0, "serverNames": [ "reality.example.com", "cdn.example.com" ], "privateKey": "YOUR_REALITY_PRIVATE_KEY", "shortIds": ["YOUR_SHORT_ID"] }, "sockopt": { "tcpFastOpen": true, "tcpCongestion": "bbr", "tcpMptcp": true } }, "tag": "VISION+REALITY", "sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"], "metadataOnly": false, "routeOnly": true } }, { "listen": "/run/xray/xhttp_in.sock", "protocol": "vless", "settings": { "clients": [ { "id": "UUID_02", "level": 0, "email": "xhttp-user" } ], "decryption": "none" }, "streamSettings": { "network": "xhttp", "xhttpSettings": { "host": "", "path": "/your-xhttp-path", "mode": "auto", "noSSEHeader": false, "scMaxEachPostBytes": 1000000, "scMaxBufferedPosts": 30, "xPaddingBytes": "100-1000", "xPaddingObfsMode": true, "xPaddingMethod": "tokenish", // 生成一个随机的 Base62 标记 "xPaddingPlacement": "queryInHeader", // 填充嵌入 Referer URL query(CF 兼容) "xPaddingKey": "t", // URL query 参数名 "xPaddingHeader": "Referer", "sessionIDPlacement": "path", "sessionIDKey": "SID", "sessionIDTable": "Base62", "sessionIDLength": "12-20" } }, "tag": "XHTTP_IN", "sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"], "metadataOnly": false, "routeOnly": true } } ], "outbounds": [ { "protocol": "freedom", "tag": "direct", "settings": {} }, { "protocol": "blackhole", "tag": "blocked", "settings": {} } ], "routing": { "domainStrategy": "AsIs", "rules": [ { "ip": ["geoip:private"], "outboundTag": "blocked" } ] }}EOF3.4 安装 Caddy
使用 Caddy 官方针对 Debian 的软件源安装:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
# 导入 GPG 密钥curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# 添加官方软件源curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
# 更新并安装sudo apt updatesudo apt install caddy -y3.5 编写 Caddyfile
TIP同理,请在本地编辑器中替换其中的占位符,替换后粘贴整段代码块至终端回车执行
sudo tee /etc/caddy/Caddyfile >/dev/null <<'EOF'# 1. REALITY 域名区块(专供 REALITY 握手与伪装网页)# 记得换成你自己的 REALITY 子域名!!!reality.example.com { # 监听 Xray REALITY 回落的 Unix Socket bind unix//run/caddy/tls_gate.sock
# 引用 acme.sh 申请的 Let's Encrypt 证书与私钥 tls /etc/caddy/certs/reality.crt /etc/caddy/certs/reality.key
log { output file /var/log/caddy/reality_access.log { roll_size 10mib roll_keep 7 roll_keep_for 168h } }
# 处理所有其他访问 # 外部扫描器或浏览器访问,直接给出伪装网页 handle { # 伪装网页路径:/var/www/html/index.html root * /var/www/html file_server }}
# 2. CDN 域名区块(处理从 Xray 回落的 CDN 代理流量)# 记得换成你自己的 CDN 子域名!!!cdn.example.com { bind unix//run/caddy/tls_gate.sock
# 申请的是多域名合并证书,引用相同的证书文件即可 tls /etc/caddy/certs/reality.crt /etc/caddy/certs/reality.key
log { output file /var/log/caddy/cdn_access.log { roll_size 10mib roll_keep 7 roll_keep_for 168h } }
# 捕获套 CDN 的出站(出站 3/4/5)传来的合法的 XHTTP 流量 # 记得换成你自己的 XHTTP 路径!!! # 记得换成你自己的 XHTTP 路径!!! # 记得换成你自己的 XHTTP 路径!!! handle /your-xhttp-path/* { reverse_proxy unix//run/xray/xhttp_in.sock { transport http { versions 2 } flush_interval -1 } }
# 可选:探针探活路径 handle /status { respond "ok" 200 }
handle /ping { respond "ok" 200 }
# 对于扫描器,直接重定向到伪装网页防扫描 # 记得换成你自己的 REALITY 子域名!!! handle { redir https://reality.example.com{uri} }}EOF请务必仔细检查你的
handle块配置,路径末尾的斜杠和星号/*不能省略XHTTP 流量请求的 URL 是动态长随机混淆参数的
如果前缀不通配,Caddy 就会将其视为未知的外部扫描探测,返回 302 伪装页
附:简单伪装导航页
如果你没有现成的网站,可以使用下面这段单文件 HTML 代码
但是后期建议让 GenAI 丰富一下,换成个人博客、OpenList 什么的
将以下代码块整体复制到终端回车执行,即可一键生成伪装站点:
sudo mkdir -p /var/www/htmlsudo tee /var/www/html/index.html >/dev/null <<'EOF'<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tech Hub</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; }
body { min-height: 100vh; display: flex; justify-content: center; align-items: center; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: linear-gradient(-45deg, #e0e7ff, #f3e8ff, #dbeafe, #ede9fe); background-size: 400% 400%; animation: gradientBG 18s ease infinite; }
@keyframes gradientBG { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
.wrapper { display: flex; flex-direction: column; align-items: center; gap: 2rem; padding: 2rem; width: 100%; max-width: 720px; }
.title { font-size: clamp(2.4rem, 6vw, 3.6rem); font-weight: 600; color: #1e293b; letter-spacing: -0.02em; text-align: center; }
.sub { font-size: clamp(0.8rem, 1.5vw, 1rem); color: #64748b; text-transform: uppercase; letter-spacing: 0.2em; border-bottom: 1px solid #cbd5e1; padding-bottom: 1rem; width: 100%; text-align: center; }
.nav { display: flex; gap: 1.5rem; padding: 1.5rem 2.5rem; border-radius: 80px; background: rgba(255, 255, 255, 0.6); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.8); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.06); flex-wrap: wrap; justify-content: center; }
.nav-item { display: flex; justify-content: center; align-items: center; width: 3.4rem; height: 3.4rem; border-radius: 50%; background: rgba(255, 255, 255, 0.4); transition: all 0.25s ease; text-decoration: none; border: 1px solid rgba(255, 255, 255, 0.6); }
.nav-item img { width: 1.6rem; height: 1.6rem; transition: transform 0.2s ease; }
.nav-item:hover { transform: translateY(-4px); background: rgba(255, 255, 255, 0.9); border-color: #94a3b8; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08); }
.nav-item:hover img { transform: scale(1.1); }
@media (max-width: 600px) { .wrapper { gap: 1.5rem; padding: 1rem; } .nav { padding: 1rem 1.5rem; gap: 1rem; border-radius: 2rem; } .nav-item { width: 2.8rem; height: 2.8rem; } .nav-item img { width: 1.3rem; height: 1.3rem; } } </style></head><body> <div class="wrapper"> <h1 class="title">Dev Center</h1> <div class="sub">Let there be light</div> <div class="nav"> <a href="https://www.google.com" class="nav-item" title="Google"><img src="https://cdn.simpleicons.org/google/1e293b" alt="Google"></a> <a href="https://github.com" class="nav-item" title="GitHub"><img src="https://cdn.simpleicons.org/github/1e293b" alt="GitHub"></a> <a href="https://dash.cloudflare.com" class="nav-item" title="Cloudflare"><img src="https://cdn.simpleicons.org/cloudflare/1e293b" alt="Cloudflare"></a> <a href="https://hub.docker.com" class="nav-item" title="Docker Hub"><img src="https://cdn.simpleicons.org/docker/1e293b" alt="Docker"></a> <a href="https://stackoverflow.com" class="nav-item" title="Stack Overflow"><img src="https://cdn.simpleicons.org/stackoverflow/1e293b" alt="Stack Overflow"></a> <a href="https://www.npmjs.com" class="nav-item" title="npm"><img src="https://cdn.simpleicons.org/npm/1e293b" alt="npm"></a> <a href="https://gitlab.com" class="nav-item" title="GitLab"><img src="https://cdn.simpleicons.org/gitlab/1e293b" alt="GitLab"></a> </div> </div></body></html>EOF3.6 用户组与运行目录设置
启动 Xray 和 Caddy 前需统一运行用户为 caddy,否则会出现 socket 权限问题:
[Info] transport/internet/tcp: REALITY: failed to dial dest: dial unix /run/caddy/tls_gate.sock: connect: permission denied进一步,为避免两个服务重启时因 RuntimeDirectory 被 systemd 清理而导致 UDS 套接字文件丢失,我们将双方的套接字放入各自所属服务的运行时目录(Xray 使用 /run/xray/,Caddy 使用 /run/caddy/):
# 统一运行用户为 caddysudo mkdir -p /etc/systemd/system/xray.service.dsudo tee /etc/systemd/system/xray.service.d/override.conf <<EOF[Service]User=caddyEOF
# 为 Caddy 启用独立的运行目录以放套接字sudo mkdir -p /etc/systemd/system/caddy.service.dsudo tee /etc/systemd/system/caddy.service.d/override.conf <<EOF[Service]User=caddyRuntimeDirectory=caddyEOF
# 重新加载 Systemd 配置sudo systemctl daemon-reload3.7 申请公有受信任证书
点击查看:为什么不能用 Caddy 自带的自动申请证书功能
NOTECaddy 默认依赖 HTTP-01 或 TLS-ALPN-01 进行 ACME 自动化证书验证,此过程的硬性前置条件是 Web 服务器必须能够直接在操作系统层面接管并监听公网的 80 或 443 端口。
在当前架构中,公网 443 端口由 Xray 独占监听,Caddy 仅绑定于内网的 Unix Socket 充当回落目标。当 Let’s Encrypt 验证集群发起 TLS-ALPN-01 请求时,流量首先到达 Xray 的 REALITY 服务端。由于该请求不具备有效的 XTLS 身份特征,REALITY 服务端会将其视为未知流量,执行透明的双向 TCP 转发(直接回落至 Caddy 的 Unix Socket)。
尽管验证流量最终送达了 Caddy,但证书申请依然会失败。因为 Caddy 的 ACME 模块在处理 TLS-ALPN-01 挑战时,强依赖于标准 443 端口监听器来挂载专用的验证证书。面对来自 Unix Socket 的回落流量,Caddy 的验证上下文无法正确匹配并下发该证书。即便 Caddy 异常响应了临时的 ACME 验证证书,由于 REALITY 服务端需持续抓取目标后端返回的 ServerHello 以缓存真实证书,这种非标准的临时证书将引发 REALITY 内部证书缓存逻辑链异常,导致整个 TLS 握手在链路中被异常阻断。
所以转而使用 acme.sh 脚本动态下发 DNS TXT 记录(即基于 API 交互的 DNS-01 验证),以实现 TLS 证书合规签发。
另外,REALITY 节点需使用真实 IP 直接承载直连流量(CDN Proxy OFF),若部署未受公共根证书信任的 Cloudflare Origin CA 证书,浏览器直接访问伪装站时会触发 TLS 错误。
第一步:获取 Cloudflare API Token
- 登录你的 Cloudflare 网页后台;
- 展开左边栏 -> 选择 管理账户 -> 账户 API 令牌;
- 点击 创建令牌;
- 令牌名称自定义;
- 权限策略 -> 编辑策略:选择
指定域名,然后下拉框选你的主域名; - 在下方的权限组列表中,点击展开
DNS & Zones类别区域 (Zone)-区域 (Zone)- 勾选读取 (Read)区域 (Zone)-DNS- 勾选编辑 (Edit)
- 令牌过期时间建议直接选择 “无过期时间”;
- 客户端 IP 地址过滤,可以什么都不填,只要你不把 Token 泄露给别人,就是安全的;或者填上运行
acme.sh脚本的服务器的公网 IP 地址; - 审核令牌 -> 创建令牌;
- 接着会给出
账户ID和CF_Token,复制并保存
第二步:在 VPS 切换至 root 并安装 acme.sh
为了后续能够全自动在后台无感续签,这一步全程在 root 用户下执行,以免权限不足导致续签后重载 Caddy 失败。
# SSH 登录 VPS 并切换到 rootsudo -i
# 设置你的真实邮箱,并安装 acme.shEMAIL="your_email@example.com"curl https://get.acme.sh | sh -s email="$EMAIL"
# 切换默认颁发机构为 Let's EncryptACME=/root/.acme.sh/acme.sh$ACME --set-default-ca --server letsencrypt第三步:隐式导入 Token 并申请证书
为防止 Token 泄露到 .bash_history 中,我们使用静默输入:
# 执行后,直接粘贴你的 Token 并回车(屏幕上不会显示)read -rsp 'Cloudflare API Token: ' CF_Tokenechoexport CF_Tokenexport CF_Account_ID="你的Account_ID"
# 申请证书 (必须同时包含 Reality 直连域名和 CDN 回源域名,否则 Cloudflare 在“完全(严格)”模式下回源会报 526 证书错误)$ACME --issue --dns dns_cf -d "reality.example.com" -d "cdn.example.com"第四步:提取证书并配置自动授权重载
我们需要把证书提取到 Caddy 的配置目录,每次续签后,私钥文件的属主会被重置为 root,这将导致低权限运行的 Caddy 无法读取私钥而崩溃。因此必须在 --reloadcmd 中加入 chown 权限交接命令:
# 创建目录mkdir -p /etc/caddy/certs
# 提取证书并设定重载命令# 安装时只需要指定主域名(第一个 -d 域名),acme.sh 会自动关联$ACME --install-cert -d "reality.example.com" \--key-file /etc/caddy/certs/reality.key \--fullchain-file /etc/caddy/certs/reality.crt \--reloadcmd "chown caddy:caddy /etc/caddy/certs/reality.* && systemctl reload caddy"NOTE证书安装后,私钥文件默认权限为
-rw-------(600),仅属主(root)可读写。
若 Caddy 以caddy用户运行,需确保其能读取。上述reloadcmd中的chown已解决属主问题。
若需进一步限制权限,可额外执行chmod 640 /etc/caddy/certs/reality.key。
TIP此时报错
Reload error for: reality.example.com / caddy.service is not active无伤大雅,因为我们在下一步才正式启动应用。
完成后,输入 exit 退出 root 环境,返回普通用户。
3.8 启动服务
启动前检查
为避免 permission denied 错误,请再次确认以下路径的属主正确:
# Caddy 日志目录sudo mkdir -p /var/log/caddysudo chown -R caddy:caddy /var/log/caddysudo chmod 755 /var/log/caddy
# 证书文件ls -la /etc/caddy/certs/# 应显示 -rw-r--r-- 1 caddy caddy reality.crt# 应显示 -rw------- 1 caddy caddy reality.key
# 若属主不是 caddy,请执行修正:sudo chown -R caddy:caddy /var/log/caddysudo chown caddy:caddy /etc/caddy/certs/reality.*sudo chmod 640 /etc/caddy/certs/reality.key正式启动:
sudo systemctl enable --now xray caddy验证状态:
systemctl show xray --property=User,Groupsystemctl show caddy --property=User,Groupls -l /run/xray/ /run/caddy/理想输出:
User=caddyGroup=
---
User=caddyGroup=caddy
# /run/xray/srwxr-xr-x 1 caddy caddy 0 ... xhttp_in.sock-rw-r--r-- 1 caddy caddy 0 ... xhttp_in.sock.lock
# /run/caddy/s-w------- 1 caddy caddy 0 ... tls_gate.sock3.9 后续更新
更新 Xray-core
官方安装脚本支持直接升级,新版本发布后,重新运行安装命令即可:
# 检查是否有新版本sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ check
# 升级到最新 Pre-release(推荐)sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install --beta脚本会自动检测版本号差异、下载新二进制、替换并重启服务。你的 config.json、override.conf、日志等配置文件全部保留,不会被覆盖。
升级后 systemd 主 service 文件会被重写为默认的
User=nobody,但override.conf(User=caddy)优先级更高,运行时用户不受影响。 若要消除Special user nobody configured警告,可手动修复:Terminal window sudo sed -i 's/User=nobody/User=caddy/' /etc/systemd/system/xray.servicesudo systemctl daemon-reload
更新 Caddy
通过 apt 更新:
sudo apt updatesudo apt upgrade caddy -y4. 客户端配置
请跳转我另一篇文章 个人 Xray-core 客户端自用配置分享
【完】
友情推荐
- 使用 Nginx 作为反代的教程:
- Debian 13 VPS 安全加固与 Xray VLESS + REALITY 手动部署
- 本文从中学习到了
read -rsp静默输入这一用法
- 本文从中学习到了
- Debian 13 VPS 安全加固与 Xray VLESS + REALITY 手动部署
- ECH 相关教程:
后话
xray-core v26.9.8 Commit 47cfe999
RPRX 移除了版本号校验:
} else { // config.MinClientVer = []byte{26, 3, 27} // errors.LogWarning(context.Background(), `REALITY: The default minimal client version is Xray-core v26.3.27...`) }并且 REALITY 库推行了强制校验 ClientHello 必须带有后量子密钥交换 X25519MLKEM768,否则判定为过时/异常握手,直接触发回落的新的抗探测规则。(嘻嘻