Shadowsocks和Trojan区别:两种伪装思路的分水岭
一句话结论
Shadowsocks 用自有加密协议配合混淆隐藏流量特征,Trojan 则把数据塞进标准 TLS 通道,让流量看起来就是访问一个普通 HTTPS 网站。前者握手更轻、延迟略低,后者在审查更严格的网络里更不容易被单独挑出来。机场同时提供两种,是为了覆盖不同网络环境。
订阅列表里 SS 和 Trojan 常常并排出现,名字后面跟着同一个地区、同一个序号,看起来像是同一个东西的两个版本。它们确实做同一件事——把你的流量搬到境外再放出去——但在「怎么让中间的观察者看不出这是代理」这个问题上,两者选了完全相反的路。
Shadowsocks 的思路是不像任何东西。它自己定义了一套加密格式,数据包出去之后既不是 HTTPS 也不是别的常见协议,内容是一串没有明显结构的随机字节。理想情况下,观察者只能看到「两台机器在交换看不懂的数据」。
Trojan 的思路正好相反,是像最普通的东西。它不发明新格式,而是直接建立一条标准的 TLS 连接——和你打开任何一个 HTTPS 网站时用的是同一套握手流程——然后把代理数据塞进这条已经建立好的加密通道里。观察者看到的是一次完全合规的 HTTPS 访问,和刷网页的流量混在一起。
一句话说清:两者分别把流量伪装成了什么
用一张表把分歧摆出来会更清楚:
| 维度 | Shadowsocks | Trojan |
|---|---|---|
| 伪装目标 | 不像任何已知协议,呈随机噪声 | 像一次普通的 HTTPS 网站访问 |
| 加密来源 | 自有加密算法(如 AEAD 系列) | 标准 TLS 协议栈 |
| 必需资源 | 服务器 IP、端口、密码 | 域名、有效证书、443 端口 |
| 被识别时的样子 | 「一条特征不明的加密流」 | 「一次到某站点的 HTTPS 请求」 |
| 被主动探测时 | 通常无响应或直接断开 | 可回落到一个真实网页 |
这里的关键词是「回落」。Trojan 服务端在收到密码不正确的连接时,可以把这次请求交给背后一个真实的网站程序处理,于是探测者会拿到一个正常的网页而不是错误。Shadowsocks 没有这一层,密码不对就是不通,这个「不通」本身反而成了一种特征。
握手过程有什么不同,为什么 Trojan 必须有域名
Shadowsocks 的连接几乎没有协商阶段。客户端拿密码派生出密钥,加密第一个数据包直接发出去,服务端解得开就继续,解不开就丢弃。整个过程一个来回都不用等。
Trojan 必须先完成一次完整的 TLS 握手:客户端发起 ClientHello 并在其中带上要访问的域名(SNI 字段),服务端返回证书,双方校验并协商出会话密钥,之后才开始传代理数据。证书需要和域名对得上,所以机场必须给你一个真实域名,而不能只给 IP。
一份典型节点配置的结构大致是这样(以下均为结构示例,地址不可用):
{
"protocol": "trojan",
"server": "node-hk-01.example.invalid",
"port": 443,
"password": "示例密码",
"sni": "node-hk-01.example.invalid",
"skip-cert-verify": false
}
对比同一台机器上的 Shadowsocks 节点,字段少了整整一层:
# 结构示例,地址不可用
type: ss
server: 203.0.113.10
port: 8388
cipher: aes-256-gcm
password: 示例密码
skip-cert-verify设为 true 会跳过证书校验。它能让填了 IP 的 Trojan 节点勉强连上,代价是失去了对中间人替换证书的防护。除非你清楚自己在做什么,否则不建议长期开着。
严格网络环境里,谁更不容易被拦
校园网、公司网和部分酒店网络的共同点是:出口设备通常比家庭宽带做更细的流量分类,有的只放行常见端口,有的会对加密流做统计特征分析。
| 网络环境的做法 | Shadowsocks 的处境 | Trojan 的处境 |
|---|---|---|
| 只放行 80/443 端口 | 需要把端口改到 443 才可能通过 | 天然就在 443 上 |
| 按协议指纹分类 | 「无法归类的加密流」容易被标记 | 归类为 HTTPS,与正常流量同组 |
| 主动探测可疑服务器 | 无响应,反而坐实可疑 | 回落到真实网页,看起来正常 |
| 强制 TLS 中间人审计 | 不受影响(本来就不是 TLS) | 证书被替换会导致握手失败 |
最后一行值得注意:在会做 TLS 解密审计的企业网里,Trojan 反而会因为证书校验失败而连不上,而 Shadowsocks 只要端口放行就可能正常。所以「Trojan 一定更能穿」并不成立,要看对面拦的是什么。这类现象的排查顺序在连接失败的分层排查方法里有更完整的流程。
延迟和 CPU 开销,普通人感知得到吗
理论上的差距是确定的:Trojan 首次建连多一轮 TLS 握手,增加一个 RTT;TLS 的加解密走的是系统或库的优化实现,现代 CPU 大多有硬件加速,单条连接的开销可以忽略。
按常见的跨境线路往返延迟推算,一个 RTT 大约是几十到一百多毫秒,只影响「第一次打开某个网站」的那一瞬间。连接建立之后,两者的传输阶段开销都很小。真正让你觉得慢的东西,几乎都排在协议之前——套餐带宽上限、跨境路径质量、落地节点负载。这三项的权重排序在协议对速度到底有多大影响里做了拆解。
一个能自己验证的做法:同一个机场里挑地区相同、序号相邻的一组 SS 和 Trojan 节点,在同一时间段内交替测五轮,取中位数而不是最快值。多数情况下差距会落在测量噪声范围内。
客户端支持度上的实际差别
- Shadowsocks:出现最早,几乎所有客户端都原生支持,老版本、小众工具、路由器固件通常也能用。代价是各家对混淆插件的实现不完全一致,插件参数填错就连不上。
- Trojan:主流客户端支持完整,但对证书、SNI、ALPN 这些字段的默认值处理各不相同,跨客户端复制配置时最容易出问题的就是这几项。
如果你在多台设备上共用一份订阅,遇到「电脑能连手机不能连」的情况,先比对两端的 SNI 和证书校验开关,而不是先怀疑节点挂了。各客户端的导入差异可以对照 Clash 配置教程与 Shadowrocket 使用教程。
机场为什么在同一批服务器上同时开两种
原因很务实:同一台落地机器上多开一个协议端口,边际成本接近于零,但能覆盖到的用户网络环境明显更多。家里宽带宽松的用户用 SS 省点开销,校园网用户切到 443 上的 Trojan,谁都不用换机场。
这也解释了为什么同名同地区的两个节点速度往往几乎一样——它们本来就是同一台机器、同一条线路,只是入口协议不同。把速度差异归因于协议,通常是把线路和负载的锅算到了协议头上。
什么情况下应该主动换到另一种协议
按现象决定,而不是按「哪个更先进」:
| 你遇到的现象 | 建议动作 |
|---|---|
| 换到某个网络后 SS 节点全部超时,Trojan 正常 | 长期用 Trojan,该网络很可能在做协议识别 |
| Trojan 报证书错误或握手失败,SS 正常 | 该网络可能有 TLS 审计,改用 SS |
| 两者都能连但都慢 | 与协议无关,换节点或查线路 |
| 只有个别网站打不开 | 属于分流规则或 DNS 问题,别动协议 |
| 设备老旧、客户端版本很低 | 优先 SS,兼容面更宽 |
换协议之前先确认问题的范围:是所有节点都这样,还是只有某几个?是所有网站,还是只有一类?范围搞错,换什么协议都不会好。
小结
Shadowsocks 赌的是「看不懂就不会管」,Trojan 赌的是「看起来正常就不会管」,两条路各有失效的场景。Trojan 需要域名和证书,因此配置项更多,出错点也集中在 SNI 与证书校验上。性能差距在同一条线路上小到需要多轮测试才能分辨,不值得作为选择依据。真正该看的是你所处网络的拦截方式:被端口和指纹卡住就走 Trojan,被 TLS 审计卡住就走 SS。两种都留在订阅里,遇到问题时手上才有第二个选项。
常见问题
Trojan 一定比 Shadowsocks 安全吗?
两者的加密强度都足够,差别不在于「能不能被解密」,而在于「容不容易被认出来是代理」。在识别手段温和的网络里两者体感一致;在会做协议指纹分析的网络里,套在标准 TLS 里的 Trojan 更难被单独挑出。
为什么我的 Trojan 节点填了 IP 就连不上?
Trojan 依赖 TLS 握手中的域名字段来匹配证书。直接填 IP 时证书校验通常失败,客户端会报证书不受信任或握手中断。正确做法是填机场给的域名,如果必须用 IP,则要另行指定 SNI 与证书校验选项。
Shadowsocks 已经过时了吗?
没有。它仍然是握手开销最小、客户端兼容面最广的一种方案,在网络环境宽松的地区依然常用。它的弱点是在做深度协议识别的网络里特征相对明显,而不是加密本身有问题。
同一个机场里 SS 和 Trojan 的节点,速度会差很多吗?
如果两者跑在同一台落地服务器、走同一条线路,差距通常只有几毫秒的握手延迟和很小的 CPU 开销,远小于线路本身的影响。速度差异更可能来自不同节点被分配了不同的线路或负载。