Skip to content

Fix max CCS fingerprint#29

Open
Fangliding wants to merge 2 commits intoXTLS:mainfrom
Fangliding:main
Open

Fix max CCS fingerprint#29
Fangliding wants to merge 2 commits intoXTLS:mainfrom
Fangliding:main

Conversation

@Fangliding
Copy link
Member

@Fangliding Fangliding commented Feb 16, 2026

这样应该就没问题了 就是被探测的网站根据行为可以知道被设置为reality dest了 或者像之前说的允许用户手动设置 嗯。。。

话说我都没这仓库的write权限((

@Fangliding
Copy link
Member Author

目前的局限性有几个
网站会知道你在用reality指向它(这种探测过于明显)
大多数网站需要64倍rtt的时间完成探测(不过应该没人dest选延迟太高的服务器给自己找补吧) 如果延迟比较低比如30ms那两秒不到可以探测完成
理论上在极端网络波动下下小于32的服务器可能返回一个略大的值 比如16变成17
部分网站的行为是无限 我拿3xui的内置表试了下 aws因为使用自有TLS实现 实际限制是无限(97是探测工具写的探测上限不是实际)
image

还有几个方案
1 固定四个挡位 1 16 32 ∞ 探测出它们比较简单
2 用户手填 不探测了 默认就 32 可以满足大多数情况

@kyber1024
Copy link

kyber1024 commented Feb 19, 2026

有无可能类似TLSmirror那样把不来自可信客户端的所有流量,包括但不限于不合法的client hello,未通过协商的密钥加密的包,全都发给dest.但是者意味着需要为每一个用户的连接维护一个匹配的和dest的tls1.3连接.好处可以解决几乎所有的edge case

@RPRX
Copy link
Member

RPRX commented Feb 21, 2026

已知 Golang TLS 的 NewSessionTicket 都在 ClientFinished 前,或许可以简单些?

另外应当像 uTLS 库一样标出哪些修改专属于 REALITY,防止以后再被误改

@Fangliding
Copy link
Member Author

Fangliding commented Feb 21, 2026

不太行 各家TLS有的有一定程度魔改 比如cloudflare 虽然max ccs是32 但是它和golang一样不会在握手完成后立即发这个有特征的NewSessionTicket

@Fangliding
Copy link
Member Author

而且这个PostHandshakeRecords不一定来自NewSessionTicket消息 它还可能来自h2服务器看到h2 alpn后发来的一些前置信息

@RPRX
Copy link
Member

RPRX commented Feb 21, 2026

主要是我测试 REALITY 都是本地跑的那不就把我卖了,虽然这完成了探测的 TODO

record_detect.go 就别改名了吧,另外哪里是 REALITY 针对 TLS 改的部分标一下,防止再同步错了

@RPRX
Copy link
Member

RPRX commented Mar 21, 2026

@Fangliding 改成固定探测四个挡位吧 1 16 32 ∞,先发 2 个,再发 15 个,再发 16 个,三次即可完成探测,文件先别改名了

@Fangliding
Copy link
Member Author

为啥不改名呢

@Fangliding Fangliding force-pushed the main branch 2 times, most recently from 9763d16 to c7dcea2 Compare March 21, 2026 17:04
@RPRX
Copy link
Member

RPRX commented Mar 22, 2026

因为会影响查看修改历史,话说 CCS 也是 record 所以叫 record_detect.go 并不违和,主要是 fingerprint 不说哪边也有歧义

@RPRX
Copy link
Member

RPRX commented Mar 22, 2026

  1. 现在只需要探测三次了,max RTT 改为一秒吧
  2. 改为 target, err := net.Dial(config.Type, config.Dest)
  3. 去掉 conn.go 1255 和 tls.go 428 处多余的空行

别的暂时没看到问题,你测试一下这个确实生效就行

@Fangliding
Copy link
Member Author

Fangliding commented Mar 22, 2026

  1. 现在只需要探测三次了,max RTT 改为一秒吧

那个不是max RTT 那是min RTT,在100ms和测得值里取最大的

这么设计的原因是有时候ping值会非常非常低 比如部分机房贴脸接入CDN的情况下ping可能只有零点几毫秒 我怕等待这么短会因为硬件噪音而错过回复才设置最小 100ms也挺够了

@RPRX
Copy link
Member

RPRX commented Mar 22, 2026

细看了一下还真是 min RTT,那 100ms 没问题

这个探测甚至还附带上了不同的 alpn,现在会同时对 target 开六条 TCP 了,这很 Chrome

虽然在这里 alpn 可能没啥用,另外我们把 alpn http/1.1 藏进 ECH 里的独家做法确实会导致网站发包行为可能产生差异

@RPRX
Copy link
Member

RPRX commented Mar 22, 2026

别根据 RTT 来了,就固定一秒吧,毕竟 RTT 是浮动的容易出错,即使是固定的比如说 TCP dial 是 50ms,处理 TLS 也要加时间

@RPRX
Copy link
Member

RPRX commented Mar 22, 2026

本身 post-handshake records 的探测都等五秒了,这里 go 同时等个几秒没啥问题,反正只要探测三次了

@Fangliding
Copy link
Member Author

本来是有一个RTT增益的我忘记填了 算了一秒就一秒吧

@Fangliding
Copy link
Member Author

image

测了一下应该没啥问题 跟我之前写的精确探测器数值一致

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants