为讨论方便,本文会存在引用、举例的内容;为内容安全性,在此不提供具体的方法。

铺垫

传输协议

HTTP(Hyper Text Transfer Protocol,超文本传输协议)

这是用于从万维网( WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议,是基于 TCP/IP 通信协议来传递数据。日常浏览的各种网页都是通过该协议传输,但是它的过程没有加密,不安全。

HTTPS(HyperText Transfer Protocol Secure,超文本传输安全协议)

这是一种通过计算机网络进行安全通信的传输协议。它经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包,HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换资料的隐私与完整性。

HTTP 的 URL 是由 http:// 起始与默认使用端口 80,HTTPS 的 URL 是由 https:// 起始与默认使用端口 443

SSL/TLS(Secure Socket Layer,安全套接层;Transport Layer Security,传输层安全)

它是一种密码通信框架,他是世界上使用最广泛的密码通信方法。SSL/TLS 综合运用了密码学中的对称密码,消息认证码,公钥密码,数字签名,伪随机数生成器等,可以说是密码学中的集大成者。TLS 实际上相当于 SSL 的后续版本。

SNI(Server Name Indication,服务器名称指示)

它是 TLS 的扩展,这允许在握手过程开始时通过客户端告诉它正在连接的服务器的主机名称,用来解决一个服务器拥有多个域名的情况。

GFW 常见保护原理

众所周知防火长城(以下简称 GFW)这个工程由若干个部分组成,实现不同功能,其最大的功能是监控和过滤互联网内容。

它对网络内容的过滤和分析是双向的,GFW 不仅针对大陆读者访问国外网站进行干扰,也对国外访问者访问在大陆的网站进行处理。

关键字过滤

Http 协议数据包头部是明文的,所以 GFW 一旦发现连接有敏感词,马上就会伪装成连接两方,向真正的对方发送 RST 数据包,产生异常,从而导致对方关闭连接。

IP 封锁

在出境的网关上加一条伪造的路由规则,从而使一些 IP 的数据包无法正确地被送达。其封路由比较严格,可能因为某个敏感站点,导致跟他同一 IP 的其他站点也无法访问。

DNS 污染、劫持

它会对所有经过骨干出口路由的在 UDP 的 53 端口上的域名查询进行检测,一旦发现有黑名单里的域名,它就会伪装并返回虚假结果。由于 UDP 自身现实,访问者只能接受到最先返回的结果。即便使用 TCP 协议,它可能会发送 RST,导致连接被重置。

特定端口

字面意思,丢弃特定端口上的数据包,使得某些功能无法使用,例如封锁 443 端口会导致 SSL 故障。

加密连接的干扰

由于加密传输公钥仍然是明文,因此它能据此识别特定服务的证书,在遇到黑名单”加密连接时,它会发送 RST 数据包,干扰连接从而切断握手。

网站受屏蔽情况

实际上有与之相似情况的网站还有很多,譬如 Steam、GitHub 等,这里以 Pixiv 作引。

通常情况下,对于这些网站,如果只用 hosts 解析 IP 地址,连接仍会被 GFW 抢先发送的 RST 报文重置。

可在这个情况下,有些民间客户端居然能绕开这个限制……

SNI 原理

TLS 有一个扩展,使得访问在 Client Hello 阶段客户端浏览器会以明文形式向服务器发送要访问网站的域名。

在最开始的 Clint Hello 阶段,双方还没有确认加密方式,在报文中采用的是明文状态,其中 Extension 字段中包含了 SNI 信息,也就是当前正在请求的域名,而这个信息可通过抓包得到。

SNI 的重要过程之一便是在客户端与服务器建立连接的时候就发送要连接的域名,以便服务器返回一张颁发给指定域名的证书;如果这是个不存在的域名,服务器会发送一张默认证书给客户端以便连接能够继续,随后进行握手步骤,在协商结束后开始通讯加密。

而 GFW 能根据这段明文进行处理,即通过 Server Name 字段来检查域名,判断是否阻止对这个 IP 的连接,从而导致无法正常访问。

域前置

域前置(Domain Fronting)则是利用有的服务器不验证 SNI 的这一特点,给 GFW 和服务器一个假的 SNI。GFW 没有私钥,只能通过 SNI 和 IP 判断网站,因此可以被欺骗。但服务器有私钥,解开后,服务器是通过 HTTP 请求头判断你要访问哪个网站的,SNI 便暂可搁置一旁了。

但毕竟需要服务端有配置,如果服务器不能以我们希望的方式响应无效的 Server Name,在收到这样的数据包后直接拒绝连接,那这种方法就失效了。

有的网站比如 Google 这类 IP 黑洞的网站,仅使用域前置时无效的,因为通常被 SNI 阻断的网站,也有 DNS 污染。而且对于有些一定要用 SNI 证书的而言(譬如虚拟主机、Cloudflare 免费版),唯一的解决办法就是 ESNI。

后记

参考:

https://www.xkww3n.cyou/2020/05/01/sni-blocking-and-domain-fronting/
https://gulut.github.io/gulut-blog/post1/2020/05/31/2020-05-31-by-pass-the-gfw-by-sni/