基础原理

DPI 如何封锁 VPN

封锁 VPN 的网络很少只做一件事。它同时运行着好几种检测方法,每一种都便宜到可以施加于每一条连接,而隧道必须全部挺过去才能保持可用。下面是每一种方法的作用。

阅读约 1 分钟最后复核

封锁是分层的,不是单一的

把一套过滤部署想成一连串关卡而不是一堵墙,会有帮助。一条连接先要与地址列表核对,然后其协议被分类,再然后其元数据与规则匹配,之后——可能是几小时以后——它的端点还可能被探测,以确认那里运行过什么。如果下一道关卡会抓住你,那么通过其中一道毫无意义。

这也解释了很多人感到困惑的一种经历:隧道完美运行了几周,然后在你这边什么都没改的情况下停止工作。你的流量没有任何变化。是端点在带外被识别出来,并被加进了某个列表。

关卡一:协议指纹

最古老也最廉价的方法,是从 VPN 协议自己的握手里认出它。大多数 VPN 协议是在威胁模型还是窃听者而非分类器的年代设计的,它们在线路上明明白白地宣告自己。

常见 VPN 协议在线路上的可辨识程度
协议暴露它的特征检测难度
PPTP / L2TP专用协议号和固定端口;握手一目了然。极易
IPsec / IKEv2UDP 500 与 4500,带有特征鲜明的 IKE 交换。极易
WireGuard第一个握手消息大小固定,且在已知偏移处有一个固定的类型字节,走 UDP。极易
OpenVPN控制通道中可辨识的操作码结构,即使在 443 端口的 TCP 模式下也是如此。容易
Shadowsocks(早期版本)完全没有握手,这本身就不寻常;早期版本还易受主动探测影响。中等
包裹在 TLS 中的隧道完全取决于 TLS 模仿得有多逼真;常见的破绽是握手指纹不匹配。中等到困难

关卡二:握手中的主机名

对任何自称是 TLS 的东西来说,下一项检查是 Server Name Indication 字段——客户端所请求的主机名,在加密开始之前明文发送。它的存在是为了让一个 IP 地址能够托管许多站点,而实际上几乎每一套运行中的过滤系统都会读取它。

  • 黑名单:如果主机名出现在列表中,连接被丢弃。大多数站点级封锁就是这样运作的。
  • 白名单:如果主机名不在列表中,连接被丢弃。这激进得多,用于某些企业和国家级网络,而且要绕过它难得多。
  • 一致性校验:将主机名与其解析到的地址、或与服务器出示的证书相比对。不一致会被视为可疑。

Encrypted Client Hello 是针对这一点的标准化解决方案:它加密主机名,使观察者无法读取。但它的采用还不完整,依赖于网络同样可能控制的 DNS 记录,而且在几乎无人使用它的网络里,你使用它这件事本身就是一个信号。它改善了状况,但没有关上这道关卡。

关卡三:这个 TLS 像真正的浏览器吗?

如果 TLS 本身看起来就不对,那么把隧道包进 TLS 也没用。客户端的开场消息带着一份有序的密码套件、支持的群组、签名算法和扩展列表。确切的组合因实现而异——Go 程序、OpenSSL 程序和 Chrome 产生的 Client Hello 明显不同——并且可以被哈希成一个简短的指纹。

如果一条连接自称是在与 Web 服务器对话的浏览器,却带着 Go 网络库的 TLS 指纹,仅凭这一处矛盾就足以把它分类出来。这就是为什么严肃的实现不只是「使用 TLS」:它们逐字节复现某个特定浏览器的握手,并且必须随着浏览器的变化持续这样做。

关卡四:主动探测

最持久的检测方法根本不对你的流量做分类。系统注意到你连接了一个陌生地址,然后自己去连接那个地址,假装成客户端。回来的东西决定判决。

  1. 观察

    一条通往无信誉记录、无相应 DNS 历史、且流量特征异常的地址的流,会被记录下来以备后续处理。

  2. 探测

    系统对该地址发起自己的连接,有时重放它从你的会话中捕获的字节,有时发送刻意构造的垃圾数据。

  3. 判定

    普通 Web 服务器会返回正常响应或一个 TLS 警报,并且无论收到什么乱七八糟的东西,行为都一致。一个粗糙的代理则回应得不一样——它可能卡住、立即关闭,或者以任何 Web 服务器都不会有的方式作答。

  4. 行动

    如果回应异常,该地址进入封锁列表,那个端口对所有使用它的人都不再可用。

