Xray-core icon indicating copy to clipboard operation
Xray-core copied to clipboard

ECH: Support TLS Encrypted Client Hello

Open Fangliding opened this issue 1 year ago • 117 comments

仅客户端 才发现go1.23官方已经支持了 之前写过的那堆复杂替换也不需要了 就正常写入就行了 ws和splithttp预计都能使用cloudflare的ECH 已经测试可以和singbox与cloudflare建立ECH连接 稍微挂个简单点的测试 curl http://crypto.cloudflare.com:443/cdn-cgi/trace --resolv crypto.cloudflare.com:443:127.0.0.1 可以看到 sni=encrypted

{
    "log": {
        "loglevel": "debug"
    },
    "inbounds": [
        {
            "port": 443,
            "listen": "127.0.0.1",
            "tag": "in",
            "protocol": "dokodemo-door",
            "settings": {
                "address": "crypto.cloudflare.com",
                "port": 443,
                "network": "tcp"
            }
        }
    ],
    "outbounds": [
        {
            "tag": "tls-repack",
            "protocol": "freedom",
            "streamSettings": {
                "security": "tls",
                "tlsSettings": {
                    "serverName": "crypto.cloudflare.com",
                    "fingerprint": "unsafe",
                    "echConfigList": "fimtale.com+udp://1.1.1.1",
                    "alpn": [
                        "http/1.1"
                    ]
                }
            }
        }
    ]
}

Fangliding avatar Sep 15 '24 04:09 Fangliding

有一个最大的问题是utls是go121的似乎 现在还不支持 遥遥落后了

Fangliding avatar Sep 15 '24 04:09 Fangliding

有一个最大的问题是utls是go121的似乎 现在还不支持 遥遥落后了

Win7 编译也需要 go121,所以等 2025 再加这个吧,至少得 utls 支持,而且感觉无法通过本地 dns 拿到 echConfig 的话有点鸡肋

最大的问题还是 GFW 又会严控 DNS 了

RPRX avatar Sep 15 '24 04:09 RPRX

有一个最大的问题是utls是go121的似乎 现在还不支持 遥遥落后了

Win7 编译也需要 go121,所以等 2025 再加这个吧,至少得 utls 支持,而且感觉无法通过本地 dns 拿到 echConfig 的话有点鸡肋

这点我考虑过了 稍后可以加build tag绕过低版本go 就像隔壁一样

至于utls 等它支持了 核心改两行代码就能跟上了 目前这个实验性功能应该没有什么坏处

最大的问题还是 GFW 又会严控 DNS 了

在配置里加一个可选的doh服务器用于获取解析? 或者尝试写死 观察一段时间 不知道CF这个ECH config是不是轮动的 如果不是的话写死也能接受

Fangliding avatar Sep 15 '24 04:09 Fangliding

先写一下通过 dns 获取 echConfig,然后等 utls 支持了再合这个 pr 吧,~~其实仅用 utls 的话可能 Win7 也能用?~~

RPRX avatar Sep 15 '24 04:09 RPRX

先写一下通过 dns 获取 echConfig,然后等 utls 支持了再合这个 pr 吧,~其实仅用 utls 的话可能 Win7 也能用?~

有一个小问题是内置DNS服务器只能处理A和AAAA 这个要再加就得外置 utls更新不知道猴年马月了 他们撮了个李鬼ech 这估计还得修改一部分才能兼容 而且开发好像没那么活跃 上次commit两个月前 这边合着测试一下大概问题不大?

Fangliding avatar Sep 15 '24 05:09 Fangliding

好了 现在支持 "echDohServer": "https://1.1.1.1/dns-query" 这样的方法代替echConfig了 设置了600秒TTL缓存 要求设置 serverName(不然去查谁呢)

Fangliding avatar Sep 15 '24 06:09 Fangliding

好了已经通过测试 websocket可以设置doh sever然后通过ECH连接到cloudflare splithttp和grpc大概也是可以的

