反代加速的秘密
你是否会好奇Steamcommunity 302,Watt Toolkit这类反代加速工具是如何做到不需要代理服务器就能访问被屏蔽的网站?本篇网站为你揭开反代加速其中的秘密。
标题虽然提到了反向代理,但是反向代理并不是本篇文章的重点。
SNI阻断
我们在正常访问网页时一般会使用HTTPS加密连接相关的网站,这种连接十分安全,保护你与网站的数据不会在传输中被篡改、截取,这种连接的核心技术叫TLS或者是SSL,这类加密流量并不是完全加密,它有一个叫做SNI
的明文字段其中记录了你要访问的域名。
CDN的服务器通过读取SNI
来为客户端提供不同网站的证书用以加密流量,因为是明文的,CDN能看,别人自然也能看。
设想一下,SNI
是明文的,那么完全可以在传输数据的时候检测TLS数据包是否包含某一个域名,如果包含就切断这个连接,这样就可以实现不屏蔽IP的情况下只屏蔽在这个IP上的某一个网站了。
那能不能在SNI
中填些其他的内容呢?比如一些不受限制的网站?或者随便填写一些内容?这样做也不是不行只是……
反代加速的原理
如果你在访问teapotium.com
时为了绕开SNI阻断而将SNI
的内容改为无效的域名或者直接设置为空,那么网站服务器在这种情况下会发送一个默认的证书,在网站使用了CDN的情况下这个默认证书不太可能和域名teapotium.com
一致。
浏览器和各类HTTPS客户端会在证书和域名不一致时会阻止用户继续访问,对于类似浏览器这种不能修改的客户端就需要准备一个可以实现上述方式的反向代理服务器,然后修改系统hosts
文件将流量劫持到反向代理服务器,接下来通过安装自签证书的方式让客户端信任并且不再阻止访问。对于一些可以修改的客户端,可以直接魔改相关代码忽略证书异常强行建立连接。
现在SNI
不会暴露你要访问的网站了,那么CDN要如何知道你要访问那一个网站呢?不用担心,HTTP协议有一个host
字段,这个字段也像SNI一样写你要访问的域名,所以host
这里就是teapotium.com
,CDN会按照这个字段的内容提供数据,而SNI
仅仅用于提供TLS加密的证书。另外不同于明文的SNI
,host
是被加密的内容。
这种在SNI
中填写其他内容,而在host
填写实际访问域名的方式叫做域前置。
上面只是一个利用域前置访问teapotium.com
的例子,在实际上是行不通的,因为teapotium.com
的CDN Cloudflare不支持域前置。
不同的网站的运行方式可能有些不同,实际操作起来也会不同。
像www.pixiv.net
因为使用了Cloudflare做CDN所以无法使用域前置直接访问,但是它的一些api还可以使用域前置,比如一些Pixiv第三方客户端的开发者利用域前置访问i.pximg.net
让其客户端可以直接使用,而i.pximg.net
服务器的默认证书刚好是i.pximg.net
的证书,第三方客户端的行为由开发者控制,无需安装证书也不需要反向代理即可以轻松实现域前置访问。
反代加速(域前置)的局限性
不难发现域前置的实现离不开服务器的配合,域前置这种方式实际上是因为服务器更关注host
字段的内容,而SNI
的内容却不重要,这与其说是特性,更像一个BUG,有很多的CDN提供商不支持域前置访问。
还有一个要求是服务器的IP没有被针对,如果直接封禁IP那么SNI
不管写什么内容都没意义,因为发送SNI
的前提是数据包能正常到达目标服务器的IP。
域前置的意义
虽然有一些CDN关闭了域前置访问但是人类对于隐私追求却从未停止,因为和新的ECH协议比起来,域前置稍微有一点歪门邪道。