起因
好吧,博客也是喜提郭利帝国运营商的认可了,喜提运营商DNS封锁,(其实也是意料之中了)那么,什么是运营商DNS封锁呢?其原理有哪些?又有什么解决手段呢?
本文将通过站长服务端和访客客户端来描述如何处理这种情况。
封锁方法一:80端口跳转劫持
先放图,可以看到当客户端输入网址furries.fun时,运营商DNS返回来的数据是跳转到0.0.0.0空地址
![[矛与盾]运营商封锁的原理以及“低成本”解决方案 67 0000 1](https://furries.fun/wp-content/uploads/2024/11/0000-1.png)
来自郭利帝国某庆洲的“润特数字移动运营商”返回的数据包
而正常的DNS返回来的数据应该是这样的:
HTTP/1.1 301 Moved Permanently Content-Type: text/html; charset=utf-8 Location: https://furries.fun/ Server: mwm.moe Date: Sat, 30 Nov 2024 09:41:39 GMT Content-Length: 0 HTTP/1.1 200 OK Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 Content-Encoding: br Content-Type: text/html; charset=UTF-8 Date: Sat, 30 Nov 2024 09:41:47 GMT Server: mwm.moe Strict-Transport-Security: max-age=63072000; includeSubDomains; preload X-Cache: BYPASS Transfer-Encoding: chunked
可以明显的看出,客户端先是访问DNS要服务器的IP地址,DNS查询到了服务器的IP,然后再访问服务器的80端口,服务器因为开启了强制HTTPS所以应该要跳转到同一个IP的443端口,但是!返回来的HTTP头部包因为是明文(此时还未建立TLS连接)而被中间人篡改成了跳转到0.0.0.0这个保留的空地址,所以就出现了错误页面。
采用 HTTP 302 跳转进行缓存劫持而不是直接反向代理篡改原始数据原因
HTTP 302 跳转方式部署起来最容易,成本最低。因为不需要对原有设备进行改造,只需要在交换机上以分光并联的方式进行连接即可。劫持设备的 DPI(深度包检测)系统可以实时探测用户和正常服务器的通信内容,可根据网络状况、劫持服务器负载、用户身份、访问内容、劫持概率等按需进行劫持。劫持时,只要伪造目标服务器的身份抢在真正的服务器之前向用户发送一条 HTTP 302 报文让用户跳转到新地址即可完成劫持。劫持设备与路由设备分离,方便维护
而如果直接篡改原始数据,则需要对原有设备进行改造,串联进路由设备,对每一个通过的数据包进行探测,决定放行或劫持。由于无法从目的 IP 判断数据包应发往真正的服务器还是截持服务器,这种系统还要为每个用户维护一份连接会话信息来作区分。可以想象的是,这套系统将对网络性能产生巨大的负面影响,并且难以维护
(来自:运营商劫持 -伊尼博客园))
解决办法
使用HSTS Preload预加载
要先了解HSTS预加载,得先了解什么是HSTS
HSTS(HTTP Strict Transport Security)是一种安全机制,它强制浏览器只通过 HTTPS(加密的 HTTP)来连接特定的网站。换句话说,一旦浏览器知道某个网站开启了 HSTS,它就会自动将所有对该网站的请求升级为 HTTPS 请求,即使用户输入的是 HTTP 地址。
ref(APA): 雪.雪猫社.https://www.yukicat.net. Retrieved 2024/11/30.
而HSTS预加载列表是一个由谷歌(郭利帝国分部)维护的,要求更加严格的一种“白名单”,这个列表由各大浏览器厂商维护,一旦某个网站的域名被添加到这个列表中,使用这个列表的浏览器都会在首次访问时强制HTTPS协议。
但是,之所以会成为“白名单”是因为其HSTS预加载的要求非常高:
1、需要开启includeSubDomains,也就是说,其子域名也必须要有部署HTTPS,否则无法访问
2、其HSTS时间必须要大于一年,这一年内你的HTTPS证书部署必须正常(也就是不能过期),一旦异常,直接无法访问站点,用户无法选择忽略警告
3、一旦加入HSTS预加载名单,其地址就会硬编码在最新的浏览器内,那么之后要是想退出名单将会是一件异常痛苦且漫长的操作
当然,为了阻止运营商的劫持,本站也是加入了HST S预加载名单:
那么,运营商封锁的问题解决了……吗?
封锁方法二:DNS投毒
顾名思义,就是运营商的DNS被一股神秘力量解析到了某些邪恶势力搭建的一台与源CDN毫不相干的服务器上,只要用户使用其默认的运营商DNS,即使使用了首次握手443端口的访问,也会遭到劫持
可以看到,上图中第一个地区解析明显异常,与一台郭利帝国境内的主机建立了连接,当时吓得本兽兽跑去查了下CTlog看看是不是连不通流氓运营商通过DNS投毒的方式与郭利帝国的黑CA相互勾结违规签发了证书,不过还好,没有奇奇怪怪的证书被签发o(^▽^)o(trustasia是目前正在用的证书,google trust 和Let's Encrypt 是Cloudflare域名控制台自带的证书,私钥存储在CF的服务器上,连我都不知道)
CTlog又是什么?这得从证书透明开始说起(来自维基百科:
2011年,荷兰的数字证书机构DigiNotar在入侵者利用其基础设施成功创建了超过500个欺诈性数字证书后申请破产。[3]
Ben Laurie和Adam Langley构思了证书透明度,并将其框架实现为开源项目。
证书透明度(英语:Certificate Transparency,简称CT)也称证书透明、证书透明化,是一个实验性的IETF开源标准[1]和开源框架,目的是监测和审计数字证书。透过证书日志、监控和审计系统,证书透明度使网站用户和域名持有者可以识别不当或恶意签发的证书,以及识别数字证书认证机构(CA)的行为。
所以CTlog允许我们查看一个网站的HTTPS证书颁发历史,并快速识别出有没有证书背误签发,那么如何做到DNS不被大面积污染投毒呢?
首先我们要知道DNS被污染的原理:
DNS污染,又称为域名服务器缓存污染(DNS cache pollution)或者域名服务器快照侵害(DNS cache poisoning)。
DNS污染是指一些刻意制造或无意中制造出来的域名服务器分组,把域名指往不正确的IP地址。
一般来说,网站在互联网上一般都有可信赖的域名服务器,但为减免网络上的交通,一般的域名都会把外间的域名服务器数据暂存起来,待下次有其他机器要求解析域名时,可以立即提供服务。一旦有相关网域的局域域名服务器的缓存受到污染,就会把网域内的电脑导引往错误的服务器或服务器的网址。
——https://github.com/hoochanlon/fq-book/blob/master/docs/doub/6t3mypbm-5.md
解决方法:服务端
DNSSEC+CAA解析
DNSSEC是域名系统 (DNS) 的一项功能,用于验证对域名查找的响应。它不会为这些查找提供隐私保护,但会阻止攻击者操控对 DNS 请求的响应或在该响应中投毒。
一个真实的例子,V2EX上V2EX上有一名用户用CF部署了一大堆开源项目在同一个域名的不同端口上,结果惨遭郭利帝国的大面积DNS投毒,结果权威DNS遭投毒连DOH/DOT都不管用了。生动形象地用情深体验证明了开DNSSEC的重要性(乐)
启用DNSSEC能够阻止运营商大面积的甚至向权威DNS解析(如阿里DNS、DNSpod等)对你网站的A/AAA cname解析投毒。
而CAA解析能够防止你不熟悉的黑CA对你网站进行证书签发,配合DNSSEC就能防止运营商签可信证书劫持你的HTTPS连接。
你可以通过https://who.cx/furries.fun 来查看自己的站点是否配置DNSSEC
也可以通过https://dnsviz.net/d/furries.fun/dnssec/ 来查看是否配置正确
![[矛与盾]运营商封锁的原理以及“低成本”解决方案 73 furriesfun 2024 11 23 14 36 02 UTC](https://furries.fun/wp-content/uploads/2024/12/furriesfun-2024-11-23-14_36_02-UTC.png)
来自https://dnsviz.net/d/furries.fun/dnssec/
听上去很好,不是吗?但………事实上,如果运营商使用自签名证书来劫持你的HTTPS流量,浏览器最多会显示警告页面,并没有解决被封锁的问题,毕竟“它不会为这些查找提供隐私保护” 而且DNSSEC 是在递归 DNS 上验证的,当然也可以选择传播到终端设备。如果递归 DNS 服务器开启了验证,那么 DNSSEC 校验不通过,会向终端设备返回 Server Fail 。如果终端设备开启了 DNSSEC 验证,那么会尝试获取递归 DNS 传播的 DNSSEC 记录,获取不到就无法上网。由于很多企业网络的 DNS 选择不传播,所以大多数系统的 DNS 都是默认关闭 DNSSEC 校验的。这样的话,如果运营商要搞你,在自己的递归 DNS 上设置不验证你的 DNSSEC 就可以劫持你的网站了。
那咋办?
客户端:更改DNS服务器,使用DOH/DOT
那就改DNS服务器呗,但网上的修改办法大多是这样:让你打开控制面板-网络与共享中心-本地网络属性-Internet协议版本4属性 然后让你改ipv4的DNS地址……
这种方法早就已经过时了!(恼)#[汗] 由于这样的DNS查询的确更改了查询服务器,但由于DNS的查询协议是纯UDP,是明文!你查了那些网站人家运营商看得明明白白,完全起不到突破封锁和保护隐私的效果,照样会被阻断。
而更加现代的方法是使用DOH查询,因为DOT协议是基于TLS,虽然加密但有明显的特征。而DOH则使用HTTPS,将查询流量混在流量甚广的HTTPS加密协议中,能更好的伪装自己,所以DOH可以算是DOT的迭代版本
各种浏览器使用(DOH/DOH)的教程我就不再多加赘述了,网上随便一搜都有~
https://www.icoa.cn/a/953.html
是的,你加入了HSTS预加载名单开启了DNSSEC,做了CAA解析,也叫用户使用了DOH加密DNS,你的爪爪(?)敲键盘敲得疲惫,然而……它还有办法!这一切并未结束!
封锁方法三:SNI RST
RST包设立的初衷是好的,就是被运营商执行坏了
了解SNI之前,我们需要知道RST包重置攻击(来自维基百科):
![[矛与盾]运营商封锁的原理以及“低成本”解决方案 75 PNG](https://furries.fun/wp-content/uploads/2024/11/PNG.png)
解决方案:服务端
不用SNI,CDN,直接高防VPS建站(不推荐)
不推荐这种方法,因为这样会相当耗费金钱而且过于折腾(因为域名直接绑定在源站)会被黑客扫爆,到时候爆0day漏洞被黑你都不知道为什么.....
启用HTTP\3(QUIC)
随着互联网技术的发展,谷歌开发了一种基于UDP的协议QUIC,并在2018年11月给出了官方批准,认可HTTP-over-QUIC成为HTTP/3。
![[矛与盾]运营商封锁的原理以及“低成本”解决方案 76 0868BEF4 58F1 4807 AE14 FBF8625D72AA](https://furries.fun/wp-content/uploads/2024/12/0868BEF4-58F1-4807-AE14-FBF8625D72AA.webp)
图片来自https://cabulous.medium.com/http-3-quic-and-how-it-works-c5ffdb6735b4
在HTTP\3中,不仅使用了UDP作为底层协议来代替之前的HTTP\2等更老协议的基于TCP的协议,而且实现了首次仅需1次握手就能建立HTTPS连接(0-RTT),不仅加载页面更快(解决了之前HTTP\2的少量的丢包就可能导致整个TCP连接上的所有流被阻塞的拥塞问题)
而且更重要的是基于UDP的协议没有Reset包这样的概念,也就是说基于UDP的协议天然就不受到连接重置包的攻击。(虽然没有加密SNI,对方仍然知道你在访问哪个网站,但不能再通过RST包阻断了)
你可以通过这个小工具来检查站点是否支持HTTP\3: https://http3.wcode.net/ (这个工具是国内检测点,可能会不准确,建议用下面这个)
https://domsignal.com/test/h4pmfht403lz3ivr7vq2lwo51hs33wvf
检测浏览器是否支持HTTP3:https://http3.is (机器人笑了就代表支持)
增加HTTPS解析记录
但这仍然有问题!你不知道浏览器首次连接时使用HTTP\3还是HTTP\2,如果首次握手是HTTP\2那就仍然会存在SNI泄露给中间人的问题!
大多数声称支持HTTP3的浏览器其实都是通过首次HTTP2握手然后再来判断ALPN(Application-Layer Protocol Negotiation)应用层协议头部来判断服务器是否支持HTTP3,刷新后(再一次请求)才会使用HTTP3。
所以浏览器就会遇到一个很棘手的问题:当首次访问一个网站时,还不知道它支不支持 HTTP3,应该发那种包?
- 如果发起 TCP 握手,网站肯定都是支持的,不太可能有网站仅用 HTTP3。但这样第一次访问就无法享受新版的协议。
- 如果发 UDP 包做 QUIC 握手,那么一旦网站不支持 HTTP3,就会白白浪费时间。
来自https://blog.kaciras.com/article/42/speedup-your-site-with-http3-using-nginx-and-dns-svcb
经测试 Firefox 对首次访问的站点仅使用 TCP 握手,其它浏览器也有不同的处理方式:
Chrome 在 HTTP/3 可用时,总是优先使用 HTTP/3 协议,当失败后再回退至 HTTP/2。而 Safari 则是并发尝试使用 HTTP/2 和 HTTP/3,并优先选择最先完成连接建立过程的连接。这可能使得在测试时发现 Safari 经常甚至永不使用 HTTP/3。
(注:safari 并非永不使用HTTP/3,而是要在设置-Safari浏览器-高级-实验性webKit功能中手动开启,当然自IOS16以上该选项就是默认开启了)
要解决这个问题,就得在建立连接之前就获知服务器是否支持 HTTP3,于是 DNS 成为了最好的选择,新的 SVCB 和 HTTPS 记录运营而生。
SVCB 记录能够给一个域名定义多个“服务”,每个“服务”都有一个域名和一组参数,客户端可以通过参数来选择服务,以及提前得知一些信息。
HTTPS 记录属于 SVCB 的一种,专门用于 HTTP,配置都是一样的。
(这也就是为什么ITDOG查不到SVCB解析而DNSSEC又显示有解析的原因)
当然,我也在CF做了HTTPS解析,这是本站的HTTPS解析(来自https://dns.google)
{ "Status": 0 /* NOERROR */, "TC": false, "RD": true, "RA": true, "AD": true, "CD": false, "Question": [ { "name": "furries.fun.", "type": 65 /* HTTPS */ } ], "Answer": [ { "name": "furries.fun.", "type": 65 /* HTTPS */, "TTL": 300, "data": "1 xiaohuangbo233.fur0.com. alpn=h3,h2" } ], "Comment": "Response from 108.162.192.183." }
其中 "data": "1 xiaohuangbo233.fur0.com. alpn=h3,h2"就是最重要的,这申明了furries.fun能查询到一个HTTPS服务,使用了cname拉平,其地址是xiaohuangbo233.fur0.com. ,支持 HTTP3 和 HTTP2,这样配合上DOT/DOH的权威DNS我们就在首次握手时就能用HTTP3了!
所以,运营商的封锁,真的终于结束了吗?…可惜的是,还有高手!
封锁方法四:禁止QUIC包(封UDP)
但网络环境总是复杂的,有些比较逆天的极端的运营商直接封了UDP包的通行!(BT下载震怒!),那,对于难道真的没有办法了吗………
当然不是,办法总比困难多!最后的终极解决方案那!就!是!
客户端:使用域前置(域名幌子)技术
这项技术本来是一般在红蓝网络攻防才会用到的黑科技,本身这项技术就不是什么新鲜技术,但其本身就是为了避免中间人封锁而出现的技术,所以,github上有一个免费开源的小工具叫Accesser
项目地址:https://github.com/URenko/Accesser
(去项目点点star吧~)
Windows 一键工具下载地址:https://github.com/URenko/Accesser/releases/download/v0.10.0/accesser.exe
而Accesser则是开源免费,使用的是域前置技术,原理并不相同,且可以自己定义网站(前提是网站得支持域前置)
你可以把Accesser理解为开源的网络改包工具,而steamcommunity 302则是直接把包转发转发在对应的cloudflare的CDN上来反代网页。
这种技术原理有些复杂我先放图:
葱上面两张图可以看出,域前置原理是
在不同通信层使用不同的域名。在明文的DNS请求和TLS服务器名称指示(SNI)中使用无害的域名来初始化连接、公布给审查者,而实际要连接的“敏感”域名仅在建立加密的HTTPS连接后发出,使其不以明文暴露给网络审查者。[5][6][7]
这种举动在被封锁的站点与无害站点为同一个大型服务提供商时较为可行,例如由内容分发网络提供的服务。[5][6][7]此时审查者通常很难区分被伪装流量与合法流量的特点,迫使审查者选择放行所有看似无害的流量,或者选择彻底封锁此域的流量。而彻底封锁可能带来显著的附加损害。[8][9]
(来自维基百科)
简单来讲,域前置就是一个允许客户端“偷”同一个CDN上其它的域名,让中间人认为你在访问另一个网站。实际上你访问了被封的站点。
就连“汁冥”开源搬运工classmate·thief·何也如此评价道:
(偷别人域名的感觉)不觉得很酷吗?作为一名理工男我觉得这太酷了,很符合我对理工MJJ的想象,科技并带着趣味~[斜眼笑]
使用方法
拿Accesser的Windows 一键工具来演示如何添加网站,拿我的站点furries.fun举例如何添加自定义站点
当然如果你是高贵的Linux用户,也可以通过Python3.10以上的运行环境来部署Accesser
详情参见:利用域前置技术绕过GFW的SNI阻断 | Enjoy your life | AEnjoy’s Blog
https://www.iotroom.top/2023/11/11/%E5%88%A9%E7%94%A8%E5%9F%9F%E5%89%8D%E7%BD%AE%E6%8A%80%E6%9C%AF%E7%BB%95%E8%BF%87GFW%E7%9A%84SNI%E9%98%BB%E6%96%AD/
先下载exe文件和github项目中的accesser的pac文件(不要有.txt后缀,无文件后缀的pac文件)
把它两个文件放在一个英文文件夹下,再运行Accesser.exe
此时会提示添加根证书,点击“是”(python 开源程序,代码很简单,你可以自己去看不用担心安全性)
启动一次程序厚会在 工作目录 下生成config.toml
和 rules.toml
接着在浏览器访问一下http://v2ex.com/ 或者 https://wikipedia.org 应该就能够正常访问了!
添加自定义站点的方法
以本站为例
先用ITDOG.cn扫一下网站CDN的IP
![[矛与盾]运营商封锁的原理以及“低成本”解决方案 82 PNG](https://furries.fun/wp-content/uploads/2024/12/PNG.png)
解析记录
拿到103.115.42.108这个IP地址,然后用IP反查网站,看看有哪些网站绑定在了同一个CDN上
这里为了方便,就拿mwm.moe举个例子吧[斜眼笑]
(当然,你也可以自行搭建一个英文伪装站点,挂在同一个CDN上,效果也是一样的)
用记事本或者VSCODE编辑PAC文件在 var domains = { 函数中插入
"furries.fun":1,
然后在rules.toml
文件中找到第37行看到一下描述并插入
[alter_hostname] # 与键对应的域名的TLS连接会使用其值对应的域名作为server_name字段,并且校验证书时也使用这一域名。键支持Unix shell风格的通配符。 # A TLS connection to the domain corresponding to the key will use the domain name corresponding to its value as the server_name field, and this domain name is also used when verifying the certificate. The key supports Unix shell-style wildcards. ... "furries.fun" = "mwm.moe" ....
当然如果在HTTP协议头部找不到CDN服务器的主机名,那就说明CDN服务商把它隐藏了(例如cloudflare),那就代表着当前网站使用的CDN不支持域前置,需要使用其它方法。
(当然,还有些CDN支持无主机名就能建立连接,这要看CDN服务商是怎么设置的,所以可以先试一下不填HOSTNAME看看能不能访问,如直接关闭连接就说明必须提供主机名)
然后在72行找到一下代码,并插入:
[hosts] # 自定义 域名-IP 映射,即用于与网站建立连接,也用于与DNS服务器建立连接。 # Customize domain-IP mapping, which is used to establish a connection with the website and the DNS server. # example for DNS server bootstrap address "dot.sb" = "185.222.222.222" # "dns.adguard-dns.com" = "94.140.14.14" ... "furries.fun" = "mwm.moe" ...
这代表你表面上向DNS服务器请求了mwm.moe网站,找到的mwm.moe的IP,mwm.moe也向你发送了其mwm.moe的证书,但实际上你在浏览器输入的是furries.fun,于是accesser手动将mwm.moe的证书替换成自己的自签名证书,建立TLS连接后浏览器请求的是furries.fun的网页页面。对于中间人而言你访问的是mwm.moe,其SNI也是mwm.moe,但实际上建立TLS加密连接后你要的是furries.fun页面。
你可以把客户端与服务器的握手过程理解为这样:
普通情况下
客户端(浏览器/用户手动输入网址furries.fun):DNS服务器,我想查询一下furries.fun网站的IP地址
DNS服务器(运营商):好的,furries.fun的IP地址解析到了0.0.0.0
客户端:跳转到0.0.0.0,唉?这是个保留地址。无法连接至服务器,显示错误页面给用户
使用DOH后
客户端(浏览器/用户手动输入网址furries.fun):DNS服务器,我想查询一下furries.fun网站的IP地址
DNS权威服务器(DOH经过加密):好的,furries.fun的地址解析到了103.115.42.108
客户端:跳转到103.115.42.108,你好103.115.42.108,我注意到你在HSTS预加载名单上,故首次连接使用HTTPS,请发送furries.fun的证书公钥
CDN:好的,这是furries.fun的证书公钥,支持的加密套件等信息,请给我你的握手密钥和通信密钥
(此时中间人:唉?服务器证书是furries.fun,在黑名单上,向客户端抢答发送RST包阻断连接)
客户端:我收到了RST包,按照TCP草案规定我得清空内存并重置连接了(显示错误页面)
CDN:客户端,你在吗?
CDN:客户端,你在吗?
CDN:客户端,你在吗?
(连接中止)
而使用域前置后:
客户端(浏览器/用户手动输入网址furries.fun)
Accesser:将用户的DNS查询改为mwm.moe
客户端:DNS服务器,我想查询一下mwm.moe网站的IP地址
DNS权威服务器(DOH经过加密):好的,mwm.moe的地址解析到了103.115.42.108
跳转到103.115.42.108,你好103.115.42.108,我需要furries.fun的证书公钥
Accesser:将用户的证书请求改为mwm.moe
CDN:好的,这是mwm.moe的证书公钥,支持的加密套件等信息,请给我你的握手密钥和通信密钥
中间人:证书是mwm.moe允许通过
Accesser:将服务器(CDN)的证书改为用户手动信任的自签名证书
......
由此建立了TLS连接
客户端:请给我furries.fun的页面
CDN:好的,这就把网站页面数据传给你
(成功建立连接)
方法2:使用Sheas Cealer实现域前置
Sheas Cealer是一款带GUI的,开源的域前置工具,相较于无GUI的难用Accesser,Sheas Cealer的页面更友好,操作也更为简单,也不需要手动添加根证书,这使得域前置使用的操作门槛大大降低。
项目开源地址:https://github.com/SpaceTimee/Sheas-Cealer
下载地址:
- Github (首选): https://github.com/SpaceTimee/Sheas-Cealer/releases
- 蓝奏云 (密码 3wnj) (大陆推荐): https://spacetime.lanzouu.com/b017hp0lc
与Accesser不同的是,它基于 WPF(.Net8) ,是通过在Chromium浏览器修改启动参数来实现SNI伪装的,不需要添加根证书,也不需要设置本地代理。
添加自定义网站(以本站为例):
1,打开软件,按照提示安装运行库windowsdesktop-runtime-8.0.11-win-x64
2,再更新上游规则
2,你会发现文件夹内出现了一个Cealing-Host-U.json文件,用记事本编辑它,插入一下内容:
[["*furries.fun"],"","148.135.83.218"],
当然你也可以填写
[["*furries.fun"],"null","148.135.83.218"],
来自:https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Documentation
3,保存后选择你的浏览器桌面上的快捷方式
4,最后点击启用伪造,打开浏览器,访问https://furries.fun/
大功告成!
服务端:使用自建CDN支持无SNI和随机SNI
为了方便访客,当然不能让访客来从HTTP协议头来猜测severname,这样很显然过于麻烦,如果服务端能弃用SNI,直接发送默认证书那就更好了(要知道能方便用户就方便用户,麻不麻烦站长无所谓,毕竟都走技术建站这种方式了就得做好折腾的准备[斜眼笑])
但服务端弃用SNI的代价就是每个IP的443端口只能有一个网站所以你得自己搭建CDN。
当然,自建CDN需要花费一定的精力和金钱,而且因为要用到一些高级功能来,所以你还不能简单搭一个CDN凑合。
我的推荐是用Goedge CDN1.3.9开心版(分遗产版本)来搭建自建CDN
⚠️ 经过部分群友反馈,GoEdge 官网发布的最新版本很可能存在数据上报能力
大致影响范围: v1.4.x 系列
本频(独家)整理的屏蔽域名列表,建议在 edge-admin 主控服务器、边缘节点(可选)上屏蔽:
🔄 屏蔽更新:
- goedge.cloud
- goedge.cn
🚫 屏蔽下载:
- dl.goedge.cloud
- cn.dl.goedge.cloud
- global.dl.goedge.cloud
- dl.goedge.cn
- global.dl.goedge.cn
- cn.dl.goedge.cn
⚠️ 屏蔽(可能)的授权上报域名:
- authority.goedge.cn
- 38b48e4f.goedge.cn
- authority.goedge.cloud
- 38b48e4f.goedge.cloud
🔰 本频不排除后续的更新的上报方式更换为 *.goedge.cloud | *.goedge.cn 随机子域名。
甚至有可能会更新 DNS over TLS/HTTPS/QUIC 甚至内置硬编码 IP 的方式解决 hosts 屏蔽方式。
原因如下:GoEdge 接手团队目前仍在更新 GoEdge,但是仔细研究更新日志会发现 v1.3.9 以后的版本更新都没有重要的特性推出,因此不推荐各位对于版本追新。
而屏蔽上报域名治标不治本,对新版分析浪费时间。
♾ 而本频的对应策略如下:
1. 对小版本更新采取简单的 patch 和注册机方法。
2. 之后推出 漏洞修复、架构重构等重要更新 再详细解包分析代码。
3. 在此之前,请回到 v1.3.9 历史版本。
❗ 生产环境不要手贱更新版本,可以去管理面板的设置中关闭版本检查。
关闭版本页面: https://<管理面板>/settings/updates
UI 操作指引:管理面板-系统设置-基础设置-检查更新-取消勾选 自动检查
至于为什么是“分遗产”,那就不得不提到那次臭名昭著的供应链投毒了,前段时间爆出其已被原作者超哥转让给方能系(黑产),且在其边缘节点程序最新版本v1.4.1中投毒。
吃瓜链接:Goedge投毒事件
https://www.nodeseek.com/post-138160-1
话说回正题,我们安装好goedge1.3.9开心版之后(懒人脚本:https://www.70ol.com/ziyuan/211.html)在管理员面板-边缘节点-设置-网站设置中关闭禁止未绑定域名访问-然后点击其他-打开自动匹配证书
这时你的网站就支持空SNI访问了!
域前置的缺陷
当然,域前置很强大,但也有自己的缺陷,其中一个显然是你必须“偷”相同CDN上的域名伪装来访问自己的域名,这对CDN有一定的“伤害”(可能会导致进IP黑名单,被封端口甚至无法PING通CDN的IP),而且CDN服务商也是不希望看到自己的CDN上有用户用这个技术,所以不是所有的CDN都支持域前置。打个比方,就拿赛博佛祖cloudflare来说吧,由于之前可能由于某郭利帝国的邻国的压迫,Cloudflare早在2016年的一些修改让基于其CDN的域前置不再工作。(来源:https://geekdaxue.co/read/jianouzuihuai@study/domainfronting ),具体表现为CDN要求客户端提供sever_name,而HTTP协议头部又隐藏了severname,所以域前置工具无法提供服务器名称,CF的CDN不知道你真正想要访问同IP上的哪个网页,所以只能关闭连接。
还有以下情况无法使用域前置:
- 所有 网站可接受的 SNI拓展 均被 SNI阻断 的网站 (主要障碍)
- 所有 网站可用的 ip地址 均被 ip封锁 的网站 (目前极少出现)
Cloudflare网站IP优选?不推荐!
Cloudflare 已明文禁止搭建VPN和代理服务,禁止优选IP
Cloudflare 已于2024年12月月初修改了其服务条款,根据新的协议,用户使用其服务提供虚拟专用网络(VPN)或其他类似的代理服务将被视为违规。
Cloudflare 早些时候已禁止用户将 Cloudflare 代理域名的流量发送给非 Cloudflare 分配的IP地址。该规定直接影响“IP优选”工具的使用,一些用户会使用此类工具绕过CF的正常流量分配机制,以获得更好的网络访问性能。但它显然会破坏 CF 网络节点的分配策略。
——来自VPS信号旗播报
这就意味着如果你网站用了CF优选,那么被打之后CF可以直接停止优选节点转发你源站的流量,这就意味着你网站不抗D了,因为你违反了CF的用户协议,而且还有一种玩法通过长期刷你优选网站的流量再向CF举报,那么CF就会停止自动续签你网站的SSL证书。
对于代理优选而言,vless-cdn-tls死了就用XTTP或者VMESS继续浪,SSL证书过期了就客户端开允许不安全继续用。但网站CF优选就很伤了,因为代理是你在暗处GFW在明处,但网站就是你网站套CF优选违反用户协议在明处,D佬在暗处了。而CF网站不开优选那么郭利帝国境内访问体验就是依托史。所以说在5202年网站又想不备案不花钱还想有一个良好的访问体验是很困难的。
IPV6,YES!
当然事实上,网站若是支持IPv6来访问,那就能一定程度上缓解来自运营商的封锁,因为IPv4和IPv6硬件上不同,数据所走的线路也不同,那也就意味着IPv4封了但IPv6不一定会被封,所以CDN支持IPv6访问是极好的~(当然源站可以支持也可以不支持,毕竟不与用户客户端直接连接)
(主要是数据走的线路IPv6和IPv4会不一样,速度或许更快)
展望未来:ECH
ECH全称是Encrypted Client Hello,通过加密整个Client Hello来保障隐私,其前身就是ESNI,但由于该技术很新,大部分浏览器还在实验性支持阶段,而且还需要服务端的支持,你可以看看CF的这篇文章,详细讲述了ECH的原理:
https://blog.cloudflare.com/zh-cn/announcing-encrypted-client-hello/
由于目前ECH仍然处于草案阶段,所以你可以图省事用cloudflare woekers做个网站反代来直接支持ECH,项目地址:https://github.com/ymyuuu/Cloudflare-Workers-Proxy
当然你也可以自建一个同时支持ECH+HTTP3/QUIC的nginx服务端,但这可就相当麻烦了,同时得让自建的CDN都同时支持ECH和HTTP3,那工程量可就蛮大的,得手动配置,这里只给出关于如何搭建nginx支持ECH服务端的教程:https://kabe.dev/nginx-ech-test/
客户端
最新的Firefox浏览器已经默认启用了ECH了,只需要设置好DOH即可。https://support.mozilla.org/zh-CN/kb/faq-encrypted-client-hello#w_ru-he-zai-firefox-qi-yong-ech
Chrome浏览器
在地址栏输入 chrome://flags/#encrypted-client-hello
,将 Encrypted ClientHello
选项设置为 Enable
并重启浏览器即可。
建议同时启用 Use DNS https alpn
。
压缩网页减少加载时间
乍一看这或许和网页优化有关,其实,这也和反运营商封锁有关,郭利帝国有些逆天网络环境凡是境外的流量长连接UDP会被QOS限速,TCP则会直接收到RST包。,甚至直接100%丢包阻断。所以要防止连接时间过长,就要压缩页面,使用gzip,br等压缩算法,并减轻页面文件大小,适当删减一些元素,虽然以美观为代价,但总比长连接被阻断好。
服务端可以设置超时时间,时间一般不超过4~5分钟。
结论
服务端
- 开启DNSSEC防止域名被污染
- 使用HSTS并加入预加载名单防止80端口跳转劫持
- 添加CAA解析,设置证书颁发机构白名单
- 时常看看CTlog看看有没有异常的证书签发行为
- TLS协议不得低于TLS1.1(最好HTTPS监测评级为A+)
- 支持HTTP/3(QUIC)协议,防止RST连接重置攻击
- 做好DNS的HTTPS记录,申明站点支持HTTP2和HTTP3,不要让浏览器首次连接去猜
- 自建CDN,对域前置有一个良好的支持(支持随机SNI访问)
- 支持IPv6/IPv4访问
- 整一个镜像CF反代镜像站点,以便支持ECH
- 使用压缩协议,调整超时时间,避免建立长连接
客户端
- 使用最新的浏览器
- 使用DOH来作为DNS查询
- 必要时可以使用例如Sheas Cealer这样的域前置工具,彻底解决封锁问题
拓展阅读
https://tessieboat.github.io/post/guan-yu-vpnfan-qiang-de-xiang-xi-jiao-cheng/
来自莱茜
https://overthefirewall.zgqinc.gq/
来自zgqinc
https://www.silverdragon.cn/archives/7484/
来自道锋潜鳞的CF网站优选教程(折腾,不要在生产环境中使用)
本文作者为xiaohuangbo,转载请注明。
cloudflare pages 是不是默认被烦人老妈封锁了?
@敖律风没有被封,很多网站比如咱的一个友链https://cynosura.one/ 就是用的cloudflare pages
@xiaohuangbo只不过特殊时期访问速度极慢甚至连通性很差就是了(如果不定期IP优选的话)