Fangliding avatar Sep 15 '24 07:09 Fangliding

看了一下非常棒!建议及早合并

yuhan6665 avatar Sep 16 '24 15:09 yuhan6665

既然这个在 v2fly 和这里都开了并且不是 draft、没有进一步行动,那么:

  • mutex 用错
  • ServerName 用错,为什么不用 *tls.Config 的?(e.g. sni 不填,服务器地址是域名)
  • proto 里的 ech_config 类型可以为 bytes
  • 根据 RFC,DoH 的 message id “应该”为 0
  • 能用正常方法读取的为什么要用正则表达式去读取?
for _, answer := range msg.Answer {
	if https, ok := answer.(*dns.HTTPS); ok && https.Hdr.Name == dns.Fqdn(domain) {
		for _, v := range https.Value {
			if echConfig, ok := v.(*dns.SVCBECHConfig); ok {
				return echConfig.ECH, answer.Header().Ttl, nil
			}
		}
	}
}
  • 完全没有 context 管理

建议重写或转 draft

dyhkwong avatar Sep 26 '24 14:09 dyhkwong

@dyhkwong 感谢指正 有的问题我也知道不过没打算合我也没动了 等会改一下

不过有必要ctx吗 log里用Background的原因是GetTLSConfig这个函数就没有ctx 至于内部管理 我想这么简单大概没有必要?

Fangliding avatar Sep 26 '24 14:09 Fangliding

~~隔壁咋已经合了,就是说现在没 uTLS 支持不会觉得很鸡肋吗,等待 uTLS 更新~~

RPRX avatar Oct 02 '24 04:10 RPRX

稍微更新了一下 以便可能有人需要

区别 rebase到最新的commit 理论上可以支持XHTTP(3)

删除win7不支持的警告 由于使用魔改go而不是旧版本所以可以正常使用

proto文件让位到20 避免跟目前在开发的mitm功能撞车 顺便mitm功能可以扩展到接管所有被墙的CF网站(通过ECH)

Fangliding avatar Feb 08 '25 10:02 Fangliding

稍微挂个简单点的测试 curl http://crypto.cloudflare.com:443/cdn-cgi/trace --resolv crypto.cloudflare.com:443:127.0.0.1 可以看到 sni=encrypted

{
    "log": {
        "loglevel": "debug"
    },
    "inbounds": [
        {
            "port": 443,
            "listen": "127.0.0.1",
            "tag": "in",
            "protocol": "dokodemo-door",
            "settings": {
                "address": "crypto.cloudflare.com",
                "port": 443,
                "network": "tcp"
            }
        }
    ],
    "outbounds": [
        {
            "tag": "tls-repack",
            "protocol": "freedom",
            "streamSettings": {
                "security": "tls",
                "tlsSettings": {
                    "serverName": "crypto.cloudflare.com",
                    "fingerprint": "unsafe",
                    "echConfigList": "fimtale.com+udp://1.1.1.1",
                    "alpn": [
                        "http/1.1"
                    ]
                }
            }
        }
    ]
}

Fangliding avatar Feb 08 '25 12:02 Fangliding

~~建议 rebase 一下~~

RPRX avatar Feb 08 '25 12:02 RPRX

