2
Turun
3
mengumpul
Lapor
berkongsi
301海外跳转原理解析兼谈缓解假墙伪墙攻击勒索的多种技术手段二转载
Fail boleh laku yang disebut dalam artikel ini mungkin memerlukan pemalam emulator ons untuk dijalankan pada peranti mudah alih (Android, iOS, HarmonyOS, dll.) atau platform lain. Jika perlu, sila muat turun pemalam atau ciri yang diperlukan dari program mini Plugin Biasa dalam aplikasi VikACG.
在上一篇文章中,我们实现了HTTP的抢答模式,避免了墙的TCP Reset。那么这次我们就来聊一聊HTTPS如何避免被TCP Reset。 我们知道,HTTPS是需要客户端和服务器之间完成TLS握手后才能收发HTTP Request和Response。然而,墙是在TLS握手时通过SNI中的域名信息进行了TCP Reset,或通过ESNI头进行TCP阻断,这时候还没有到能发送HTTP Request或Response的这个阶段,所以HTTP Response抢答模式无法应用于HTTPS。那么,我们该怎么办呢? 让我们回到TCP Reset本身——既然是TCP Reset,那么它只会对TCP协议生效。如果有一个应用层协议,其底层不是TCP呢?相信聪明的同学已经想到了,那就是HTTP 3.0(简称HTTP/3或h3)。H3的底层协议是QUIC,而QUIC是基于UDP而非TCP的。经过我的测试,发现墙现在无法识别QUIC协议,不管QUIC协议中出现任何敏感词都能无障碍过墙。这也是为什么有些网站(如v2ex)在解决了DNS污染(比如客户端主动加hosts)后,并且连接过一次(首次还是需要科学上网,原因之后会讲)后,就能关闭科学上网访问了。也就是说,使用了H3后,我们甚至不需要进行301跳转,直接就能无障碍访问服务器了(但仍建议使用301跳转,否则可能会使封锁升级,如DNS污染)。虽然H3现在仍旧处于草案阶段,但各大浏览器都已经进行了支持,而其中Google Chrome对H3的支持是最好的。 那么,如何在服务器上部署并开启H3呢?由于H3现在仍是草案阶段,所以Nginx的正式版并不支持H3,需要更换为Nginx-QUIC来支持H3。编译使用Nginx-QUIC也可以参考这篇文章。另外,Cloudflare也已经支持了H3,可以自行开启(在“网络”设置中打开“HTTP/3(使用 QUIC)”)。在Cloudflare中开启H3后,Cloudflare和服务器的通讯仍旧可以使用HTTP/2(简称h2)或HTTP/1.1,并不需要服务器支持H3,而是由Cloudflare进行协议转换。 H3主要是依赖
Alt-Svc这个HTTP头来进行协议选则的。比如我们可以添加HTTP头: Alt-Svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400,指出服务器支持H3,H3的UDP端口为443,有效期(过了有效期后浏览器又会重新使用H2或HTTP/1.1进行访问)为1天(86400秒),支持最新的H3草案以及27、28、29草案。另外,我们也可以灵活地修改Alt-Svc——比如可以在“:443”之前添加IP或域名,做到HTTP和HTTPS使用不用的IP或域名,方便我们在自己的服务器上部署HTTP抢答模式,又能使用Cloudflare的H3协议转换,或者使用不同的域名从而在原域名被DNS污染的情况下老用户(没有过有效期86400秒的)依然可以通过H3访问服务器(因为H3是另一个域名,而不是被DNS污染的那个域名。或者直接使用IP,从根本上杜绝了DNS污染,只不过之后有可能遭到IP封锁)。另外,有效时间也可以进行适当延长(比如从1天延长到1个月或更长时间),避免客户端尝试H2或HTTP/1.1并且延长老用户的过期时间。我们可以在还没遇到HTTPS的TCP Reset时就开启H3,这样即使之后遭遇了HTTPS的TCP Reset,曾经访问过网站的老用户在H3有效期内也能继续访问网站。而且我们也不必担心UDP数据包被ISP丢弃(俗称UDP被QoS)的问题,因为浏览器在H3连接失败的时候会快速回退到H2和HTTP/1.1。
然而,H3是一个Alternative服务。首次访问服务器时,浏览器并不会主动使用H3,还是会优先使用H2或HTTP/1.1。当获取到Alt-Svc头后,浏览器才会在之后的访问中优先使用H3。这也是为什么有些网站(如v2ex)需要在科学上网的情况下访问过一次后才能关闭科学上网进行访问(当然,DNS污染首先还是需要用户自行修改hosts解决)。那么,我们如何让用户全程不使用科学上网的情况下访问服务器呢?
首先想到的是通过上一篇文章中的HTTP抢答模式提供Alt-Svc头,不过可惜的是现在的主流浏览器会忽略HTTP中的Alt-Svc头,只接受HTTPS中的Alt-Svc头。而如果HTTPS本来就已经被TCP Reset的话,浏览器就无法获取Alt-Svc头了。那么,那些提供HTTPS的301海外跳转服务是怎么做的呢?
在调查和尝试了几个支持HTTPS的301海外跳转服务后,我们发现,它们根本就没有解决HTTPS的TCP Reset问题,HTTPS依然被TCP Reset了,而它们宣称支持HTTPS中301跳转的做法就是在HTTP抢答模式下加上普通的TLS服务。因为大部分网站遭遇的只是HTTP中的TCP Reset而HTTPS并不会被TCP Reset,所以只需要解决HTTP的301跳转,再加上普通的HTTPS,表面上就能同时做到HTTP和HTTPS的301跳转。而且在调查过程中我们还发现有个跳转服务主页的HTTPS也被TCP Reset了,而他们自己却对此毫无办法。那么,对于新用户访问HTTPS的TCP Reset,我们也只能止步于此,束手无策了吗?那也未必。
其实,从本系列一开始,我们就假设301跳转服务器是在国外。如果使用的是国内服务器,那么就能避免墙的识别了(因为不过墙)。但使用国内服务器(似乎)有个绕不过去的坎:备案系统——使用HTTP会提示域名没有备案,使用默认端口443的HTTPS同样会有TCP Reset。我们又该怎么办?其实,备案系统其实就是一个简化版的墙,没有TCP流量重组的功能,使用上一篇文章的抢答模式同样也能绕过备案系统。而且正是因为备案系统没有TCP流量重组的功能,我们甚至可以在TCP模式的HTTP和HTTPS中设置TCP window size(比如Linux上可以使用Geneva;Windows上可以自行编写一个反向代理,在其中设置SO_RCVBUF为1,两者的用法在上一篇文章中都已进行说明,在此不再重复),从而可以直接通过HTTP和HTTPS绕过备案系统而无需使用301跳转(因为备案系统没有TCP流量重组功能,所以只需要在连接初始时设置个较小的TCP window size,之后恢复正常即可。这也是很多国内免备案服务器的原理和使用的方案)。不过,绕过备案系统展示网页有一定的风险,301跳转风险会小一些,希望大家还是要权衡好利弊。
在讨论好HTTPS中防TCP Reset的方案后,最后让我们来聊一聊DNS污染。
其实,在撰写本文之前,我曾去尝试过几个声称可以解决域名污染的301海外跳转的服务,但无一例外都失败了,都无法解决DNS污染。然后我也去咨询了提供了这些服务的人,他们的说法大致分为两种:
1、需要将被DNS污染的域名的NS记录指向国内的DNS服务(如DNSPod、阿里云等),然后需要等一段时间,运气好的话过一段时间就会解封了(对于这种说法,我也曾经亲自验证过,将一个被DNS污染的域名的NS记录转移回国内,等了几个月,依然被污染)。
2、域名污染指的是域名被关键字Reset,而不是DNS污染(这个说法和大多数人理解的不同,将域名污染解释为了TCP Reset,和DNS污染分为了两个概念),他的服务只能解决域名污染,不能解决DNS污染。
那么,对于DNS污染,我们只能束手无策,或只能碰运气转移回国内了吗?那也未必。不过,由于解决DNS污染所需要的成本较高,所以这也是为什么之前H3虽然能让用户在原有域名下继续访问,我仍旧建议使用301跳转的原因。否则封锁升级为DNS污染后连301跳转都会变得比较困难了。
讲到这里,细心的同学应该已经发现,其实在刚才H3的使用方法中,已经介绍了如何使老用户在DNS污染的情况下继续进行访问的方法了。这是解决DNS污染部分问题的方法之一。那么,还有没有别的方法也能解决部分问题呢?其实,在H3的方案中,我们主要利用了浏览器的Cache中记录了H3的服务信息,来让老用户通过不同的域名或IP进行访问的。那么,浏览器的Cache中除了能保存H3的信息外,也是可以保存其他内容的。讲到这里,聪明的同学应该已经想到了。没错,就是Cache-Control(或使用Expires也有相同的效果)。通过这个HTTP头,我们可以将一个页面的过期时间设置成很长,在过期之前,浏览器并不会发起HTTP请求,甚至没有网络的离线情况下都能访问(使用F5刷新除外,这时候浏览器会忽略过期时间从而发起HTTP请求;Ctrl+F5更是会发起请求)。在这个页面中,我们可以引用别的域名下的JavaScript脚本文件,在JavaScript而非HTML中渲染整个网页。这样,老用户同样可以在DNS污染的情况下继续访问我们的服务器。不过,这种做法对SEO不是很友好,但我们可以使用HTML和JavaScript同时渲染的方法让搜索引擎可以进行索引——HTML中仍旧是正常内容给搜索引擎进行索引,而浏览器会加载JavaScript,使用JavaScript重新渲染一遍网页,避免Cache没有过期而呈现老页面的问题。老用户的问题可以解决,但新用户怎么办呢?或者我们有没有办法从根本上来解决DNS污染呢?而且听说现在有一些价格昂贵的污染清洗服务,它们真的能从根本上解决DNS污染吗?它们是怎么做的呢?
如果我们想从根本上解决问题,首先我们还需要了解整个DNS系统是怎么工作的:
1、DNS服务器分为递归查询服务器、DNS代理和权威服务器(称为ADNS)。我们把递归查询服务器和DNS代理统称为LDNS。
2、普通用户上网所使用的一般是ISP提供的LDNS,它会负责向ADNS查询真实的A(和AAAA以及其它)记录。
3、ADNS即是域名的NS记录所指向的服务器。
我们知道,DNS污染是墙在海外ADNS返回正确的结果之前进行了抢答,返回了错误的结果。这样,在国内LDNS向海外ADNS查询的时候,同样会受到DNS污染,从而返回给普通用户错误的结果。那么,我们有没有办法劫持ISP的LDNS,从而让其返回我们想要的IP而不是墙返回的错误IP呢?这样,虽然DNS污染仍旧存在,但普通用户却得到了正确的IP,从而可以正常访问我们的服务器了。
讲到这里,就不得不提到2008年曾经轰动全球的DNS投毒攻击案了。在这篇文章中,Kaminsky可以修改任意LDNS中缓存的A(或AAAA以及其它)记录,虽然在经过了那次事件后这个漏洞更难被利用了,但终究无法完全修复,我们仍旧可以利用其中的原理劫持ISP的LDNS(能猜中源端口和QID就能进行劫持),将被污染域名的IP换成自己想要的IP。而且由于墙污染的TTL较小,我们也能更快地利用这个漏洞而不需要每次等待1天的时间。所以短则几天,慢则几个星期就能劫持成功。这也是现在有些价格不菲的污染清洗服务所采用的方案之一。当然,某些攻击团队也同样在利用这个漏洞就行DNS劫持,虽然导致的结果是LDNS被劫持而非墙的DNS污染,但对于普通用户所造成的结果是一致的——网站无法访问。不过,要实施这种DNS劫持需要源IP欺骗,现在能进行源IP欺骗的服务器已经越来越少了。那么我们还有没有别的方法无需源IP欺骗来劫持LDNS呢?
既然大家已经看了上面的这篇文章,那么让我们来重新细致地梳理一下整个DNS查询过程。以浏览器访问 Pautan Web(www.youtube.com) 为例:
1、操作系统向ISP的LDNS发起请求 www.youtube.com 的A(以及AAAA)记录。
2、LDNS查询缓存中有没有 www.youtube.com 的A(或AAAA)记录,如有则返回给客户端,如没有则执行第3条。
3、LDNS查询(可从缓存中查询)DNS根服务器(当前为13个)的A(或AAAA)记录。
4、LDNS向根服务器(或从缓存中)查询 .com 的ADNS。
5、LDNS向 .com 的ADNS发起查询 youtube.com 的ADNS(即 youtube.com 的NS记录)。
6、LDNS向 youtube.com 的ADNS发起查询 www.youtube.com 的A(或AAAA)记录。之后返回给客户端。
我们知道, youtube.com 是个被DNS污染的域名,所以第5和第6步会受到墙的DNS污染,而前4步不会。第6步我们也很熟悉了,国内IP向国外IP发起查询请求时墙就会抢答 www.youtube.com 的错误A(或AAAA)记录。而第5步中,由于LDNS在国内,查询到 youtube.com 的NS记录同样会受到污染。我们同样知道,墙的DNS污染虽然成功概率接近100%,但仍有很小的概率会污染失败。那么我们能不能不停地向LDNS请求 www.youtube.com 的A(或AAAA)记录,在墙污染失败的时候,LDNS就能刷新到正确的IP地址了呢?可惜的是,LDNS是有缓存的,在缓存有效期内,不会再次向ADNS发起请求。即使在缓存失效后偶尔会由于污染失败得到了正确的IP地址,但在缓存再次失效后由于污染再次回到了错误的IP地址。所以被污染的概率仍旧接近100%。墙看上去似乎无懈可击,我们该怎么办呢?
让我们重新回到第5条,使用国内IP向 .com 的ADNS请求 youtube.com 的NS记录。以Linux为例:
dig ns youtube.com @e.gtld-servers.net (e.gtld-servers.net为 .com 的其中一个ADNS)
我们看到墙返回了污染的结果, youtube.com 被污染的NS是……咦?不对!墙竟然返回的是A(或AAAA)记录,而不是我们查询的NS记录!而且墙的污染是有很小的概率会失败的!相信聪明的同学已经想到了——由于墙返回的是不是NS记录,所以LDNS没有获取到 youtube.com 的NS记录,自然无法将 youtube.com 的NS记录存入缓存中。所以,在下次客户端请求 youtube.com 的NS记录时,LDNS会再次向 .com 的ADNS请求 youtube.com 的NS记录而不是从缓存中获取。既然不存在缓存,我们就能一直向LDNS发起请求,而LDNS就会一直向ADNS发起请求,直到墙的污染失败出现,LDNS终于获得了正确的NS记录。而由于NS记录本身是带有TTL的,所以会被存入LDNS的缓存之中,在缓存过期之前不会再受到墙的污染。而我们可以将NS记录的TTL设置得非常长,从而可以在很长得时间内让墙得污染无法生效。而在TTL过期之后,我们可以利用同样的方法再次让LDNS获得正确的NS记录。
在解决了第5条中的污染后,我们还需要解决第6条中的污染。而第6条中墙返回的确实是查询的A(或AAAA)记录,会被存入LDNS缓存,也就无法利用上述方法了。我们该怎么办呢?相信聪明的同学也已经想到了。没错,就是将NS记录转移回国内,这样DNS请求就不会过墙,自然就不会受到污染了。可是,不对呀?刚才不是讲过我也曾经亲自验证过,将一个被DNS污染的域名的NS记录转移回国内,等了几个月,依然被污染么?那是因为之前的测试只是将NS记录指向了国内服务器,我们并没有大量地发送NS查询请求到LDNS,所以LDNS并没有获得正确的NS记录,所以污染仍旧存在。而且,ISP的LDNS是分运营商并且分区域的。只将一个LDNS中的NS刷新到正确结果只能解决一个运营商的一小片区域中的污染,如果想要在全国范围内解决污染,需要使用大量的IP地址(因为很多ISP的LDNS限制了查询请求的发起IP只能是本地宽带用户),不停地对大量的LDNS查询NS记录,直到全国大部分地区的LDNS都获取到了正确的NS记录,才能在大范围内解决DNS污染。而且即使LDNS获取到了正确的NS记录,查询仍然要继续,因为缓存是有过期时间的。而这,也是现在很多昂贵的污染清洗服务所采用的方案之一。
关于DNS污染,作者所了解到的现阶段有这些方案。如果你有别的方法,或者对本系列话题感兴趣的,都欢迎和作者联系。作者的联系方式为:
1、Email: lehui99#gmail.com
2、Twitter: @davidsky2012
3、TG: 技术交流群、技术交流频道
4、本系列Github: lehui99/articles
下一篇作者会开始讲解如何缓解假墙伪墙攻击方面的话题,敬请期待。
*原文地址 articles/301海外跳转原理解析兼谈缓解假墙伪墙攻击勒索的多种技术手段(二).md at main · lehui99/articles · GitHubPengisytiharanSemua artikel di laman web ini, melainkan dinyatakan atau ditandakan sebaliknya, adalah penerbitan asal laman web ini. Mana-mana individu atau organisasi dilarang menyalin, mencuri, mengumpul, atau menerbitkan kandungan laman web ini ke mana-mana laman web, buku, atau platform media lain tanpa kebenaran daripada UP master. Jika kandungan laman web ini melanggar hak dan kepentingan sah pengarang asal, sila hubungi kami untuk pemprosesan: Laporan DMCA
Ikuti Kami













Lelaki ini nampaknya sangat pemalu (Bushi
可是我腦子拒絕了
Lelaki ini nampaknya sangat pemalu (Bushi
维咔编辑部审核专员