这次遇到的现象是:3x-ui 面板能打开,订阅也能生成,但客户端里的 VLESS 和 Hysteria2 节点都无法使用。表面看起来像端口、防火墙或客户端配置问题,最后却是两个完全不同的协议层故障叠在一起。
本文隐去了服务器地址、端口、UUID、订阅 ID、密钥和登录凭据。命令中的域名、路径和端口都是示例,实际操作前请换成自己的值。
先说结论
- VLESS + TCP + Reality 的服务进程和端口都正常,真正失败的是 Reality 伪装目标的 TLS 握手。目标站点的证书记录数超过 Xray Reality 当前可解析的上限,导致服务端在握手阶段直接断开连接。
- Hysteria2 使用了自签名证书,证书的 CN/SAN 与订阅里的 SNI 虽然能对上,但客户端没有开启不安全模式,因此严格校验证书链时会拒绝连接。
- 修复不能只看“端口是否监听”。最终必须分别验证 TCP/Reality 握手、QUIC/TLS 证书和真实客户端订阅,三者缺一不可。
环境与症状
故障服务器是 Debian 13,运行 3x-ui 3.7.0 和 Xray-core 26.7.28,配置了两类入站:
| 入站 | 传输 | 现象 |
|---|---|---|
| VLESS | TCP + Reality | 节点显示在线,但客户端连接后立即断开 |
| Hysteria2 | QUIC/UDP + TLS | 节点无法建立连接,严格校验模式报证书错误 |
面板本身可以访问,订阅链接也能返回内容。为了避免把“面板正常”误判成“节点正常”,我先从服务状态和监听状态开始。
第一步:先排除服务、端口和防火墙
在服务器上执行:
systemctl status x-ui --no-pager
ss -lntup | grep -E 'xray|x-ui|你的端口'
journalctl -u x-ui -n 100 --no-pager
这里要同时观察四件事:
x-ui是否为active (running);- Xray 是否真的监听了对应的 TCP 和 UDP 端口;
- 日志中是“没有监听”还是“已经收到连接但握手失败”;
- 云安全组、主机防火墙和运营商入口规则是否放行了正确的协议。
这次检查显示服务正常,TCP/UDP 端口都在监听,连接计数也有变化。也就是说,请求确实已经到达 Xray,继续盯着防火墙没有意义,应该转向协议日志和生成后的 Xray 配置。
第二步:定位 Reality 的握手失败
1. 不要只看面板,检查生成配置
3x-ui 保存的是面板数据,真正运行的是它生成的 Xray 配置。需要确认 realitySettings 中的目标、serverNames 和密钥来自同一套配置,例如:
{
"realitySettings": {
"target": "example.com:443",
"serverNames": ["example.com"],
"privateKey": "<redacted>",
"shortIds": ["<redacted>"]
}
}
客户端的 SNI 必须落在 serverNames 中,服务端和客户端的公钥、短 ID 也必须来自同一个入站。确认这些字段没有被订阅缓存或旧配置覆盖后,再看目标站点本身。
2. 目标站点的证书链也可能让 Reality 失效
我用 Xray 自带的 TLS 探测检查目标站点:
xray tls ping example.com:443
原配置的目标站点证书链包含约 8273 条记录,超过 Reality 当前实现可处理的 8192 限制。结果不是“证书不受信任”,而是 Reality 在解析握手材料时无法完成协商,客户端通常只看到 EOF、连接重置或握手超时。
这个问题很容易误判,因为服务器没有改配置,目标网站却可能因为 CDN、证书轮换或新增中间证书而突然变得不可用。Xray 项目的 #6356 问题记录 也记录了同类的证书链过长现象;Reality 的字段含义和目标选择可以对照 官方配置文档。
3. 用 A/B 测试确认,而不是凭感觉换配置
为了排除客户端软件、密钥和网络路径,我复制运行配置到临时文件,只改变 Reality 的目标站点:
cp /path/to/config.json /tmp/xray-check.json
xray run -c /tmp/xray-check.json
原目标依旧在握手阶段失败;换成另一台证书链较短、支持 TLS 1.3 的稳定站点后,服务端日志出现 uConn.Verified: true,再通过本地 SOCKS 代理发起请求也能得到服务器出口地址。这说明端口、防火墙、Reality 密钥和客户端链路都没有问题,故障点就是目标站点的握手材料。
修复时不要把某个域名当作永久答案。应该先用 xray tls ping 检查候选目标,再确认目标的 443 服务稳定、证书链可解析,并让 target 与 serverNames 保持一致。本文这次验证通过的候选目标只是一次 A/B 结果,后续仍应定期复测。
第三步:定位 Hysteria2 的证书问题
Hysteria2 的服务端配置指向了一张本地自签名证书,证书的 CN/SAN 是某个公共域名;订阅导出的 SNI 也使用了这个名字,但客户端没有 insecure 或证书 pin。于是会出现这样的链路:
- UDP 端口可达,说明网络层没有完全阻断;
- QUIC 能收到握手,但 TLS 证书链不受信任;
- 严格校验的客户端拒绝连接,表现为“节点不可用”。
临时测试可以在客户端显式关闭校验,但生产配置不应该依赖自签名证书。更稳妥的做法是使用可信 CA 签发的证书,并确保证书 SAN 覆盖订阅里的 SNI:
{
"tlsSettings": {
"serverName": "your-domain.example",
"certificates": [
{
"certificateFile": "/path/to/fullchain.pem",
"keyFile": "/path/to/privkey.pem"
}
]
}
}
3x-ui 不同版本对 Hysteria2 字段的外层结构可能略有差异,上面的片段只强调证书、SNI 和完整链之间的关系;实际修改应以面板生成的配置为准,不要整段照抄覆盖其他字段。
如果暂时只能使用 IP 访问,就申请包含该 IP 的证书,并把 SNI、证书 SAN 和服务端 serverName 统一成这个 IP;同时确认 ACME 续期任务正常。域名证书通常更容易迁移,也更适合长期维护。
修复时的安全流程
1. 先备份,再停服务
直接修改 3x-ui 数据库或生成配置前,先做可恢复备份:
backup_dir="/root/x-ui-backup-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$backup_dir"
cp -a /etc/x-ui/x-ui.db* "$backup_dir/"
systemctl stop x-ui
如果使用面板修改,备份仍然有价值;如果确实需要改 SQLite,务必在停止服务后做事务更新,不要一边让 x-ui 写 WAL 一边手工改库。
2. 修改两处协议配置
- Reality:换成经过 TLS 探测的候选目标,
target和serverNames同步修改,保留原有私钥、短 ID 和客户端公钥关系。 - Hysteria2:把自签名证书替换为可信证书,证书文件使用完整链(fullchain),私钥权限保持最小化,
serverName与证书 SAN、订阅 SNI 一致。
3. 重启并检查生成结果
systemctl start x-ui
systemctl is-active x-ui
ss -lntup | grep -E '你的 TCP 端口|你的 UDP 端口'
journalctl -u x-ui -n 100 --no-pager
不要只看到 active 就结束。还要检查生成后的 Xray 配置,确认旧目标、旧证书路径和旧 SNI 没有残留。
4. 重新获取订阅并做真实路径验证
修改入站后,客户端里的旧订阅仍可能缓存旧配置。重新获取订阅,确认以下字段:
- VLESS 的地址、端口、UUID、公钥、短 ID 和 SNI;
- Hysteria2 的地址、端口、密码、SNI 和证书校验模式;
- 客户端没有继续使用旧的订阅快照或旧节点。
最后分别通过实际客户端访问一个简单的公网地址。服务端回环测试只能证明服务能工作,不能替代手机、桌面端或旁路由上的真实链路测试。
这次故障留下的检查清单
| 层级 | 要回答的问题 | 常用证据 |
|---|---|---|
| 进程 | x-ui/Xray 是否运行? | systemctl、journalctl |
| 监听 | TCP/UDP 端口是否正确打开? | ss -lntup |
| 网络 | 云防火墙和主机防火墙是否放行对应协议? | 安全组、iptables/nftables |
| 协议 | 是 TCP/QUIC 到不了,还是握手失败? | Xray/Hysteria 日志 |
| TLS | SNI、SAN、证书链是否一致且受信? | xray tls ping、证书检查 |
| 配置 | 面板和生成配置是否一致? | 生成后的 JSON |
| 客户端 | 是否已经拉到新订阅? | 导出的节点字段、真实访问 |
最后总结
这次排查最重要的经验,是把“节点不能用”拆成可观察的层:端口监听不等于协议握手成功,证书能加载也不等于客户端会信任,面板显示正常更不等于订阅已经刷新。
Reality 的目标站点是外部依赖,目标证书链变化可能在没有改服务器配置的情况下造成故障;Hysteria2 则必须把证书链、SNI 和客户端校验策略当成一个整体维护。以后遇到类似问题,先保留证据,再一次只改变一个变量做 A/B 测试,通常比反复重装面板更快找到根因。
另外,任何公开文章、工单或截图都不要包含 root 密码、私钥、UUID、订阅链接和完整配置。若凭据曾经出现在聊天记录或截图中,排障完成后应立即轮换密码并重新生成相关密钥。
参考: