SS-ShadowTLS
ShadowTLS 是一种代理混淆层协议,于 2022 年 8 月发布,由开发者 @ihciah 创建。它不是一个独立的代理协议,而是一个"外壳"——在真实的 TLS 握手完成后,将内层代理流量(如 Shadowsocks)隐藏在 TLS 连接之中。其核心创新在于:它使用的 TLS 握手来自真实的后端服务器(如 nginx、nginx.org 等),因此握手过程中的每一个字节都是货真价实的 TLS 数据,无法与真实的 HTTPS 连接区分。
设计背景
现有的基于 TLS 的代理协议(如 Trojan、VLESS + TLS)虽然使用了 TLS 加密,但它们的 TLS 握手是由代理程序自身完成的,使用的是自己的 TLS 实现和证书。这带来一个问题:
- 代理程序的 TLS 实现(如 Go 的
crypto/tls、Rust 的rustls)产生的握手特征与真实浏览器存在差异 - 即使使用 uTLS 来模拟浏览器指纹,在握手数据包的细节层面仍可能存在可识别的偏差
- 主动探测者可以向服务器发出特定请求来验证服务器的行为是否符合 TLS 服务器规范
ShadowTLS 的解决方案是:让握手交给真实的 TLS 服务器来完成。
普通代理的 TLS 握手:
客户端 <---[代理程序的 TLS 实现(非真实服务器)]---> 代理服务端
ShadowTLS 的 TLS 握手:
客户端 <---[真实 TLS 服务器(如 nginx.org)的 TLS 实现]---> ShadowTLS 服务端(代理给真实服务器)
握手完成后:
客户端 <---[隐藏在 TLS 连接中的代理流量]---> ShadowTLS 服务端
这意味着握手阶段产生的每一个数据包,实际上都来自真实服务器的真实 TLS 实现,无论是证书、密码套件顺序、扩展字段,还是服务器的响应行为,都与真实访问该服务器完全一致。
版本演进
ShadowTLS 目前有三个版本,每个版本都修复了前一个版本的已知问题:
| 版本 | 发布时间 | 主要变化 |
|---|---|---|
| v1 | 2022.08 | 初始版本,握手中继,但数据阶段特征仍可识别 |
| v2 | 2022.10 | 引入 HMAC 认证标记,修复数据阶段的识别问题 |
| v3 | 2023.01 | 完全重设计,引入 authorized relay 机制,修复 v2 的重放和流量标记问题 |
关于旧版本
ShadowTLS v1 和 v2 均存在已被公开的安全和隐蔽性漏洞,请务必使用 v3 版本。当前所有主流客户端和服务端实现均已支持 v3。
工作原理
握手阶段(v3)
客户端
|
| 1. 向 ShadowTLS 服务端发起 TLS 握手(ClientHello)
v
ShadowTLS 服务端
|
| 2. 将 ClientHello 原样转发给真实 TLS 服务器(如 nginx.org:443)
| 3. 将真实服务器的 TLS 握手响应原样转发回客户端
| 4. 客户端与真实服务器完成完整的 TLS 握手(ShadowTLS 服务端只是中继)
|
| 5. 握手完成时,客户端发送一个携带 HMAC 标记的特殊数据包
| 6. ShadowTLS 服务端识别到 HMAC 标记,确认该连接为合法的 ShadowTLS 连接
v
进入数据代理阶段
在整个握手阶段,ShadowTLS 服务端只是一个透明中继——所有握手数据都来自真实的后端服务器,没有任何一个字节是 ShadowTLS 服务端自行生成的。
对于不知道密码的主动探测者:
- 探测者向服务端发起 TLS 连接
- ShadowTLS 服务端中继真实服务器的握手响应
- 握手完成后,探测者发出的数据不包含合法的 HMAC 标记
- ShadowTLS 服务端将其转发给后端真实服务器,行为与正常 TLS 反向代理一致
- 探测者得到真实网站的内容响应,无法确认代理服务的存在
数据阶段(v3)
握手完成且 HMAC 验证通过后,ShadowTLS 服务端开始将连接的后续流量转发给内层代理服务(通常是本地运行的 Shadowsocks 服务端):
客户端(ShadowTLS 客户端 + Shadowsocks 客户端)
|
| TLS 连接(握手已完成,后续流量经过 TLS 加密)
| 内层:Shadowsocks 加密流量
v
ShadowTLS 服务端
|
| 转发内层流量到本地 Shadowsocks 服务端
v
Shadowsocks 服务端(监听本地端口,如 127.0.0.1:8388)
|
v
目标服务器
HMAC 认证机制
v3 版本中,客户端在握手完成后发送一个包含 HMAC(Hash-based Message Authentication Code)标记的数据包。HMAC 使用共享密码派生密钥生成,服务端通过验证此标记来确认连接的合法性,同时防止重放攻击(每个连接的 HMAC 值不同)。
ShadowTLS 与内层协议的关系
ShadowTLS 是一个纯粹的"传输层混淆"工具,它本身不提供完整的代理功能,必须搭配一个内层代理协议使用:
客户端侧:
应用流量 → 内层代理客户端(如 Shadowsocks)→ ShadowTLS 客户端 → 网络
服务端侧:
网络 → ShadowTLS 服务端 → 内层代理服务端(如 Shadowsocks,监听本地端口)→ 目标
最常见的组合是 ShadowTLS + Shadowsocks 2022,因此通常也被称为 "SS-ShadowTLS"。
当然,理论上 ShadowTLS 可以与任何 TCP 代理协议搭配使用,包括 VLESS、VMess 等,但 Shadowsocks 2022 是最为常见和推荐的内层协议。
与其他协议的对比
| 对比维度 | SS-ShadowTLS | Trojan | VLESS + Reality | NaiveProxy |
|---|---|---|---|---|
| TLS 握手来源 | 真实后端服务器(100% 真实) | 代理程序自身(可模拟指纹) | Reality 机制(接近真实) | Chromium 网络栈(真实) |
| TLS 证书 | 来自后端服务器(不需要自己申请) | 需要自己持有 | 不需要 | 需要自己持有 |
| 需要域名 | 可以不需要(用后端 IP 即可,但推荐使用域名) | 是 | 否 | 是 |
| 主动探测防护 | 有(回落至真实服务器) | 有(回落至后端 Web) | 有(回落至目标网站) | 有(服务端即 Web 服务器) |
| 传输层 | TCP | TCP | TCP | TCP(HTTP/2) |
| 是否需要内层协议 | 是(如 Shadowsocks) | 否 | 否 | 否 |
| 配置复杂度 | 中(需要配置两层) | 中 | 中 | 中 |
| 客户端支持 | 中等 | 广泛 | 广泛 | 有限 |
ShadowTLS vs VLESS + Reality
两者在"使用真实 TLS 数据"这一点上有相似之处,但实现方式截然不同:
- VLESS + Reality:Reality 在服务端模拟真实网站的 TLS 握手行为,但握手数据并非来自真实服务器
- ShadowTLS:握手数据来自真实后端服务器的真实响应,不存在"模拟"
从纯粹的握手真实性角度看,ShadowTLS 更彻底。但 VLESS + Reality 不需要内层协议,整体配置更简洁,且不需要维护一个可被中继的后端服务器。
优缺点
| 优点 | 缺点 |
|---|---|
| 握手数据 100% 来自真实服务器,无法通过握手特征区分 | 需要配置两层协议(ShadowTLS + 内层代理),复杂度较高 |
| 不需要自己申请 TLS 证书(使用后端服务器的证书) | 依赖后端 TLS 服务器的可用性 |
| 主动探测防护完善,回落至真实网站 | 客户端支持不如 Trojan、VLESS 广泛 |
| 可与任何内层 TCP 代理协议搭配 | 仅支持 TCP,无法代理 UDP 流量 |
| 内层协议独立处理流量加密,分工明确 | 若后端服务器不稳定可能影响握手成功率 |
| v3 版本修复了所有已知安全问题 | — |
适用场景
推荐使用 SS-ShadowTLS 的场景:
- 对 TLS 握手真实性有极高要求,希望握手数据来自真实服务器
- 不想自行管理 TLS 证书,同时又需要 TLS 级别的伪装
- 已有 Shadowsocks 2022 基础设施,希望在外层叠加更强的 TLS 伪装
- 对协议实现细节感兴趣,希望在技术上使用最接近"真实 TLS"的方案
需要考虑替代方案的场景:
- 配置简洁性优先(直接用 VLESS + Reality 即可,无需两层配置)
- 客户端兼容性要求高(ShadowTLS 的客户端支持不如主流协议广泛)
- 需要 UDP 代理能力(ShadowTLS 仅支持 TCP,需要搭配其他方案)
- iOS 主力用户(iOS 主流客户端对 ShadowTLS 的支持有限)
实用性权衡
ShadowTLS 的设计思路十分精妙,但在日常使用中,VLESS + Reality 通常能提供足够强的抗检测能力,且配置更简单、客户端支持更广。ShadowTLS 更适合对协议细节有深入研究兴趣的用户,或在特定的高强度审查场景下作为针对性选项。
服务端部署参考
以下以 ShadowTLS v3 + Shadowsocks 2022 的组合为例进行说明。
前置条件
- 一台公网 VPS,已开放 TCP 443 端口(或其他目标端口)
- 无需域名和证书(会使用后端服务器的证书)
- 已安装 shadowsocks-rust(内层代理服务端)
安装 ShadowTLS 服务端
从 GitHub Releases 下载预编译二进制文件:
# 访问 https://github.com/ihciah/shadow-tls/releases 获取最新版本
# 以 Linux amd64 为例
wget https://github.com/ihciah/shadow-tls/releases/latest/download/shadow-tls-x86_64-unknown-linux-musl.tar.xz
tar -xJf shadow-tls-*.tar.xz
chmod +x shadow-tls
mv shadow-tls /usr/local/bin/shadow-tls
配置内层 Shadowsocks 2022 服务端
内层 Shadowsocks 服务端监听在本地端口(不对外暴露),只接受来自 ShadowTLS 转发的连接:
生成 Shadowsocks 2022 密钥:
openssl rand -base64 32
创建 Shadowsocks 配置文件 /etc/shadowsocks/config.json:
{
"server": "127.0.0.1",
"server_port": 8388,
"method": "2022-blake3-aes-256-gcm",
"password": "your-ss2022-key-base64",
"mode": "tcp_only"
}
注意:server 必须设置为 127.0.0.1,确保 Shadowsocks 只监听本地端口,不直接对外暴露。
启动 Shadowsocks 服务端:
ssserver -c /etc/shadowsocks/config.json -d
或通过 systemd 管理:
[Unit]
Description=Shadowsocks Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/ssserver -c /etc/shadowsocks/config.json
Restart=on-failure
[Install]
WantedBy=multi-user.target
启动 ShadowTLS 服务端
ShadowTLS 使用命令行参数或环境变量进行配置:
shadow-tls \
--threads 4 \
server \
--listen 0.0.0.0:443 \
--server 127.0.0.1:8388 \
--tls www.bing.com:443 \
--password your-shadowtls-password
参数说明:
| 参数 | 说明 |
|---|---|
--listen | ShadowTLS 监听的地址和端口,对外暴露 |
--server | 内层代理服务端的地址和端口(本地 Shadowsocks) |
--tls | 用于握手中继的后端 TLS 服务器,应选择真实存在且支持 TLS 1.3 的网站 |
--password | ShadowTLS 的认证密码,用于 HMAC 验证 |
--threads | 工作线程数,通常设置为 CPU 核心数 |
选择后端 TLS 服务器的原则:
- 必须是真实存在的 TLS 1.3 站点
- 应选择在中国大陆无法直接访问的境外网站(与 Reality 的选择原则相同)
- 推荐使用大型知名网站,如
www.bing.com:443、addons.mozilla.org:443、www.microsoft.com:443
关于后端 TLS 服务器的连接
ShadowTLS 服务端在握手阶段需要实时向后端 TLS 服务器(如 www.bing.com)发起 TCP 连接,以完成握手中继。如果你的 VPS 无法连接所选的后端服务器,握手将会失败。请事先测试服务器能否正常连接所选的后端目标。
Systemd 服务单元(ShadowTLS)
[Unit]
Description=ShadowTLS Server
After=network.target shadowsocks.service
[Service]
Type=simple
ExecStart=/usr/local/bin/shadow-tls --threads 4 server \
--listen 0.0.0.0:443 \
--server 127.0.0.1:8388 \
--tls www.bing.com:443 \
--password your-shadowtls-password
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
启动顺序
需要先启动内层 Shadowsocks 服务,再启动 ShadowTLS:
systemctl daemon-reload
systemctl enable shadowsocks
systemctl start shadowsocks
systemctl enable shadow-tls
systemctl start shadow-tls
# 验证运行状态
systemctl status shadow-tls
journalctl -u shadow-tls -f
开放防火墙规则
ufw allow 443/tcp
客户端配置参考
使用 sing-box 配置(推荐)
sing-box 原生支持 ShadowTLS v3,可以直接在配置文件中将内层协议与 ShadowTLS 结合:
{
"type": "shadowtls",
"tag": "shadowtls-node",
"server": "your.server.ip",
"server_port": 443,
"version": 3,
"password": "your-shadowtls-password",
"tls": {
"enabled": true,
"server_name": "www.bing.com",
"utls": {
"enabled": true,
"fingerprint": "chrome"
}
},
"detour": "ss-inner"
}
同时配置内层 Shadowsocks 出站(作为 shadowtls 的 detour 目标):
{
"type": "shadowsocks",
"tag": "ss-inner",
"server": "your.server.ip",
"server_port": 443,
"method": "2022-blake3-aes-256-gcm",
"password": "your-ss2022-key-base64"
}
完整的 sing-box 客户端配置(出站部分):
{
"outbounds": [
{
"type": "shadowsocks",
"tag": "ss-out",
"server": "your.server.ip",
"server_port": 443,
"method": "2022-blake3-aes-256-gcm",
"password": "your-ss2022-key-base64",
"detour": "shadowtls-out"
},
{
"type": "shadowtls",
"tag": "shadowtls-out",
"server": "your.server.ip",
"server_port": 443,
"version": 3,
"password": "your-shadowtls-password",
"tls": {
"enabled": true,
"server_name": "www.bing.com",
"utls": {
"enabled": true,
"fingerprint": "chrome"
}
}
},
{
"type": "direct",
"tag": "direct"
}
]
}
在这个配置中,ss-out 使用 shadowtls-out 作为其传输通道(detour),实现了 Shadowsocks 流量通过 ShadowTLS 隧道的效果。
Mihomo 配置
Mihomo 从较新的版本开始支持 ShadowTLS v3:
proxies:
- name: "ss-shadowtls"
type: ss
server: your.server.ip
port: 443
cipher: 2022-blake3-aes-256-gcm
password: "your-ss2022-key-base64"
plugin: shadow-tls
plugin-opts:
host: www.bing.com
password: "your-shadowtls-password"
version: 3
使用原版 ShadowTLS 客户端
在不支持 ShadowTLS 的客户端上,可以在本地运行一个 ShadowTLS 客户端,将流量转为本地的 Shadowsocks 格式后,再由 Shadowsocks 客户端处理:
shadow-tls \
client \
--listen 127.0.0.1:8389 \
--server your.server.ip:443 \
--tls www.bing.com \
--password your-shadowtls-password
然后将 Shadowsocks 客户端的服务器地址指向 127.0.0.1:8389,密码和加密方式与服务端内层 Shadowsocks 配置一致。
客户端支持
| 平台 | 客户端 | 支持状态 | 版本要求 |
|---|---|---|---|
| Windows / macOS / Linux | sing-box | 支持(v3) | sing-box 1.3+ |
| Windows / macOS / Linux | Mihomo | 支持(v3) | 较新版本 |
| Windows / macOS / Linux | ShadowTLS 原版客户端 | 支持 | 任意版本 |
| Windows / macOS / Linux | v2rayN | 支持 | 需要搭配 sing-box 内核 |
| iOS | Shadowrocket | 支持(v3) | 需要较新版本 |
| iOS | Stash | 支持 | 需要较新版本 |
| iOS | Quantumult X | 支持(v1/v2) | v3 支持有限 |
| iOS | Loon | 支持 | 需要较新版本 |
| iOS | Surge | 支持 | 需要较新版本 |
| macOS | Stash | 支持 | — |
| Android | NekoBox | 支持 | 通过 sing-box 内核 |
| Android | Husi | 支持 | sing-box 内核 |
| Android | Exclave | 支持 | — |
| Linux | dae | 支持 | 较新版本 |
关于 Quantumult X 的支持
Quantumult X 早期对 ShadowTLS v1/v2 有支持,但 v3 的支持进度较慢,建议查阅最新版本的更新日志确认当前版本是否已支持 v3。
常见问题
Q:ShadowTLS 和 Trojan 都用了 TLS,主要区别是什么?
关键区别在于 TLS 握手数据的来源:
- Trojan 的 TLS 握手由运行 Trojan 的服务器自身完成,证书是你自己申请的,握手数据来自你自己部署的 TLS 实现
- ShadowTLS 的 TLS 握手来自一个真实的第三方服务器(如 www.bing.com),服务端只是一个透明中继,握手数据的每一个字节都是真实服务器的真实输出
从主动探测的角度:
- 探测 Trojan 服务器时,得到的证书是你自己的,TLS 实现特征来自 Xray/sing-box
- 探测 ShadowTLS 服务器时,得到的证书是 www.bing.com 的,TLS 实现特征来自微软的服务器
Q:后端 TLS 服务器(如 www.bing.com)能感知到被 ShadowTLS 使用吗?
可以感知到一定的异常,因为 ShadowTLS 服务端会频繁向该服务器发起 TLS 握手请求(每个新的代理连接都会触发一次握手)。这是 ShadowTLS 设计上的一个固有特征。选择大型云服务提供商的域名(如微软、谷歌等)有助于降低被注意到的风险,因为这些服务每天处理的握手请求数量极为庞大。
Q:为什么必须使用 v3,不能用 v1 或 v2?
- v1 在数据传输阶段存在可识别的流量特征,握手后的流量模式可以被检测
- v2 引入了 HMAC 标记,但存在重放漏洞——攻击者可以捕获合法的连接并重放
- v3 重新设计了认证机制,修复了上述所有已知问题
Q:服务端的 --tls 参数使用 IP 还是域名?
强烈推荐使用域名(如 www.bing.com:443),而不是 IP 地址。使用域名时,TLS 握手中的 SNI(Server Name Indication)字段与目标服务器一致,流量特征最为自然。使用 IP 地址可能导致 SNI 为空或异常,反而暴露特征。
Q:SS-ShadowTLS 节点可以用订阅链接分发吗?
可以。SS-ShadowTLS 有对应的 URI 格式,支持在 Clash/Mihomo、Shadowrocket 等客户端中通过订阅方式使用。具体的 URI 格式取决于客户端实现,通常是在 Shadowsocks URI 的基础上附加 ShadowTLS 的插件参数。
Q:内层协议一定要用 Shadowsocks 吗?
不是。ShadowTLS 只是一个传输层混淆外壳,内层可以使用任何 TCP 代理协议。Shadowsocks 2022 是最常见的选择,因为它安全性好、性能高且无额外加密开销(外层 TLS 已提供加密)。理论上也可以使用 VLESS(无加密模式)或 VMess 作为内层,但实际上没有太大意义。
延伸阅读
- Shadowsocks 2022 — 了解 ShadowTLS 最常见的内层协议
- VLESS 协议 — 无需内层协议且无需域名的 Reality 方案,综合实用性更高
- NaiveProxy — 同样关注 TLS 真实性的另一种方案(基于 Chromium 网络栈)
- AnyTLS 协议 — 关注 TLS 会话行为模式伪装的新型协议
- 代理协议总览 — 回到协议总览页面