等改好吧 这为啥不开个pr一直在fp((

Fangliding avatar Feb 08 '25 12:02 Fangliding

我还在想要不要加个 alterNameForDohServer 或者 做成 "echDohServer": "xxx.com+https://1.1.1.1/dns-query" 这样的类型 因为从面向 cloudflare 编程的角度很多域名不返回 https 记录但是他们的 infra 支持ech握手 需要加个其他域名获取到 https记录

Fangliding avatar Feb 08 '25 12:02 Fangliding

想了一下还是加上了 ech config 不应该强行和 servername 挂钩 改了一下楼上的示例 从其他网站拿到 ech config 连接本没有 HTTTPS 记录的 crypto.cloudflare.com ps: 奇怪的是 这是CF的官方ECH测试域名 本来是有的 几个月前不知为何被撤掉了 测试网站也被下了

Fangliding avatar Feb 08 '25 18:02 Fangliding

说到TLS go的 x25519Kyber768 还没捂热乎 1.24+就已经让它滚了 甚至不是兼容而是删了 换成了 X25519MLKEM768 (这是正统不是draft了)顺便现在编译出的golang默认启用后量子 和前段时间还不一样

Fangliding avatar Feb 08 '25 18:02 Fangliding

可以 rebase 了,~~虽然这个 PR 会放到以后的版本~~

话说现在 Chrome 是啥指纹,uTLS 的指纹是不是已经过时了?

RPRX avatar Feb 08 '25 18:02 RPRX

uTLS 过时了的话我们通过 REALITY 仓库弄一个吧,我想的是把现成 Chrome 指纹当做模板,填东西进去就行,再打乱扩展顺序

RPRX avatar Feb 08 '25 18:02 RPRX

~~这样又少一项 TLS 依赖~~

RPRX avatar Feb 08 '25 18:02 RPRX

最好联系一下 Gaukas Wang 至少让他写一个维护指纹的 training

yuhan6665 avatar Feb 08 '25 18:02 yuhan6665

我不想以 uTLS 那种方式维护指纹,感觉搞得太复杂了,我觉得有指纹模板然后替换内容进去就行,顶多再加个打乱扩展顺序

RPRX avatar Feb 08 '25 18:02 RPRX

可以 rebase 了,~虽然这个 PR 会放到以后的版本~

merge 按钮是亮的 这个pr对原结构改掉很小 别动proto和那个config解析应该不会conflict

顺便1.24会加服务端支持 到时候应该也是稍微改动即可

话说现在 Chrome 是啥指纹,uTLS 的指纹是不是已经过时了?

新版本带后量子的 但是过时这个事不能这么说 不是说跟最新不一样就是没了了 旧版本chrome的流量肯定还有很多很多的

我不想以 uTLS 那种方式维护指纹,感觉搞得太复杂了,我觉得有指纹模板然后替换内容进去就行,顶多再加个打乱扩展顺序

utls 指纹差不多就是模板 但是kyber毕竟涉及到握手流程 这个不能发假的得真实现 有点难 至于基于gotls的模板的模板。。支持这样搞吗 得修改tls库吧

Fangliding avatar Feb 08 '25 19:02 Fangliding

merge 按钮是亮的 这个pr对原结构改掉很小 别动proto和那个config解析应该不会conflict

不是 conflict,我考虑的是如果有人要用这个 PR,不会用到有 bug 的版本

RPRX avatar Feb 09 '25 00:02 RPRX

utls 指纹差不多就是模板 但是kyber毕竟涉及到握手流程 这个不能发假的得真实现 有点难 至于基于gotls的模板的模板。。支持这样搞吗 得修改tls库吧

等 Chrome 默认发 X25519MLKEM768 了就能搞

不是基于 gotls,是基于 REALITY 仓库

RPRX avatar Feb 09 '25 00:02 RPRX

等 Chrome 默认发 X25519MLKEM768 了就能搞

早就是了

不是基于 gotls,是基于 REALITY 仓库

那得看了

Fangliding avatar Feb 13 '25 15:02 Fangliding

BTW we have the new research fellow taking over UTLS (thank god Trump cannot/haven't layoff this project) You two knows quite a lot about fingerprint, we can make suggestions to Mingye Chen if you see fit.

yuhan6665 avatar Feb 18 '25 17:02 yuhan6665

能复更是最好的 能把新版chrome做一下再支持一下ech就行了(

Fangliding avatar Feb 18 '25 19:02 Fangliding

等待 https://github.com/refraction-networking/utls/pull/322

RPRX avatar Feb 25 '25 13:02 RPRX