知名项目 Xray 的作者放出了一个简单的项目,可以轻松识别你的 Trojan 传出流量,换而言之如果将这个程序的逻辑部署在长城防火墙中, 则可以实现全面封禁所有 Trojan 协议。也有很多传言说 Trojan 被识别、Vmess 被识别等各种说法,很多都是因为 TLS 被检测出来了。
介绍
注意这只是一个简单的程序,一个 Demo,一个 Example 只是为了说明 Trojan 或 TLS in TLS 的问题,供于参考和学习,其源代码中主要的逻辑是:
v1.0.0 · XTLS/Trojan-killer@02c3683 · GitHub
监听一个端口,将 Trojan 传出的流量导入这个程序, 通过识别每一个连接的CCS 交换密钥及之后 上传字节是否在 650 与 750 的区间,下载字节在 170-180, 或 3000-7500 的区间。
若建立的连接符合这么一个简单的特征,则认为这是 TLS in TLS 流量。
TLS in TLS
Trojan 本身是通过 TLS 建立的连接,而封装在 Trojan 之内的流量原本是不可见加密的,以保证用户传输内容安全。但因为访问 https 网站时,其网站连接 TLS 握手固定的特征大小头被塞入了 Trojan 的 TLS 包中。
使其特征更明显,原本常见的客户端访问 HTTPS 网站 ,它的 TLS Client Hello 握手包一般是 517 字节,交换密钥 CCS ( Change Cipher Spec) 也都很小。将原本用户的 TLS Client Hello + CCS 包塞入 Trojan 服务器连接的 TLS 包中, 刚好可能符合 Trojan-Killer 上行识别的范围 650-750 字节,所以能够命中。
curl Google 服务器
curl Cloudflare 服务器
Google TLS IN Trojan TLS 请求
误判
在测试中,打开监听程序, 将浏览器的代理设置到 Trojan-Killer,网站均能够正常访问,且不会报有异常。
当把 Trojan 的流量导入 Trojan-Killer 中时,浏览器设置代理为 Trojan,则几乎所有的流量都能够被识别到。
有人说,通过字节大小判断,未免太武断不严谨,会不会误判,有一些没考虑到的场景或者互联网公司常用的协议 grpc 之类的等等?
目前阶段从作者的反馈和其他用户的评论来看,理论上是有误判,但目前大部分场景很难命中或是很少。
即使有误判,在宁可错杀不可放过的政策下,GFW 也随时有可能采用这套策略来封禁流量。
复现
如果你也想简单复现,可以按照 README 编译源代码,或者下载我 编译好的文件。
1. 首先运行 exe,它会监听本机 12345 端口
2. 设置浏览器的代理,如 Chrome 的 SwitchyOmega 插件:
新建一个情景模式,代理服务器和端口为:127.0.0.1:12345 协议为 HTTP,并为其命名 为 TrojanKill。
选中代理插件中的 Trojan-Kill
然后访问 Google,或者任意 https 网站,你就可以发现这个中间人程序一切正常。
3. 将你常用的 Trojan 代理 出口转到 Trojan-Killer 上
这个 example 目录中有提供 Trojan 的服务端和客户端配置,无论你使用官方 Trojan 或者 Xray 或者 V2ray 均可以。
需要你有手动改配置的能力,在此简单说明下。
这个配置的核心是将你 Trojan 的完整流量导入到这个 HTTP 的 outbounds 中,关键参数是 sockopt 的 dialerProxy 配置。
注:在 outbounds 没有路由干扰的情况下,默认采用第一条作为传出终端。
4. 同 第二步方法,为浏览器新增一个代理,配置协议为 HTTP,服务器端口为:127.0.0.1:11111( example 中的地址) 或者你具体真实的监听地址。
然后刷新 Google,访问 YouTube 等任何 https 网站,就可以明显看到 Trojan-Killer 识别到了你所有的特征流量。
那么试想一下,如果你是 GFW,你会不会封杀这个可疑服务器?
其实也不只是 Trojan 流量,包括 naiveproxy, vmess, vless 等任意协议外层套了 TLS 证书的(符合 TLS IN TLS 流量特征),都能够轻易识别。
也不排除去年 10 月 GFW 也是使用了类似的策略进行干扰。
相关讨论
https://github.com/XTLS/Trojan-killer
Xray 的作者欢迎也支持大家去他的项目或 issues 中进行友好讨论,来指出或改进方案。
有需要的去研究研究。