Debian & Ubuntu 搭建部署 sing-box 的 VLESS + Vision + REALITY 服务

Contents
  1. 1. 背景与原理
    1. 1.1. 介绍 VLESS + Vision + REALITY
    2. 1.2. 本方案不适用的场景
  2. 2. 准备工作
    1. 2.1. 服务器
    2. 2.2. 选定 REALITY 的 SNI 目标站
    3. 2.3. 内容准备
    4. 2.4. 安装所需基本工具
    5. 2.5. 服务器防火墙配置
  3. 3. 安装 sing-box
    1. 3.1. 通过官方 APT 仓库安装
    2. 3.2. systemd 服务
  4. 4. 生成密钥与标识
    1. 4.1. 生成 REALITY 密钥对
    2. 4.2. 生成 short_id
    3. 4.3. 生成 VLESS UUID
  5. 5. 配置 sing-box
    1. 5.1. 创建配置文件
    2. 5.2. 关键字段说明
    3. 5.3. 配置校验
  6. 6. 启动服务
  7. 7. 客户端配置文件
    1. 7.1. 客户端关键字段说明
  8. 8. 维护与长期可用性
    1. 8.1. 定期轮换
    2. 8.2. 更新 sing-box
    3. 8.3. 常见排查
  9. 9. References

本文最后更新于 2026 年 4 月 20 日


本文以 Debian 13 为例,介绍如何搭建 sing-box 的 VLESS + Vision + REALITY 服务端,并说明对应的客户端配置文件的格式。本文同样完全适用于 Ubuntu 24.04 及以上系统。

本方案有以下特点:

  1. 无需域名,无需解析
  2. 无需申请 TLS 证书(REALITY 借用第三方站点的真实 TLS 握手)
  3. 无需 Nginx 或其他 Web 服务器(REALITY 自己负责处理握手层的伪装与转发)
  4. 无需 CloudFlare 中转,客户端与 VPS 直连

该方案对 VPS 的 IP 质量要求较高,需要选择合理的 SNI 目标站,并定期维护配置以应对长期可用性风险。

注:请先参照 Debian & Ubuntu 服务器的初始化配置 一文对服务器进行各种必要的配置。本文以 sammy 用户为例,进行 sing-box 的部署,并默认已按初始化配置文章对服务器进行了配置。


背景与原理

介绍 VLESS + Vision + REALITY

VLESS + Vision + REALITY 是代理中成熟、部署广泛的组合之一,具有以下特性:

  1. REALITY 将 TLS ClientHello 的 SNI 指向一个真实的第三方站点(称为 handshake server),由服务端完成密钥协商。若客户端认证成功则走代理通道,否则将连接完整转发给该第三方站点。这使得主动探测者获取的是真实站点的证书与响应,握手层难以区分真实访问者与代理用户。
  2. Vision(xtls-rprx-vision)是 VLESS 的一个子协议流控,它在内层 TLS 握手完成后识别出握手边界,将后续数据从 TLS record 封装中剥离出来,直接通过底层 TCP 传输。这消除了"内层 TLS 报文结构穿透到外层"的特征——即 TLS-in-TLS 的典型包长分布——使代理流量的数据段行为与普通 HTTPS 直连流量趋同。
  3. 整个协议链路在直连场景下不引入额外的 transport,客户端发出的流量经 REALITY 握手后直接承载 VLESS 内容,延迟与吞吐无额外损耗。

本方案不适用的场景

  1. VPS IP 本身已被封锁或严重干扰的情况。REALITY 无法修复 IP 层的封锁。
  2. 需要借助 CDN 隐藏源站 IP 的场景。REALITY 的工作方式与 CDN 反代不兼容,此外 Vision 流控本身也要求底层是裸 TCP,与 CDN 所需的 transport 层(WebSocket、HTTPUpgrade、gRPC 等)不兼容。如需通过 CDN,请改用 VLESS + WebSocket/HTTPUpgrade + TLS 的方案,而非本文的 Vision 方案。
  3. 需要代理 UDP 流量但客户端不支持 XUDP 的场景。Vision 基于 TCP,UDP 通过 VLESS 的 packet_encoding 机制封装传输,客户端需要支持 xudp 或 packetaddr。

准备工作

服务器

  1. 可用的公网 IP 服务器
  2. 建议选择冷门机房,避开已被大量代理用户使用的热门 IP 段
  3. 开放 TCP 443 端口的入站访问(若有防火墙或安全组)

选定 REALITY 的 SNI 目标站

REALITY 需要一个真实存在的第三方站点作为 SNI 目标(即 handshake server)。该目标站需要满足以下条件:

  1. 站点支持 TLS 1.3
  2. 站点支持 X25519 密钥交换
  3. 站点返回的证书合法且稳定
  4. 站点非 CloudFlare、Akamai 等大型 CDN 托管(回源复杂、SNI 校验可能不一致)
  5. 站点地理位置最好与 VPS 同机房或同 IP 段,以避免 IP 与域名地理分布不一致引起的可疑特征
  6. 站点不要使用 www.microsoft.comwww.apple.comitunes.apple.com 等已被代理圈广泛使用的目标

可以使用 RealiTLScanner 扫描 VPS 邻近 IP 段,找到合适的目标。

1
2
3
wget https://github.com/XTLS/RealiTLScanner/releases/latest/download/RealiTLScanner-linux-64
chmod +x RealiTLScanner-linux-64
./RealiTLScanner-linux-64 -addr 你的VPS_IP -port 443

扫描结果示例中会列出每个 IP 对应的域名、TLS 版本、是否 feasible。从 feasible=true 的记录中挑选一个,并用浏览器打开 https://该域名/ 确认内容为正常的非敏感网站。

内容准备

  1. 记录下上一步选定的 SNI 目标站域名
  2. 生成一个用于 VLESS 用户认证的 UUID(见后续步骤)
  3. 生成一对 REALITY 密钥(见后续步骤)
  4. 生成一个或多个 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
2
3
4
5
6
7
8
9
10
11
12
13
sudo mkdir -p /etc/apt/keyrings &&
sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc &&
sudo chmod a+r /etc/apt/keyrings/sagernet.asc &&
echo '
Types: deb
URIs: https://deb.sagernet.org/
Suites: *
Components: *
Enabled: yes
Signed-By: /etc/apt/keyrings/sagernet.asc
' | sudo tee /etc/apt/sources.list.d/sagernet.sources &&
sudo apt-get update &&
sudo apt-get install sing-box # or sing-box-beta

验证版本:

1
sing-box version

systemd 服务

APT 包已自带 systemd 单元,无需手动编写。服务单元会读取 /etc/sing-box/config.json 作为配置文件。常用管理命令参见官方文档。

此时尚未编写配置文件,暂不启动服务。


生成密钥与标识

生成 REALITY 密钥对

1
sing-box generate reality-keypair

输出示例:

1
2
PrivateKey: uP2PWZY... (服务端用)
PublicKey: AbC123... (客户端用)

将这两个值记录下来。PrivateKey 用于服务端配置,PublicKey 用于客户端配置。

生成 short_id

short_id 是 0 到 8 字节的十六进制字符串(即 0 到 16 个十六进制字符),用于在一个 REALITY 实例下区分不同客户端身份。生成一个 8 字节的 short_id

1
openssl rand -hex 8

输出示例:

1
0123456789abcdef

记录下来。服务端可以配置多个 short_id 以支持多客户端;客户端配置时使用其中一个。

生成 VLESS UUID

1
sing-box generate uuid

输出示例:

1
bf000d23-0752-40b4-affe-68f7707a9661

记录下来,用于服务端与客户端的 VLESS 用户认证。


配置 sing-box

创建配置文件

1
2
sudo mkdir -p /etc/sing-box
sudo vim /etc/sing-box/config.json

添加如下内容。注意替换其中的 你的 REALITY 私钥你选定的 SNI 目标站域名你生成的 short_id你生成的 UUID

/etc/sing-box/config.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
"log": {
"level": "warn",
"timestamp": true
},
"inbounds": [
{
"type": "vless",
"tag": "vless-in",
"listen": "::",
"listen_port": 443,
"users": [
{
"name": "sammy",
"uuid": "你生成的 UUID",
"flow": "xtls-rprx-vision"
}
],
"tls": {
"enabled": true,
"server_name": "你选定的 SNI 目标站域名",
"reality": {
"enabled": true,
"handshake": {
"server": "你选定的 SNI 目标站域名",
"server_port": 443
},
"private_key": "你的 REALITY 私钥",
"short_id": [
"你生成的 short_id"
]
}
}
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"rules": [
{
"ip_is_private": true,
"action": "reject"
},
{
"protocol": "bittorrent",
"action": "reject"
}
],
"final": "direct"
}
}

关键字段说明

具体参见 VLESSTLS - Reality Fields

inbounds[].listen:: 表示同时监听 IPv4 与 IPv6。若 VPS 仅有 IPv4,也可以填 0.0.0.0

inbounds[].listen_port:监听端口。本文使用 443,与真实 HTTPS 服务共用同一端口,最不引起可疑。

inbounds[].users[]:VLESS 的用户列表,每个用户包含 nameuuidflowname 仅用于日志标识,uuid 用于认证。

inbounds[].users[].flow:VLESS 的子协议字段。本文固定为 xtls-rprx-vision,即启用 Vision 流控。根据 sing-box 官方文档,该字段目前仅此一个合法值。服务端与客户端必须同时设置此字段且值一致,否则协议不匹配,连接将被拒绝。注意:配置了 Vision 流控后,同一个 VLESS inbound 不能再配置 transport 字段(WebSocket、HTTPUpgrade、gRPC 等),否则 Vision 流控所依赖的"底层 TCP 裸传"假设不成立,行为不符合设计。

