本文最后更新于 2026 年 4 月 20 日
本文以 Debian 13 为例,介绍如何搭建 sing-box 的 AnyTLS + REALITY 服务端,并说明对应的客户端配置文件的格式。本文同样完全适用于 Ubuntu 24.04 及以上系统。
本方案有以下特点:
- 无需域名,无需解析
- 无需申请 TLS 证书(REALITY 借用第三方站点的真实 TLS 握手)
- 无需 Nginx 或其他 Web 服务器(REALITY 自己负责处理握手层的伪装与转发)
- 无需 CloudFlare 中转,客户端与 VPS 直连
该方案对 VPS 的 IP 质量要求较高,需要选择合理的 SNI 目标站,并定期维护配置以应对长期可用性风险。
注:请先参照 Debian & Ubuntu 服务器的初始化配置 一文对服务器进行各种必要的配置。本文以 sammy 用户为例,进行 sing-box 的部署,并默认已按初始化配置文章对服务器进行了配置。
背景与原理
介绍 AnyTLS + REALITY
当前 sing-box 原生支持的直连协议中,AnyTLS 与 REALITY 的组合具有以下特性:
- REALITY 将 TLS ClientHello 的 SNI 指向一个真实的第三方站点(称为 handshake server),由服务端完成密钥协商。若客户端认证成功则走代理通道,否则将连接完整转发给该第三方站点。这使得主动探测者获取的是真实站点的证书与响应,握手层难以区分真实访问者与代理用户。
- AnyTLS 协议本身在 TLS 之上提供了
padding_scheme机制,用于在协议层对数据包长度进行随机填充,以对抗基于包长分布的被动流量识别。 - 整个协议链路在直连场景下不引入额外的 transport(如 WebSocket、HTTPUpgrade、gRPC),客户端发出的流量经 REALITY 握手后直接承载 AnyTLS 内容,延迟与吞吐无额外损耗。
本方案不适用的场景
- VPS IP 本身已被封锁或严重干扰的情况。REALITY 无法修复 IP 层的封锁。
- 需要借助 CDN 隐藏源站 IP 的场景。REALITY 的工作方式与 CDN 反代不兼容。
- 使用的第三方客户端版本过旧不支持 AnyTLS 协议的场景。在配置前请先确认目标客户端支持 AnyTLS,否则考虑改用 VLESS + Vision + REALITY 方案。
准备工作
服务器
- 可用的公网 IP 服务器
- 建议选择冷门机房,避开已被大量代理用户使用的热门 IP 段
- 开放 TCP
443端口的入站访问(若有防火墙或安全组)
选定 REALITY 的 SNI 目标站
REALITY 需要一个真实存在的第三方站点作为 SNI 目标(即 handshake server)。该目标站需要满足以下条件:
- 站点支持 TLS 1.3
- 站点支持 X25519 密钥交换
- 站点返回的证书合法且稳定
- 站点非 CloudFlare、Akamai 等大型 CDN 托管(回源复杂、SNI 校验可能不一致)
- 站点地理位置最好与 VPS 同机房或同 IP 段,以避免 IP 与域名地理分布不一致引起的可疑特征
- 站点不要使用
www.microsoft.com、www.apple.com、itunes.apple.com等已被代理圈广泛使用的目标
可以使用 RealiTLScanner 扫描 VPS 邻近 IP 段,找到合适的目标。
1 | wget https://github.com/XTLS/RealiTLScanner/releases/latest/download/RealiTLScanner-linux-64 |
扫描结果示例中会列出每个 IP 对应的域名、TLS 版本、是否 feasible。从 feasible=true 的记录中挑选一个,并用浏览器打开 https://该域名/ 确认内容为正常的非敏感网站。
本文以 www.example-target.jp 代指选定后的 SNI 目标站。
内容准备
- 记录下上一步选定的 SNI 目标站域名,本文以
www.example-target.jp为例 - 生成一个用于 AnyTLS 用户认证的密码(见后续步骤)
- 生成一对 REALITY 密钥(见后续步骤)
- 生成一个或多个
short_id(见后续步骤)
安装所需基本工具
1 | sudo apt update && sudo apt install curl vim wget ca-certificates -y |
服务器防火墙配置
确保服务器仅开放必要端口。本方案中 sing-box 将监听 443/tcp:
1 | sudo ufw allow 443/tcp |
安装 sing-box
通过官方 APT 仓库安装
sing-box 官方提供了 APT 仓库,推荐优先使用此方式,便于后续升级。
1 | sudo mkdir -p /etc/apt/keyrings && |
验证版本:
1 | sing-box version |
systemd 服务
APT 包已自带 systemd 单元,无需手动编写。服务单元会读取 /etc/sing-box/config.json 作为配置文件。常用管理命令参见官方文档。
此时尚未编写配置文件,暂不启动服务。
生成密钥与标识
生成 REALITY 密钥对
1 | sing-box generate reality-keypair |
输出示例:
1 | PrivateKey: uP2PWZY... (服务端用) |
将这两个值记录下来。PrivateKey 用于服务端配置,PublicKey 用于客户端配置。
生成 short_id
short_id 是 0 到 8 字节的十六进制字符串(即 0 到 16 个十六进制字符),用于在一个 REALITY 实例下区分不同客户端身份。生成一个 8 字节的 short_id:
1 | openssl rand -hex 8 |
输出示例:
1 | 0123456789abcdef |
记录下来。服务端可以配置多个 short_id 以支持多客户端;客户端配置时使用其中一个。
生成 AnyTLS 用户密码
根据 sing-box 官方文档中 AnyTLS 的示例,password 为 base64 格式的随机字符串。生成一个 16 字节的密码:
1 | openssl rand -base64 16 |
输出示例:
1 | 8JCsPssfgS8tiRwiMlhARg== |
记录下来,用于服务端与客户端的 AnyTLS 用户认证。
配置 sing-box
创建配置文件
1 | sudo mkdir -p /etc/sing-box |
添加如下内容。注意替换其中的 你的 REALITY 私钥、你选定的 SNI 目标站域名、你生成的 short_id、你生成的 AnyTLS 密码:
1 | { |
关键字段说明
具体参见 AnyTLS 与 TLS - Reality Fields。
inbounds[].listen::: 表示同时监听 IPv4 与 IPv6。若 VPS 仅有 IPv4,也可以填 0.0.0.0。
inbounds[].listen_port:监听端口。本文使用 443,与真实 HTTPS 服务共用同一端口,最不引起可疑。
inbounds[].users[]:AnyTLS 的用户列表,每个用户包含 name 与 password。name 仅用于日志标识,password 用于认证。
inbounds[].tls.server_name:REALITY 对外声明的 SNI,必须与 reality.handshake.server 保持一致,且必须是真实存在、可访问的站点。
inbounds[].tls.reality.handshake.server 与 server_port:REALITY 在客户端认证失败或发起探测时,会将流量完整转发给该地址。必须是一个真实运行 HTTPS 服务的站点。
inbounds[].tls.reality.private_key:REALITY 服务端私钥,由 sing-box generate reality-keypair 生成。
inbounds[].tls.reality.short_id:数组形式,可填入一个或多个 short_id。客户端连接时必须使用其中之一。
outbounds[]:本方案作为纯代理服务端,只需一个 direct 出站,将认证通过的代理流量直接发往目标。
route.rules[] 中的规则:
ip_is_private配合"action": "reject":匹配内网地址并拒绝,防止代理流量访问 VPS 所在内网资源protocol: bittorrent配合"action": "reject":拒绝 BT 流量,避免 VPS IP 被滥用举报
配置校验
保存后,使用 sing-box 自带的校验命令检查配置文件语法:
1 | sudo sing-box check -c /etc/sing-box/config.json |
若无输出则表示配置文件通过校验。如有报错,按提示修正。
启动服务
启动 sing-box 并设置开机自启:
1 | sudo systemctl enable --now sing-box |
查看运行状态:
1 | sudo systemctl status sing-box |
查看日志确认无误:
1 | sudo journalctl -u sing-box --output cat -e |
至此,服务端已部署完成。
客户端配置文件
此为示例,主要展示 outbound 的写法,不代表分流规则完善的高阶配置。
注意替换下方的 你的 VPS 公网 IP、你选定的 SNI 目标站域名、你的 REALITY 公钥、你生成的 short_id、你生成的 AnyTLS 密码:
1 | { |
客户端关键字段说明
outbounds[].type: anytls:使用 AnyTLS 协议(客户端侧为单一密码认证,无需 users 字段)。
outbounds[].tls.server_name:必须与服务端的 server_name 完全一致,即选定的 SNI 目标站域名。
outbounds[].tls.utls:启用 uTLS 伪造 ClientHello 指纹。这对 REALITY 客户端是必需的,不是可选项。REALITY 协议的客户端认证依赖将认证数据嵌入 TLS ClientHello 的 session ID 字段,而 Go 标准库 crypto/tls 不支持自定义 session ID,因此 sing-box 的 REALITY 客户端实现强制要求通过 uTLS 来构造 ClientHello。若省略 utls 或将 utls.enabled 设为 false,sing-box 启动时会直接报错 uTLS is required by reality client。
fingerprint 可选值包括 chrome、firefox、edge、safari、ios、android、random、randomized 等。一般推荐 chrome,与大多数实际浏览器流量分布一致。
需要说明的是,sing-box 官方文档对 uTLS 本身的评价较为保守(“uTLS has had repeated fingerprinting vulnerabilities discovered by researchers”),但该评价针对的是"单独使用 uTLS 作为 TLS 指纹对抗手段"的场景。在 REALITY 场景下,主要的抗识别机制来自 REALITY 协议本身(借用真实站点完成 TLS 握手),uTLS 在此仅承担 REALITY 协议实现所需的 ClientHello 定制能力,与独立使用 uTLS 的风险模型不同。
outbounds[].tls.reality.public_key 与 short_id:与服务端配置对应。注意客户端侧 short_id 是字符串形式(单个值),而服务端侧是数组形式(可多个)。
维护与长期可用性
以下建议基于实际部署经验,用于提升方案的长期稳定性。
定期轮换
建议按以下周期轮换关键凭据:
short_id:每 6-12 个月轮换一次,可在服务端short_id数组中加入新值后通知客户端切换,再删除旧值实现无缝过渡- AnyTLS 密码:每 1-2 年轮换一次
- REALITY 密钥对:2-3 年轮换一次
- SNI 目标站:每年重新扫描并评估一次,确认原目标仍然可用且未被代理圈大规模使用
更新 sing-box
APT 源安装的版本可通过标准方式升级:
1 | sudo apt update && sudo apt upgrade sing-box -y |
升级前建议先查看 sing-box Change Log,确认没有破坏性变更。
常见排查
- 客户端连接超时但端口可达:确认客户端的
server_name、public_key、short_id与服务端完全一致 - 主动探测返回了 handshake server 的内容:这通常意味着客户端的 REALITY 认证失败,sing-box 按设计将连接转发给了真实站点。请检查
public_key与short_id是否正确 - 部分应用流量正常,部分应用异常:通常是 DNS 泄漏或路由规则问题,检查客户端的
dns与route配置 - 近期突然全部无法连接:先用其他节点测试 VPS IP 是否已被阻断(如
ping或在海外机器上curl https://你的VPS_IP/)。若 IP 已被阻断,考虑更换 IP