Snell — sing-box
Snell 是 Surge 的轻量代理协议。sing-box 实现了两端:snell 入站(服务端)与 snell 出站(客户端)。该实现涵盖除 v5 QUIC 代理模式外的全部 Snell 特性,因此两端的版本不同 —— 入站提供版本 5 或 6,出站使用版本 4 或 6。无需任何构建标签。
入站
位于 inbounds[] 下的 type: "snell",外加常规监听字段(listen、listen_port 等):
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
version | int | (required) | 5 | 6 | 该入站提供的 Snell 版本。5 接受 Surge v4 与 v5 客户端(未实现 v5 的 QUIC 代理模式,因此其 TCP 线上格式与 v4 相同);6 接受 v6 客户端。缺失或其他取值会在启动时报错。 |
源码: option/snell.go:12-17 · 锚定版本 v1.14.2 (af6e64c)
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
psk | string | (required) | <string> | 服务端预共享密钥。版本 6 要求长度为 12 到 255 字节。 |
users | []SnellUser | [] | [SnellUser] | 启用多用户模式:每个客户端用各自的 userkey 鉴权,psk 仍作为服务端密钥。 |
源码: option/snell.go:19-23 · 锚定版本 v1.14.2 (af6e64c)
users[]
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
name | string | (unset) | <string> | 可选标签,用于日志。 |
userkey | string | (required) | <string> | 该用户的密钥。客户端将其作为出站的 userkey 发送。 |
源码: option/snell.go:135-138 · 锚定版本 v1.14.2 (af6e64c)
出站
位于 outbounds[] 下的 type: "snell",外加 server / server_port 与拨号字段:
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
version | int | (required) | 4 | 6 | 使用的 Snell 版本。4 可连接 v4 与 v5 服务端(去掉 QUIC 代理模式后的 v5 在线上与 v4 兼容);6 连接 v6 服务端。缺失或其他取值会在启动时报错。 |
源码: option/snell.go:70-75 · 锚定版本 v1.14.2 (af6e64c)
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
psk | string | (required) | <string> | 服务端预共享密钥;必须与服务端一致。 |
userkey | string | (unset) | <string> | 多用户服务端的用户密钥。单用户服务端留空。版本 6 拒绝超过 255 字节的密钥。 |
reuse | bool | false | true | false | 通过 Snell v2 的 CONNECT 命令复用到服务端的连接,而不是每个请求新建一条 TCP 连接。 |
network | NetworkList | (tcp and udp) | tcp | udp | 该出站处理的网络。UDP 承载在到服务端的 TCP 连接中。 |
源码: option/snell.go:77-84 · 锚定版本 v1.14.2 (af6e64c)
版本专属字段
这些键与 version 并列,位于入站或出站对象的顶层。sing-box 只读取所选版本对应的键;属于其他版本的键会在启动时作为未知字段被拒绝。
混淆 —— 入站版本 5
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
obfs_mode | string | none | none | http | tls | 仅版本 5。服务端期望的混淆:无、HTTP 请求伪装或 TLS 记录伪装。必须与客户端一致。 |
源码: option/snell.go:131-133 · 锚定版本 v1.14.2 (af6e64c)
混淆 —— 出站版本 4
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
obfs_mode | string | none | none | http | tls | 仅版本 4。包裹在连接外的混淆;必须与服务端一致。 |
obfs_host | string | bing.com (http) / cloudfront.net (tls) | <hostname> | 仅版本 4。混淆所展示的主机名:http 模式下为 HTTP Host 头,tls 模式下为伪造 ClientHello 的服务器名。 |
源码: option/snell.go:140-143 · 锚定版本 v1.14.2 (af6e64c)
流量整形 —— 版本 6(两端)
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
mode | string | default | default | unshaped | unsafe-raw | 仅版本 6。default 使用由 PSK 派生的记录与填充配置对流量整形;unshaped 保留 AEAD 加密但不整形;unsafe-raw 发送不加密的记录。两端须使用相同模式。 |
源码: option/snell.go:145-147 · 锚定版本 v1.14.2 (af6e64c)
示例
带两个用户的版本 6 服务端:
{
"inbounds": [
{
"type": "snell",
"tag": "snell-in",
"listen": "::",
"listen_port": 8443,
"version": 6,
"psk": "<at-least-12-byte-psk>",
"users": [
{ "name": "alice", "userkey": "<alice-key>" },
{ "name": "bob", "userkey": "<bob-key>" }
]
}
]
}连接该服务端的版本 6 客户端:
{
"outbounds": [
{
"type": "snell",
"tag": "snell-out",
"server": "snell.example.com",
"server_port": 8443,
"version": 6,
"psk": "<at-least-12-byte-psk>",
"userkey": "<alice-key>"
}
]
}带 HTTP 混淆的版本 4 客户端(可连接 v4 与 v5 服务端):
{
"outbounds": [
{
"type": "snell",
"tag": "snell-v4",
"server": "snell.example.com",
"server_port": 8388,
"version": 4,
"psk": "<psk>",
"obfs_mode": "http",
"obfs_host": "www.bing.com"
}
]
}说明
- 版本组合是有意为之:没有 v5 QUIC 代理模式时,v5 的 TCP 线上协议与 v4 完全相同,因此 sing-box 提供 v5 服务端(v4 与 v5 客户端均可连接)和 v4 客户端(可连接 v4 与 v5 服务端),而不提供 v4 服务端或 v5 客户端。
- 解析器接受
obfs_mode: "tls",Snell 库也实现了它,尽管上游选项文档只列出了none与http。 - 入站只监听 TCP。客户端的 UDP 在 TCP 流内中继,出站也是如此,因此服务端无需开放 UDP 端口。
unsafe-raw会完全去掉加密层。只应在路径本身已受保护的场景使用(例如位于另一条隧道内)。- 多用户模式下顶层
psk仍为必填,由所有用户共用;每个用户通过其userkey识别。
跨内核说明
- mihomo 同样两端都支持 Snell,键名为 kebab-case:出站接受
version1–5(以 v4 方式连接 v5 服务端),混淆放在obfs-opts下(http/tls,外加shadow-tls/restls/jls伪装层);入站的obfs-opts支持http/tls。mihomo 没有 Snell v6。参见 Snell — mihomo。 - Xray-core 不支持 Snell。
源码: option/snell.go:12-147 · v1.14.2 (af6e64c)