inbounds[].tls.server_name:REALITY 对外声明的 SNI,必须与 reality.handshake.server 保持一致,且必须是真实存在、可访问的站点。

inbounds[].tls.reality.handshake.serverserver_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你生成的 UUID

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
{
"log": {
"level": "warn",
"timestamp": true
},
"dns": {
"servers": [
{
"type": "https",
"tag": "remote-dns",
"server": "1.1.1.1",
"detour": "proxy"
},
{
"type": "udp",
"tag": "local-dns",
"server": "223.5.5.5"
}
],
"rules": [
{
"rule_set": "geosite-cn",
"server": "local-dns"
}
],
"final": "remote-dns",
"strategy": "ipv4_only"
},
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"address": [
"172.19.0.1/30"
],
"auto_route": true,
"strict_route": true
}
],
"outbounds": [
{
"type": "vless",
"tag": "proxy",
"server": "你的 VPS 公网 IP",
"server_port": 443,
"uuid": "你生成的 UUID",
"flow": "xtls-rprx-vision",
"packet_encoding": "xudp",
"tls": {
"enabled": true,
"server_name": "你选定的 SNI 目标站域名",
"utls": {
"enabled": true,
"fingerprint": "chrome"
},
"reality": {
"enabled": true,
"public_key": "你的 REALITY 公钥",
"short_id": "你生成的 short_id"
}
}
},
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"rules": [
{
"action": "sniff"
},
{
"protocol": "dns",
"action": "hijack-dns"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"rule_set": "geosite-cn",
"outbound": "direct"
},
{
"rule_set": "geoip-cn",
"outbound": "direct"
}
],
"rule_set": [
{
"type": "remote",
"tag": "geosite-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs",
"download_detour": "proxy"
},
{
"type": "remote",
"tag": "geoip-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs",
"download_detour": "proxy"
}
],
"final": "proxy",
"auto_detect_interface": true,
"default_domain_resolver": {
"server": "local-dns",
"strategy": "ipv4_only"
}
},
"experimental": {
"cache_file": {
"enabled": true
}
}
}

客户端关键字段说明

outbounds[].type: vless:使用 VLESS 协议(客户端侧为单一 UUID 认证,无需 users 字段)。

outbounds[].uuid:与服务端 users[].uuid 一致。

outbounds[].flow:必须填 xtls-rprx-vision,并与服务端一致。该字段为空或填其他值将与服务端协议不匹配。

outbounds[].packet_encoding:UDP 包的封装方式。本文采用 xudp,这是 sing-box 的默认值,也是主流 VLESS 实现的推荐值,兼容 Xray 生态。若客户端不需要 UDP 代理或对 UDP 封装格式有特殊要求,可省略该字段或改为其他值。

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 可选值包括 chromefirefoxedgesafariiosandroidrandomrandomized 等。一般推荐 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_keyshort_id:与服务端配置对应。注意客户端侧 short_id 是字符串形式(单个值),而服务端侧是数组形式(可多个)。


维护与长期可用性

以下建议基于实际部署经验,用于提升方案的长期稳定性。

定期轮换

建议按以下周期轮换关键凭据:

  1. short_id:每 6-12 个月轮换一次,可在服务端 short_id 数组中加入新值后通知客户端切换,再删除旧值实现无缝过渡
  2. VLESS UUID:每 1-2 年轮换一次
  3. REALITY 密钥对:2-3 年轮换一次
  4. SNI 目标站:每年重新扫描并评估一次,确认原目标仍然可用且未被代理圈大规模使用

更新 sing-box

APT 源安装的版本可通过标准方式升级:

1
2
sudo apt update && sudo apt upgrade sing-box -y
sudo systemctl restart sing-box

升级前建议先查看 sing-box Change Log,确认没有破坏性变更。

常见排查

  1. 客户端连接超时但端口可达:确认客户端的 server_namepublic_keyshort_iduuidflow 与服务端完全一致
  2. 主动探测返回了 handshake server 的内容:这通常意味着客户端的 REALITY 认证失败,sing-box 按设计将连接转发给了真实站点。请检查 public_keyshort_id 是否正确
  3. 客户端能连上但流量异常(如慢、丢包、协议错误):检查服务端和客户端的 flow 是否都设置为 xtls-rprx-vision。服务端设置了而客户端没有,或反之,连接虽能建立但行为会异常
  4. 部分应用流量正常,部分应用异常:通常是 DNS 泄漏或路由规则问题,检查客户端的 dnsroute 配置
  5. 近期突然全部无法连接:从国内测 VPS IP 是否可达(ping 或 TCP 443 连通性);若国内不通但海外能通,说明 IP 被阻断,考虑更换 IP。

References

sing-box

XTLS / REALITY

XTLS / Xray-core / Vision

XTLS / RealiTLScanner

Mastodon