Skip to content

Conversation

@Fangliding
Copy link
Member

RT 如果DNS消息回复被截断则再次发送带EDNS的请求并把大小扩展到1350

@RPRX RPRX merged commit 7eebf55 into main Mar 21, 2025
70 checks passed
@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

@Fangliding 我发现这些 DNS 查询所用到的 genEDNS0Options() 函数内本来就有一行

common.Must(opt.Header.SetEDNS0(1350, 0xfe00, true))

@Fangliding
Copy link
Member Author

Fangliding commented Mar 21, 2025

@Fangliding 我发现这些 DNS 查询所用到的 genEDNS0Options() 函数内本来就有一行

common.Must(opt.Header.SetEDNS0(1350, 0xfe00, true))

这个是用来设置client IP的 如果没有就不会设置

我这个会检查原始msg是否有ENDS0参数 如果没有就不retry了

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

按我的理解,不是一定有的吗

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

看到了,没有 client IP 的话就没有了

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

我是想给 EDNS0 加个 padding net4people/bbs#459 (comment) ,给 DoH 默认启用,你有空研究下吗

EDNS0PADDING = 0xc // EDNS0 padding (See RFC 7830)

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

DoH 服务器似乎都支持这个,如果请求是 EDNS0 with padding,响应就会自动带上 padding

@Fangliding
Copy link
Member Author

Fangliding commented Mar 21, 2025

我是想给 EDNS0 加个 padding net4people/bbs#459 (comment) ,给 DoH 默认启用,你有空研究下吗

EDNS0PADDING = 0xc // EDNS0 padding (See RFC 7830)

这非常简单 只需要这样就行了

padding := dnsmessage.Option{
Code: 0xc,
Data: make([]byte, 100),
}
opt.Body.(*dnsmessage.OPTResource).Options = append(opt.Body.(*dnsmessage.OPTResource).Options, padding)

或者直接修改 genEDNS0Options 函数就行了
不过我必须提一句这样作用有限 一是服务端不会padding 二是一来一回的模型还是摆在那

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

服务端不会padding

据说如果客户端带上了 padding,服务端也会自动带上,至少 1.1.1.1 貌似是这样

Golang h2 req 的 header 和 body 没粘一起 #4430 (reply in thread) ,所以之前 e466b04 光给 req header 加 padding 还不够

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

RFC 8467:

   Based on empirical research performed by Daniel K. Gillmor
   [NDSS-PADDING], padding SHOULD be performed following the Block-
   Length Padding strategy as follows:

   (1)  Clients SHOULD pad queries to the closest multiple of 128
        octets.

   (2)  If a server receives a query that includes the EDNS(0) "Padding"
        option, it MUST pad the corresponding response (see Section 4 of
        RFC 7830) and SHOULD pad the corresponding response to a
        multiple of 468 octets (see below).

   Note that the recommendation above only applies if the DNS transport
   is encrypted (see Section 6 of RFC 7830).

@Fangliding
Copy link
Member Author

Fangliding commented Mar 21, 2025

should而已 CF没实现也很正常 这不是我的观点 事实如此
image
顺便它要是按里面的描述padding到定长回复那就更地狱了

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

@Fangliding 你这张图,客户端带上 padding 了吗

@Fangliding
Copy link
Member Author

肯定是带了才这么说的

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

@Fangliding 是不是 padding 方式错了或你看的地方不对?RFC 写的是“it MUST pad the corresponding response”,并且

https://community.cloudflare.com/t/doh-service-adds-edns-padding-even-if-client-does-not-indicate-edns-support/84199
https://community.cloudflare.com/t/1-1-1-1-malformed-but-technically-valid-response-tls-1-3/350031

1.1.1.1 是支持这个的

@Fangliding
Copy link
Member Author

Fangliding commented Mar 21, 2025

@Fangliding 是不是 padding 方式错了或你看的地方不对?RFC 写的是“it MUST pad the corresponding response”,并且

https://community.cloudflare.com/t/doh-service-adds-edns-padding-even-if-client-does-not-indicate-edns-support/84199 https://community.cloudflare.com/t/1-1-1-1-malformed-but-technically-valid-response-tls-1-3/350031

1.1.1.1 是支持这个的

哦 UDP DNS 没有 DOH 有 还蛮细节

还有是我猜对了 1.1.1.1 把每个 response 都 padding 到定长 468 从隐私上讲这样很好 从隐藏DOH看 嗯。。。

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

还有是我猜对了 1.1.1.1 把每个 response 都 padding 到定长 468 从隐私上讲这样很好 从隐藏DOH看 嗯。。。

一言难尽啊,不过 A 和 AAAA 查询的 response 长度本来就比较固定吧?

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

还有 response h2 header 和 body 一般是粘起来的吧?有没有什么办法能诱使服务端在 response header 中加些料

@Fangliding
Copy link
Member Author

为了防止放大攻击这块管的都比较严

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

h.Class = Class(udpPayloadLen) 这个会不会影响 response 长度?

我在想要不不用 0xc,用个未定义的其它 code,防止服务端把 response padding 至定长

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

或者有办法把 h2 req header 和 body 粘一起的话也行

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

经过考虑,我觉得 DoH req body 默认开 padding 还是有必要的,就算会导致比如 1.1.1.1 把 response padding 至定长 468 从而暴露了这条 HTTPS 是 DoH,但它不 padding 就不会暴露了吗?同样会,且可能会因为 response length 变化而暴露更多信息,所以只能说是两害相权取其轻吧,至少先把隐私保护起来,以及现在为了隐藏 DoH 至少都要配合 domain fronting,针对白名单 SNI 还要分析流量时序特征也增加了 GFW 的工作量,最后就是自建的 DoH 服务端可以有不同的 padding 策略,也可以只针对 header

另外 Golang h2 req 先发 header 的原因是 golang/go#58674 (comment) ,还挺有道理的,短期内估计不会改,需要 padding body

@Fangliding
Copy link
Member Author

h.Class = Class(udpPayloadLen) 这个会不会影响 response 长度?

我在想要不不用 0xc,用个未定义的其它 code,防止服务端把 response padding 至定长

这是可以做到的 CF不会在服务端padding了

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

我觉得还是让它 padding 吧,总比没有 padding 暴露更多信息强,况且这 Golang h2 库特征本来就挺多的,有点难藏

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

532261d 的 test 炸了,但只炸 Windows 是什么原理 @Fangliding

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

TestDOHNameServer 的 https+local://1.1.1.1/dns-query 只在 Windows 上炸

@Fangliding
Copy link
Member Author

复现不能 我的电脑上是好的

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

我发现炸哪不是确定的,最新的测试炸的是 TestDOHNameServerWithIPv6Override

可能是随机到的 padding 100-600 过长会炸?第一次测试时就 Windows 比较倒霉命中了,后面每次都比较倒霉?

@Fangliding
Copy link
Member Author

Fangliding commented Mar 21, 2025

这下懂了 单个request body最大不能超过512字节(同原始udp dns) 不然就爆炸 所以是随机爆炸不是就Windows炸 我的新测试里就炸了俩

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

这个 512 是哪里的限制,DoH 规范还是?

@Meo597
Copy link
Collaborator

Meo597 commented Mar 21, 2025

这个 512 是哪里的限制,DoH 规范还是?

https://developers.google.com/speed/public-dns/docs/doh?hl=zh-cn

谷歌也这样,问就是他们说了算

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

这个 512 是哪里的限制,DoH 规范还是?

https://developers.google.com/speed/public-dns/docs/doh?hl=zh-cn

我之前看到了这篇,不过我只看了 EDNS 那里

既然这样把 padding 范围改为 100-300 应该就没问题了,至于 h2 padding,Golang 可能没提供接口,就像 TLSv1.3 padding

@Fangliding
Copy link
Member Author

这个 512 是哪里的限制,DoH 规范还是?

找了几个地方应该是他们自家的策略 8888和1111都是512

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

改成 100-300 了,至于那篇文档里提到的别发 User-Agent,我本来想删掉 Golang 的,但怕过不了(自建)DoH behind CDN

至于要不要把 Xray 的 HTTP 请求全改为 Chrome 的 UA,这是另一个话题,目前对抗 CDN 不是 Xray 的重点

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

ecc3d46 炸的是 TestUDPDNSTunnel,看起来只是偶然炸了,并不涉及 DoH

maoxikun pushed a commit to maoxikun/Xray-core that referenced this pull request Aug 23, 2025
maoxikun pushed a commit to maoxikun/Xray-core that referenced this pull request Aug 23, 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.

4 participants