防御之道是:对任何没有有效凭据的人——包括在恶意输入之下——服务器都必须真正与普通站点无从区分。这一族协议的做法是把未经认证的连接转发给一台真正的 Web 服务器,并让那台服务器来作答——于是探测者收到的是一个真实站点,因为它确实到达了一个真实站点。

关卡五:地址信誉

与线路上发生的一切无关,地址本身也带有信誉。知名主机托管商的地址段被广泛标记为数据中心空间,某些网络会默认对其加以限制或额外验证。而公开列表中发布过的地址——由服务商发布、写在应用商店说明里、或者出现在论坛帖子中——根本不需要任何检测就能被封锁。

没有任何协议设计能解决这一点。这是地址的属性,不是流量的属性。端点轮换因此而存在,一个被广泛分享的公开端点之所以比小范围分发的端点寿命更短,原因也在这里。

关卡六:劣化而非封锁

封锁是显眼的,会招来投诉。放慢流量则不然。一条被分类为「疑似隧道」的流可以被整形到几百 kbps,使即时通讯勉强可用、视频彻底不可能,而看上去与一个拥塞的网络毫无二致。

从客户端一侧看,它的特征是:连接正常建立,以全速传输一小阵,然后稳定在一个低而可疑地平稳的速率上——平稳本身就是破绽,因为真正的拥塞是波动的。确认它的办法,是在同一时刻与一条通往无关目的地的对照连接做对比测量。

协议设计能解决什么、不能解决什么

检测手段与协议设计能够作出的应对
手段协议设计能应对吗?
协议握手指纹能——通过根本不产生指纹,或产生浏览器的指纹。
TLS 指纹不匹配能——通过精确复现真实客户端的握手。
握手中的主机名部分能——借用一个可信的域名,或在支持之处将其加密。
主动探测能——通过作出与普通服务器完全一致的回应。
地址封锁列表不能——这与地址有关,与流量无关。
统计流量分析部分能——填充与节奏控制会抬高成本,代价是吞吐量。
默认拒绝的白名单不能——只放行指定目的地的网络,什么都过不去。

诚实的结论是:协议设计能很好地应对前四项,对第五项无能为力,对最后两项只能抬高成本。任何声称某个隧道「无法被检测」的说法,描述的都是一套尚未遇到过意志坚决的运营方的系统。

常见问题

我的 VPN 用了好几个月,为什么突然就不行了?

多数情况下,并不是你的流量发生了变化,而是端点地址被识别并列入了封锁名单。这种识别可能通过主动探测发生,也可能因为该地址出现在某个公开列表中,或者仅仅因为流量规模——单个地址承载着异常大量的长连接流量,是会引起注意的。

WireGuard 会被 DPI 封锁吗?

它是最容易被识别的协议之一,因为它的第一个握手消息大小固定,且在已知偏移处带有一个固定的类型字节。在按协议指纹过滤的网络里,它通常很早就被封掉。这并不说明它在不受过滤的网络上的协议素质——在那里它非常出色。

使用 443 端口能让 VPN 无法被检测吗?

不能。自从检测成为常态,443 端口就不再是藏身之处;真正重要的是那上面的流量看起来是否像本该在那里的 HTTPS。一个未经改造就跑在 443 上的 VPN 协议,如果说有什么区别,反而更显眼,因为它声称自己是某种明显不是的东西。

一个网络能封锁所有 VPN 吗?

只放行一份明确的许可目的地清单的网络可以做到——代价是破坏大量正常使用。多数网络不会走到这一步,因为附带损害无法接受,而这正好给与放行流量相似的流量留下了空间。

HushTunnel 如何运用这些设计

HushTunnel 采用 VLESS 搭配 REALITY 与 XTLS,也就是这些指南中介绍的设计,并且不保留你访问过哪些网站的记录。

全部指南