> For the complete documentation index, see [llms.txt](https://kb.nssurge.com/surge-knowledge-base/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kb.nssurge.com/surge-knowledge-base/zh/release-notes/snell.md).

# Snell

Snell 是由我们团队开发的精简加密代理协议，主要特点如下：

* 极致的性能。
* 支持 UDP over TCP 转发。
* 单一二进制文件，零依赖（glibc 除外）。
* 提供向导帮助快速上手。
* 遇到错误时，代理服务端会将远端错误报告给客户端，客户端可针对不同场景采取相应对策。

{% code overflow="wrap" %}

```markdown
https://dl.nssurge.com/snell/snell-server-v6.0.0-linux-amd64.zip
https://dl.nssurge.com/snell/snell-server-v6.0.0-linux-i386.zip
https://dl.nssurge.com/snell/snell-server-v6.0.0-linux-aarch64.zip
https://dl.nssurge.com/snell/snell-server-v6.0.0-macOS-arm64.zip
```

{% endcode %}

{% hint style="danger" %}
Snell 是一个以性能为首要目标设计的代理协议。作为有意为之的设计取舍，在相关开销会对性能产生可观影响的地方，它省略了部分安全特性，并采用了更轻量的密码学参数。

如果你的首要目标是最大化安全保障而非最小化开销，我们建议改用基于 TLS 的代理协议。Snell 面向的是愿意在安全与性能之间做出审慎权衡，以换取更低延迟、更低资源占用和更高吞吐量的用户。
{% endhint %}

<details>

<summary><mark style="color:purple;">安全技术细节</mark></summary>

以下设计选择应被理解为有意的性能与安全权衡，而非协议的缺陷。

例如，Snell 不提供前向保密（forward secrecy）。实现前向保密需要进行临时密钥交换，使会话密钥不仅由长期密钥派生。由于 Snell 被设计为 0-RTT 协议，应用流量仅凭预共享密钥即可立即完成认证和加密。若要提供前向保密，就需要在保护应用数据之前增加一个额外的密钥交换阶段，从而增加连接建立延迟和协议复杂度。

同样，Snell 没有实现专门的防重放机制。防重放并非互联网协议的普遍特性，许多广泛部署的协议在不维护防重放状态的情况下依然可以安全运行。此外，历史上一些因重放而被识别的代理协议，其问题主要在于缺乏认证加密和完整性保护，而非缺少防重放机制本身。Snell 在整个协议中均使用认证加密（AEAD），确保被篡改或伪造的流量会被拒绝。

出于同样的原因，Snell 的 PSK 密钥派生函数所使用的参数经过有意调整，与更保守、更侧重安全的配置相比降低了计算开销。即便采用了这些降低后的参数，只要使用足够随机的 PSK，暴力破解依然不可行。实际上，一个 12 位或以上随机生成的 PSK 所提供的安全余量已远超穷举搜索的能力范围。我们建议使用 snell-server 设置向导生成的 32 位随机 PSK，即使对攻击者能力做出极为乐观的假设，它也能提供极大的抗暴力破解余量。即便假设攻击者每秒可以验证一百京（10^18）个候选密钥，穷举整个密钥空间仍需约 10^31 年。

</details>

## Release Notes

### v6.0.0

Snell v6 引入了基于 PSK 派生的部署级协议多样性，为每个部署生成独特的流量特征，大幅降低了对单一协议指纹的依赖，同时保留了 Snell 在性能、部署简便、准确错误报告以及完整 TCP 语义方面的核心目标。Snell v6 还移除了 QUIC Proxy Mode，新增了 IPv4/IPv6 网络栈控制选项，包括 dns-ip-preference 以及多地址 listen 支持，目前处于 Beta 测试阶段。

更多信息请参阅[我们的博客](https://nssurge.com/blog/snell-v6/)。

Snell v6 新增了 mode 设置：

1. `mode=default` 默认模式，启用流量混淆和 AES 加密。
2. `mode=unshaped` 关闭混淆，仅使用 AES 加密。与默认模式相比，吞吐性能可提升约 10%。该模式等同于 Snell v3，加密后的流量表现为完全随机。
3. `mode=unsafe-raw` 关闭加密和混淆，所有流量以明文转发。仅应在安全的网络环境中使用，例如内网或其他安全隧道之下。

请注意，服务端与客户端的 mode 必须保持一致。

### v5.0.1

* 修正了一处因断言导致的低概率崩溃问题。

### v5.0.0

#### Dynamic Record Sizing

该特性将改善存在丢包的网络环境下的延迟表现。技术细节可参考：[Cloudflare Blog](https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency/)

#### QUIC Proxy Mode

Snell v5 加入了专为 QUIC 流量设计的 QUIC Proxy 模式，该模式以 UDP over UDP 方式工作，以避免 TCP over UDP 问题。（服务端需开放 UDP 端口）

* 该工作模式为 QUIC 进行了特殊优化，仅当 Surge 识别到 QUIC 流量时才会启用，其他 UDP 流量依然使用 UDP over TCP 模式。
* QUIC Proxy 只会对 QUIC Handshake 数据包进行强加密，以保护 SNI 和目标主机名，同时进行鉴权。后续的所有 QUIC 数据包由于本身已经被 QUIC 强加密，将直接以裸包形式转发，大幅降低了不必要的加解密开销。同时由于未引入额外字节，不会影响 QUIC 的 PMTU 探测。

#### 出口控制

* 支持配置 `egress-interface` 参数控制出口 interface（需要 root 权限或授予 `CAP_NET_RAW/CAP_NET_ADMIN` 权限，同时该 interface 上需要有目标地址和 DNS 的路由表）。
* 支持 systemd 的 Socket Activation 机制，可用于配置 network namespace，也可用于出口 interface 配置。我们会在之后提供配置样例。

{% hint style="info" %}
Snell v5 的服务端可以向下兼容 v4 客户端。如果不想使用 QUIC Proxy Mode 功能，将客户端设置为 v4 版本即可。Dynamic Record Sizing 的优化只和服务端有关。
{% endhint %}

### v4.1.1

* 修正了 UDP 转发过程中可能出现的崩溃问题。

{% code overflow="wrap" %}

```markdown
https://dl.nssurge.com/snell/snell-server-v4.1.1-linux-amd64.zip
https://dl.nssurge.com/snell/snell-server-v4.1.1-linux-i386.zip
https://dl.nssurge.com/snell/snell-server-v4.1.1-linux-aarch64.zip
https://dl.nssurge.com/snell/snell-server-v4.1.1-linux-armv7l.zip
```

{% endcode %}

### v4.1.0

* 新增 dns 参数，用于自定义 DNS 服务器地址，支持配置多个地址。
* 将 DNS 库 c-ares 更新至最新版本，解决与特定 DNS 记录的兼容性问题。
* 启动时输出当前使用的 DNS 服务器。
* 调整日志输出，将 broken pipe 错误信息降低至 verbose 级别。
* 将 libuv 更新至 v1.48.0，修正在部分系统上访问 IPv6 地址时可能出现的崩溃问题。
* 改进 DNS 错误的日志信息。
* 修正某些无效 DNS 记录可能导致崩溃的问题。

### v4.0.1

修正了 UDP 数据包无法转发至 IPv6 地址的问题。

## 使用 Surge Mac 作为 Snell 代理服务端

你也可以将 Surge Mac 用作 Snell 代理服务端（自 3.1.0 版本起）。在配置中添加以下内容：

```
[Snell Server]
interface = 0.0.0.0
port = 6160
psk = RANDOM_KEY_HERE
```

Surge 内置的 Snell 服务端使用 Snell V1 协议。
