Skip to content

TLS client & server: Support Encrypted Client Hello (ECH) #3813

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jul 26, 2025
Merged

TLS client & server: Support Encrypted Client Hello (ECH) #3813

merged 27 commits into from
Jul 26, 2025

Conversation

Fangliding
Copy link
Member

@Fangliding Fangliding commented Sep 15, 2024

仅客户端
才发现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
Copy link
Member Author

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

@RPRX
Copy link
Member

RPRX commented Sep 15, 2024

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

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

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

@Fangliding
Copy link
Member Author

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

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

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

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

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

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

@RPRX
Copy link
Member

RPRX commented Sep 15, 2024

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

@Fangliding
Copy link
Member Author

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

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

@Fangliding
Copy link
Member Author

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

@Fangliding
Copy link
Member Author

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

@yuhan6665
Copy link
Member

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

@yuhan6665 yuhan6665 changed the title 尝试支持 TLS Encrypted Client Hello ECH: client support TLS Encrypted Client Hello Sep 16, 2024
@dyhkwong
Copy link
Contributor

dyhkwong commented Sep 26, 2024

既然这个在 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

@Fangliding
Copy link
Member Author

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

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

@RPRX
Copy link
Member

RPRX commented Oct 2, 2024

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

@Fangliding
Copy link
Member Author

Fangliding commented Feb 8, 2025

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

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

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

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

@Fangliding
Copy link
Member Author

Fangliding commented Feb 8, 2025

稍微挂个简单点的测试
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"
                    ]
                }
            }
        }
    ]
}

@w0l4i
Copy link

w0l4i commented Jul 26, 2025

so just Adding echconfig list inside tls setting on client side with cf doh , that's all ?
no need to do anything on cf side or server side ?
how to confirm it's working and encrypting client hello ?
so it's essentially work on any tls based config, like httpupgrade tls and etc ... ?

@w0l4i 客户端 TLS 配置内加个 "echConfigList": "https://1.1.1.1/dns-query" 就行

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

so just Adding echconfig list inside tls setting on client side with cf doh , that's all ?

y

no need to do anything on cf side or server side ?

CF enables ECH by default

how to confirm it's working and encrypting client hello ?

No internet if it is not working

so it's essentially work on any tls based config, like httpupgrade tls and etc ... ?

y

@w0l4i
Copy link

w0l4i commented Jul 26, 2025

@w0l4i 客户端 TLS 配置内加个 "echConfigList": "https://1.1.1.1/dns-query" 就行

is this ok ?
IMG_20250726_144322_999.jpg

so in this case we don't need to use fragments !?

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

is this ok ?

y

so in this case we don't need to use fragments !?

It depends

@w0l4i
Copy link

w0l4i commented Jul 26, 2025

is this ok ?

y

so in this case we don't need to use fragments !?

It depends

tnx a lot sir

@w0l4i
Copy link

w0l4i commented Jul 26, 2025

is this ok ?

y

so in this case we don't need to use fragments !?

It depends

depends on ?

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

depends on ?

Whether your area blocks SNI cloudflare-ech.com or not

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

@Fangliding 我发现这个没查到 ECH 的话会回退到明文 SNI,行为不符合预期

@Fangliding
Copy link
Member Author

因为 GetTLSConfig 没有返回错误 只配报log(

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

虽说这个行为也行,不至于 no internet 且报了 log,但在隐私上总觉得欠妥,SNI 泄露

@Fangliding
Copy link
Member Author

要改改下可能也可以 加个err返回就是了 不然用的DNS服务器是被阻断的可能都不知道 不过call这个函数的地方有点多

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

下个版本前改一下吧,Windows 上还能看到 log,但 Android 上没人去看,不知道的还以为能用

要不就加个严格模式,如果没查到 ECH 参数的话就不给连接

还有可能有的地方无法访问分享链接中的 ECH 服务器,可以加个使用本地默认 DNS 查询的选项

@Fangliding
Copy link
Member Author

我想过 但是破go没有 我提了issue 得等猴年马月

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

我想过 但是破go没有 我提了issue 得等猴年马月

想过哪一条

@embeddedlove
Copy link

rust版本

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

rust版本

我打算先给 Xray-core 加上 Windows TUN 再搞 rust 版本的 VLESS 吧

@w0l4i
Copy link

w0l4i commented Jul 26, 2025

rust版本

我打算先给 Xray-core 加上 Windows TUN 再搞 rust 版本的 VLESS 吧

why not to write xray core using rust ?

@Meo597
Copy link
Contributor

Meo597 commented Jul 26, 2025

why not to write xray core using rust ?

pr welcome

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

why not to write xray core using rust ?

Xray-core 这么复杂的功能全用 rust 重写。。。等 AI 再发展个五年吧

目前的想法是 rust 版 VLESS 就是一个极简的客户端,暂不包含服务端功能

@w0l4i
Copy link

w0l4i commented Jul 26, 2025

why not to write xray core using rust ?

pr welcome

fair enough i just ...

@Fangliding
Copy link
Member Author

我想过 但是破go没有 我提了issue 得等猴年马月

想过哪一条

用系统DNS获取的那个

@w0l4i
Copy link

w0l4i commented Jul 26, 2025

我想过 但是破go没有 我提了issue 得等猴年马月

想过哪一条

用系统DNS获取的那个

what about using dns crypt ? and other ways to resolve so there is no worry about unresolving dns query instead of doubt about it's not working or it's dns

@w0l4i
Copy link

w0l4i commented Jul 26, 2025

我想过 但是破go没有 我提了issue 得等猴年马月

想过哪一条

用系统DNS获取的那个

can't use host's inside dns section for this matter ?
i mean hardcoding the dns inside config instead of resolving from dns itself

@RPRX
Copy link
Member

RPRX commented Jul 26, 2025

@Fangliding 至少加个严格模式吧,没查到 ECH 参数就不给连接,不知道其它代理软件的默认行为是怎么样的

@Fangliding
Copy link
Member Author

这个函数25个调用 xhttp那一堆封装丢来丢去也不好弄 要不查失败丢个无效的config进去 应该会失败可以达到目的

RPRX pushed a commit that referenced this pull request Aug 2, 2025
RPRX pushed a commit that referenced this pull request Aug 2, 2025
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.

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy