-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在启用TCP Timestamp(TCP时间戳)后,GFW对obfs4的审查无效 #442
Comments
呃 |
我上午太兴奋了所以写下了不少错误,现在重写了(扶额)。 |
在2024年5月我用比较严谨的实验证明 河南固定宽带网络之所以开了tcp timestamps情况会跟没开有所不同,并不是省墙能力不足,而是河南的省墙在固定宽带网络上故意放过了 tcp header length不等于5的数据包。 而出口GFW并没有这个关于tcp timestamps或tcp header length的豁免规则。至于封禁obfs4网桥应该是出口GFW的工作/任务才对。 |
Hi @5e2t, your observation and conclusion align with our experimental findings on the Henan Firewall. Below is an excerpt from our unpublished documentation: TCP header length has to be 20 bytes. The four most significant bits of the 13th byte of the TCP header represent the TCP Data Offset, which specifies the length of the TCP header in 32-bit words. The minimum value of the TCP Data Offset field is 5 words (20 bytes) when no TCP options are present, and the maximum value is 15 words (60 bytes). We found that the Henan Firewall required the TCP header length to be exactly 20 bytes to correctly parse and block the TLS ClientHello or HTTP request messages. We tested this by sending forbidden messages (e.g. TLS ClientHello messages with a forbidden SNI 011.com) from our vantage point in Henan to our sink server in Guangzhou on October 17, 2024, with different TCP options set in their TCP headers. While varying the TCP header length, we made sure that the TCP options is always a multiple of 4 bytes to comply with the 32-bit word alignment requirement of TCP header. The TCP options we tested include common TCP ones like Maximum Segment Size (MSS), Window Scale, Timestamps, Selective Acknowledgment Permitted (SAckOk), No Option (NOP), End of Option List (EOL), as well as self-defined TCP options that are not commonly used. We found that as long as any TCP option was set, the Henan Firewall did not block the connection. A possible explanation for this strange behavior is that the Henan Firewall does not parse the TCP header length field in the TCP header, and falsely assumes that the TCP header length is always 20 bytes. This way, when a TCP header has more than 20 bytes due to TCP options, it will treat the TCP options as part of the TCP payload and will thus fail to recognize a complete TLS ClientHello or HTTP request message. However, we falsified this hypothesis and confirmed the Henan Firewall did parse the TCP header length field. In particular, we sent TLS ClientHello messages with a forbidden SNI 011.com with no TCP option set in its TCP header, confirming that this message was blocked by the Henan Firewall. If the Henan Firewall does not parse the TCP header length field in the TCP header, then regardless of the TCP header length value we put in the TCP header, this message should be blocked. We changed the 4-bit TCP header length field in the TCP header to be all 24 possible values from 0 to 15, and recomputed the correct TCP checksum for each TCP packet, and found that the Henan Firewall only blocked a connection when its TCP header length value was 5 words (20 bytes). This experiment indicates that the Henan Firewall did parse the TCP header length field in the TCP header, but had a condition to only block a connection when its TCP header length is 20 bytes. Although we were unable to determine the rationale behind this condition — possibly an oversight by the censor — it raises an important question about how much real-world traffic evaded detection due to this condition. We conducted a test on a university network tap in the United States. Specifically, we captured the TCP header length fields for all traffic on the network tap over a one-hour period from 10:56:14 PM to 11:56:14 PM (UTC) on October 31, 2024. In total, we collected 23.1 billion TCP packets and 5.0 billion TLS packets. As shown in Figure 6, only 22% of the TCP packets had a header length of 20 bytes, and only 19% of the TLS packets had a header length of 20 bytes. This result suggests that the Henan Firewall may only be able to censor around 20% of the targeted connections. |
在河南固定宽带网络上,仅阻断tcp header length为5的流量,从节省算力的角度来讲,也是说的通的。不可能是技术人员疏忽的原因,毕竟先检查4比特 tcp header length,根据header length的值 来决定是否进入 一个继续检查其他字段的 ”分岔路口“,本来就是在节省算力方面效率比较高的行为。 而且在河南数据流量网络上不仅不会放过有 tcp option的流量,也不会放过 tcp fast open流量,也不会放过client hello分片流量(即便servername写在第二个clienthello分片也没用,只有给分片之间加延迟才可避免被阻断)。 几乎只有两种可能性,1.为了节省算力,2.不想这个墙影响范围太广。(具体是哪种原因则不得而知) |
We agree with you that it's unlikely to be an "oversight" by the censor as they intentionally checked for this field.
For your second conjecture, it would be helpful to understand which Operating System will send TCP packets without any TCP options. Do you have any idea on this? Any specific examples would be very helpful.
These observations are very interesting. We, unfortunately, haven't been able to obtain a vantage point to test the Henan mobile network. Do you have any suggestions on how we can obtain such vantage points for testing? (Please feel free to reach out to us privately if you consider this information sensitive. Thank you!) |
@gfw-report XTLS/Xray-core#3601 (comment) 我这个测试结果或许能说明河南的省墙在解析ClientHello方面用了比出口GFW更加高级的方式,就是说有不止一种出口GFW无法阻断的clientHello形态,河南的省墙都能阻断: 以上4个例子都是出口GFW无法阻断,但河南的省墙可以阻断的情况,可以想象设计河南省墙的人就没有任何可能性犯那个 假定 所有TCP包的 TCP头都是20字节的 低级错误。 XTLS/Xray-core#3601 (comment) 也就是说,河南数据流量网络上的省墙,能观测到极多 河南固定宽带网络上的省墙所没有的行为,如果把数据流量网络上的省墙的所有行为都搬到 固定宽带网络上的话,可能算力的确不够用吧。 |
Linux系统和一般的安卓手机都是打开tcp timestamps的,而Windows默认并没有打开tcp timestamps。 |
至于如何获得河南数据流量网络的测试环境,呃,也只能把一台安装了中国手机卡的手机放在河南连入数据流量网络,然后在上面跑代理。只不过麻烦的事情在于,数据流量网络是 有状态防火墙的,IPv6不允许入站,IPv4也是对称性NAT,对此我的建议应该是,在一台连入了有线网络的设备上,再把一台连入了河南数据流量的手机通过USB与此【连入了有线网络的设备】连到一起,跑代理时 通过 有线网络入站, 出站时 绑定到 USB网卡也就是手机 上。 |
Which layer are you fragmenting here? IP fragmentation / TCP segmentation / TLS record layer fragmentation? |
TCP segmentation and TLS record layer fragmentation |
It's TCP segmentation and TLS record layer fragmentation. IPv6 doesn't allow IP fragmentation so I don't care about the situation of IP fragmentation. |
Can you confirm that obfs4 will be identified quickly from traffic characteristics without the modification? And your result is not related to the unusual iat-mode? |
Did you take countermeasures against Residual Censorship? If not, you might get incorrect results. And IPv6 does support fragmentation, see https://datatracker.ietf.org/doc/html/rfc8200#section-4.5
It is unlikely that users of cellular data in China are behind IPv6 NAT, symmetric UDP Firewall can easily be traversed with UDP hole punching. In some regions, users of China Telecom (cellular data) are even behind Endpoint-Independent Mapping NAT. |
thank you,very useful message. |
上海电信这里,对于client hello的tcp层分片没有用(有延迟也不行),得上tls record层的分片配合tcp分片。 |
之前github上刷到,忘了在哪个项目issue里 |
啊,那你刷到的那个也都是我发表的评论,就是这个项目的issue。 |
我在那个issue里发表的 几乎都是推测,没什么证据,但其实我是期待着有能力做实验的人,按照我的想法去设计实验的,后续我自己设计了一点实验也基本证明我那些猜想是正确的( |
所以把sni精准切开能不能绕过河南墙? |
把SNI精准切开的话,不加延迟能绕过河南固定宽带网络上的SNI墙,不加延迟并不能绕过河南数据流量网络上的SNI墙,因为河南数据流量网络上的SNI墙会把没加延迟的clienthello分片组合到一起。加了延迟的话也能绕过河南数据流量网络上的SNI墙了。 |
(我太兴奋了,重写一下,之前有大量错误,并且重新进行实验)
在之前我看到这么一篇博客文章,提到TCP时间戳选项会影响河南省墙的判断。
我对这个说法保持怀疑,但想到如果头部多出十个字节的明文,那么应该可以干扰GFW对obfs4的判断(众所周知,obfs4在中国已经被屏蔽很长一段时间)。
于是我自己配置了一个obfs4 iat-mode=2的网桥,将Windows设置为同时启用TCP窗口和TCP时间戳。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Tcp1323Opts(设置为3)
很有趣的是:obfs4网桥就此恢复正常使用,就好像GFW从来没有侦测到过它一样。
这里是抓包文件,其他人能很明显地发现,到达网桥的通信(TCP 17120端口)从未被干扰/阻止。
即使在我已经在听歌,这段通信依旧未被阻止。
网桥地址:obfs4 172.236.211.247:17120 126E14CC2C03133E70FBBF306D76D75AA96D47EB cert=ubysetrGTVF+eux3IDgjC/w9u6xjGGNUnz89U2zkuDFCF3lQsWb0FuB9qfG6TzN1AL73HA iat-mode=2
The text was updated successfully, but these errors were encountered: