XTLS / Xray-core

Xray, Penetrates Everything. Also the best v2ray-core, with XTLS support. Fully compatible configuration.
https://t.me/projectXray
Mozilla Public License 2.0
25.53k stars 3.95k forks source link

河南新上的SNI/HOST黑名单墙 #2426

Closed 5e2t closed 1 year ago

5e2t commented 1 year ago

新开个issue,防止在别人的帖子回复时,打扰到别人.......

RPRX commented 1 year ago

https://github.com/XTLS/Xray-core/issues/2229

5e2t commented 1 year ago

IPv4的TTL我尝试了 62 63 64 65 66 127 128 129,在Linux上运行的xray,servername填sslip.io时,均不会触发RST。Linux所处的网络模式为桥接模式。

5e2t commented 1 year ago

我看了半天Windows的IPv4报头,真的跟Linux没有什么不同。

5e2t commented 1 year ago

Windows的IPv4报头的TTL为128,跟Linux里的xray一模一样的配置,会触发RST。

5e2t commented 1 year ago

@5e2t 但其实Linux系统把RST忽略了的这种说法也是说不通的,如果墙给我发了RST,但是被Linux系统忽略了,那么我在Windows上应该是能抓到这个RST的..........或者直接在路由器上抓包,就肯定知道墙有没有发RST了,我倾向于相信墙确实没发RST吧

5e2t commented 1 year ago

感谢@yoohooyoo 提供的修改WindowsTTL的方法,经过测试,Windows的IPv4的TTL为 63 64 65 128时,在servername填sslip.io时,均会触发RST。

Fangliding commented 1 year ago

@5e2t 所以到底是rst包被Linux过滤了还是Linux发出的包由于某些特征免于拦截

5e2t commented 1 year ago

windows的IPv4 TTL为127 和129时 把servername填 sslip.io,均会收到RST

5e2t commented 1 year ago

Windows的IPv4的TTL为255,也会触发RST

5e2t commented 1 year ago

分别在Windows上和Linux上 用openssl测试的结果,跟xray的表现、浏览器的表现一模一样,三种情况都是抓到一样的RST。

5e2t commented 1 year ago

三种情况都是在Windows上抓到RST,在Linux上正常使用,没有RST

RPRX commented 1 year ago

我想说的是在 #2229 继续讨论,你这非要搞两个地方。。。

5e2t commented 1 year ago

@RPRX 我已经不知道该测什么了。

RPRX commented 1 year ago
  1. 电脑是“直出”还是经过了路由器
  2. 你在 WireShark 内看到 TTL 改了吗
  3. 问题不在 IP 栈的话,可能在 TCP 栈,看一下 window、MSS 等有什么区别
5e2t commented 1 year ago

@RPRX 电脑经过了路由器 在wireshark里看到TTL改了

5e2t commented 1 year ago

@RPRX TCP有一个硬件校验和,但是我在网卡设置里看到是打开着的

RPRX commented 1 year ago

你对比一下 Windows 和 Linux 的 TTL 相同时,它们发出的 TCP 数据报有哪些区别,发到这里

capxax commented 1 year ago
  • 电脑是“直出”还是经过了路由器
  • 你在 WireShark 内看到 TTL 改了吗
  • 问题不在 IP 栈的话,可能在 TCP 栈,看一下 window、MSS 等有什么区别

在河南昨天用reality,用的自己的.xyz域名,连了大概1小时后,发现打不开,后来用浏览器访问自己的域名,也会显示连不上,但是ip可以访问,后来reality偷微软的域名,就可以连上了

5e2t commented 1 year ago

@capxax 如果说有什么区别的话,可能是Windows系统的window是1000,而Linux系统的TCP的window是500

5e2t commented 1 year ago

@5e2t 说的clienthello这个包

capxax commented 1 year ago

IMG_8884 自己的域名打不开,但是ip可以

5e2t commented 1 year ago

@5e2t 这个数字是很稳定的,每次Windows上的TCP window都是1028,而Linux系统上的TCP 的clienthello包的window是 502

RPRX commented 1 year ago

@capxax 抱歉折叠了图,有点刷屏,看起来最近河南上了 SNI 黑名单,可能 .xyz 整个都黑了

mclovin-2k commented 1 year ago

@capxax 抱歉折叠了图,有点刷屏,看起来最近河南上了 SNI 黑名单,~可能 .xyz 整个都黑了~

6月份HOSTLOC就有人反应这个情况了。 而且不光是代理,正经建站的也会被封域名。

5e2t commented 1 year ago
810143up433
5e2t commented 1 year ago
810143506
RPRX commented 1 year ago

注:上面的图为 TLS Client Hello 的 TCP 壳,白底的是 Windows,黑底的是 Linux

@5e2t 看一下 TCP 的第一个 SYN 包

5e2t commented 1 year ago
1014up5156 81014up4850
RPRX commented 1 year ago

目前看起来最有可能是 TCP Option - Timestamps,你 Windows 加上它或 Linux 删掉它看看

5e2t commented 1 year ago

Linux关闭 tcp timestamp以后,收到RST

0155941

810152855

0152812

5e2t commented 1 year ago

Linux再开启tcp timestamp,不会收到RST

155913

0153657

154037

RPRX commented 1 year ago

Bingo,看来 GFW 又偷懒了

之前你说 Linux 虚拟机的网络模式改为 NAT 会收到 RST,看看是不是 TTL 的原因(修改 Linux 的 TTL 为 64、128 左右)

5e2t commented 1 year ago

@RPRX 虚拟机网络模式为NAT模式时,在虚拟机上抓包是有TCP timestamps的,但是在Windows上抓包时timestamps不见了。虚拟机网络模式为NAT模式时,在Windows上抓包的源IP是我的Windows电脑的IP。

当虚拟机网络模式为桥接模式时,也能在Windows上抓到Linux系统里的流量,此时源IP为Linux系统的IP,可以看到TCP timestamps选项。

5e2t commented 1 year ago

@RPRX TTL我在Linux上和Windows上都改过了,怎么改TTL都不会让情况发生变化。

5e2t commented 1 year ago

@5e2t 就是说虚拟机网络模式为NAT模式时,我在Windows电脑上抓 Linux虚拟机往外发出的流量,TCP也是经过了重新封装的........

5e2t commented 1 year ago

@5e2t 想想也非常合理,用的是我的Windows电脑的端口,自然用Windows的TCP栈...........

5e2t commented 1 year ago

@5e2t 虚拟机网络模式为NAT模式时,Linux用的是五万多的端口号往外发数据,而我的Windows电脑给Linux系统的数据包进行NAT以后,以我的Windows电脑的IP为源IP往外发数据用的是1000多的端口号,因为我的Windows电脑的临时端口范围是1025-31025

而Linux的临时端口范围是32768-60999

所以TCP肯定需要重新封装,所以TCP timestamps选项没了

RPRX commented 1 year ago

这是实现的锅,其实它也可以选择保留这个选项,这个虚拟机的“NAT 模式”可能是为了简单而几乎完全重新封装 TCP,更像是代理

RPRX commented 1 year ago

关于 TSopt,RFC 7323 的规定如下:

``` A TCP MAY send the TSopt in an initial segment (i.e., segment containing a SYN bit and no ACK bit), and MAY send a TSopt in only if it received a TSopt in the initial segment for the connection. Once TSopt has been successfully negotiated, that is both and contain TSopt, the TSopt MUST be sent in every non- segment for the duration of the connection, and SHOULD be sent in an segment (see Section 5.2 for details). The TCP SHOULD remember this state by setting a flag, referred to as Snd.TS.OK, to one. If a non- segment is received without a TSopt, a TCP SHOULD silently drop the segment. A TCP MUST NOT abort a TCP connection because any segment lacks an expected TSopt. Implementations are strongly encouraged to follow the above rules for handling a missing Timestamps option and the order of precedence mentioned in Section 5.3 when deciding on the acceptance of a segment. ... [RFC1323] recommended that segments NOT carry timestamps and that they be acceptable regardless of their timestamp. At that time, the thinking was that old duplicate segments should be exceedingly unlikely, and their cleanup function should take precedence over timestamps. More recently, discussions about various blind attacks on TCP connections have raised the suggestion that if the Timestamps option is present, SEG.TSecr could be used to provide stricter acceptance tests for segments. While still under discussion, to enable research into this area it is now RECOMMENDED that when generating an , if the segment causing the to be generated contains a Timestamps option, the should also contain a Timestamps option. In the segment, SEG.TSecr SHOULD be set to SEG.TSval from the incoming segment and SEG.TSval SHOULD be set to zero. If an is being generated because of a user abort, and Snd.TS.OK is set, then a Timestamps option SHOULD be included in the . When an segment is received, it MUST NOT be subjected to the PAWS check by verifying an acceptable value in SEG.TSval, and information from the Timestamps option MUST NOT be used to update connection state information. SEG.TSecr MAY be used to provide stricter acceptance checks. ```

太长不看版:(2014)建议 RST 带上 TSopt,接收方可以检查,以防御 RST 攻击(GFW 常用于阻断 TCP 连接的手段)

最有可能是你那边的 GFW 没处理这种情况,只会发普通 RST 包,结果还没到你电脑就被扔了

注:由于 @5e2t 启用 TSopt 后电脑就没收到 RST 包,尚未测试 Windows、Linux 系统本身是否有对 RST 包的严格检查

RPRX commented 1 year ago

启用 TCP Timestamps 选项,Windows:

netsh interface tcp set global timestamps=enabled

Linux(IPv6 也会生效):

sysctl -w net.ipv4.tcp_timestamps=1

显然人们不知道自己的设备有没有开 TSopt,有的默认开了就没被阻断,这就是人们对河南新上的 SNI 黑名单说法不一的原因之一

5e2t commented 1 year ago

@RPRX sysctl -w net.ipv4.tcp_timestamps=1 这一条命令同时对IPv4和IPv6生效

Fangliding commented 1 year ago

启用 TCP Timestamps 选项,Windows:

netsh interface tcp set global timestamps=enabled

Linux(IPv6 应该类似吧):

sysctl -w net.ipv4.tcp_timestamps=1

显然人们不知道自己的设备有没有开 TSopt,有的默认开了就没被阻断,这就是人们对河南新上的 SNI 黑名单说法不一的原因之一

补充一点 Windows查看该选项是否启用 netsh interface tcp show global RFC 1323 时间戳 比如我这就是开的()

5e2t commented 1 year ago

经测试,Windows开启timestamps之后,连接黑名单里的域名不会收到RST。

RPRX commented 1 year ago

下一步就是等你那边的 GFW 修复了,若这个方法凉了仍能根据 TTL 扔 RST 包,结果 GFW 看到这句同时安排上了

总之各地 GFW 的供应商不一,且这种最基础的 RST 攻击都是自己写的,这里不漏那里漏,长期可用,就像新手总会写出 SQL 注入

toyo2333 commented 1 year ago

mac系统和ios系统呢?

RPRX commented 1 year ago

@toyo2333 Google?

@5e2t 我更新了 https://github.com/XTLS/Xray-core/issues/2426#issuecomment-1672957790 ,最后一行你看一下

5e2t commented 1 year ago

@RPRX 不同版本的系统的行为都不同

5e2t commented 1 year ago

@RPRX 这个我应该没法测试了。

5e2t commented 1 year ago

@RPRX 而且最重要的是...........是完全不知道怎么测试

simpleandstupid commented 1 year ago

RFC 1323 时间戳初始是allowed,和enabled有区别吗