apernet / OpenGFW

OpenGFW is a flexible, easy-to-use, open source implementation of GFW (Great Firewall of China) on Linux
https://gfw.dev/
Mozilla Public License 2.0
9.64k stars 725 forks source link

关于针对 TLS in TLS 握手的检测与封锁 #77

Open RPRX opened 7 months ago

RPRX commented 7 months ago

我注意到有这么一段常量与描述:

https://github.com/apernet/OpenGFW/blob/bc2e21e35dcc747bbc80fdebf5dae6215a0c5206/analyzer/tcp/trojan.go#L14-L27

  1. trojanUpUB 在 Trojan-killer 中目前是 750,而在 OpenGFW 中是 1000,应该会增加误报率,这是为了匹配内层 ECH 吗
  2. OpenGFW 是否只是针对单条连接检测并阻断 Trojan?Trojan-killer 只是一个证明 TLS in TLS 问题存在的 PoC,若从封锁的角度来说,我觉得应该持续监测同一目标(IP+端口+域名)的 M 条连接,若阳性率大于 N 就封锁该目标(用户可自定义),这样可以有效提升精准度

题外话:当初我还和 @yuhan6665 讨论要不要把 Trojan-killer 命名为 XGFW,后来决定还是把这个名字留给一个网关式的综合 GFW

RPRX commented 7 months ago

根据去年的众多报告,GFW 对 Shadowsocks 可以做到秒封,而对 Trojan 一般是隔天封端口,猜测是因为 SS 几条连接就可以实锤,而封锁 Trojan 时 GFW 需要收集更多的连接数据、辅以多个维度的信息来加权求和,也就是说封锁这两类适用于不同的决策机制

tobyxdd commented 7 months ago

trojanUpUB 在 Trojan-killer 中目前是 750,而在 OpenGFW 中是 1000,应该会增加误报率,这是为了匹配内层 ECH 吗

是的,我测试的时候发现 750 会匹配不到浏览器发起的很多连接(curl 之类的倒是没问题),必须改到 1000 才行。原因就是 ECH 和一些乱七八糟的额外 extensions

若从封锁的角度来说,我觉得应该持续监测同一目标(IP+端口+域名)的 M 条连接,若阳性率大于 N 就封锁该目标(用户可自定义),这样可以有效提升精准度

我也想过这个问题,只是目前单纯按 expr 表达式匹配的 ruleset 没有保存状态的机制,实现不了 “观察同一个 ip 多个连接,阳性率超过多少就直接封 ip” 这种逻辑。可能提供一个脚本引擎是最好的?

RPRX commented 7 months ago

trojanUpUB 在 Trojan-killer 中目前是 750,而在 OpenGFW 中是 1000,应该会增加误报率,这是为了匹配内层 ECH 吗

是的,我测试的时候发现 750 会匹配不到浏览器发起的很多连接(curl 之类的倒是没问题),必须改到 1000 才行。原因就是 ECH 和一些乱七八糟的额外 extensions

去年 Trojan-killer 放出的时候(2023 年 5 月)好像还没这么乱,去年底我测试 ECH 和 X25519Kyber768Draft00 发现前者会使 CH 长度变为 512+,后者则是 1500+,不过它们至今仍要手动开 flag,如果是普通用户而非我们这种开发者应该还是 512

若从封锁的角度来说,我觉得应该持续监测同一目标(IP+端口+域名)的 M 条连接,若阳性率大于 N 就封锁该目标(用户可自定义),这样可以有效提升精准度

我也想过这个问题,只是目前单纯按 expr 表达式匹配的 ruleset 没有保存状态的机制,实现不了 “观察同一个 ip 多个连接,阳性率超过多少就直接封 ip” 这种逻辑。可能提供一个脚本引擎是最好的?

想出了一种非常简单的实现,比如说一条阳性就 +2,一条阴性就 -1,不可减至负数,总数大于 20 就封锁,这三个数可自定义,前两个数决定比例(阳性率大于 1/3 就迟早被封),“总数”决定容错程度(允许偶尔出现一些阳性),建议直接实现该机制

RPRX commented 7 months ago

看了下去年底测试 ECH 的 pcapng 文件,Chrome CH 长度均未超过 600,为了匹配它加 100 是可以接受的,即 650~850

ghost commented 7 months ago

不过它们至今仍要手动开 flag

TLS Encrypted Client Hello (ECH) 特性已在 Chromium 117 版本后默认启用,而 X25519Kyber768 key encapsulation for TLS 特性计划至 124 版本后才默认启用,124 稳定版本计划在 4 月 10 日发布。

RPRX commented 7 months ago

不过它们至今仍要手动开 flag

TLS Encrypted Client Hello (ECH) 特性已在 Chromium 117 版本后默认启用,而 X25519Kyber768 key encapsulation for TLS 特性计划至 124 版本后才默认启用,124 稳定版本计划在 4 月 10 日发布。

感谢,我用 Chrome 122 reset all flags 后试了一下,似乎后者也默认启用了,那么我有个大胆的想法,你那边的情况呢?

ghost commented 7 months ago

~似乎后者也默认启用了,那么我有个大胆的想法~,你那边的情况呢?

后者似乎是从 Chrome 121 版本后,如果登录了 Google 账号还是说在别的因素的影响下,会灰度启用。

RPRX commented 7 months ago

看起来 Trojan-killer 需要更新 2.0 了,虽然增大匹配范围必定会增大单个连接的假阳率,但配合“封锁算法”应该仍能做到足够精准

tobyxdd commented 7 months ago

~看起来 Trojan-killer 需要更新 2.0 了~,虽然增大匹配范围必定会增大单个连接的假阳率,但配合“封锁算法”应该仍能做到足够精准

更新的话要不直接在 OpenGFW 上 PR 吧 🗿

RPRX commented 7 months ago

更新的话要不直接在 OpenGFW 上 PR 吧 🗿

这个更新可能是有生之年系列,所以