Skip to content

DNS: Support returning upstream TTL to clients#4526

Merged
RPRX merged 5 commits intoXTLS:mainfrom
Meo597:dns-ttl
Mar 24, 2025
Merged

DNS: Support returning upstream TTL to clients#4526
RPRX merged 5 commits intoXTLS:mainfrom
Meo597:dns-ttl

Conversation

@Meo597
Copy link
Collaborator

@Meo597 Meo597 commented Mar 21, 2025

响应给客户端的TTL不应是魔法值600

此PR能做到:

  • FakeDNS = 1
  • Hosts = 10
  • LocalDNS = 600 (若觉得不合适可改成60)
  • 其它遵循上游DNS,体现出当前Xray管理的缓存有效期

Closes #4527

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 21, 2025

对了

proxy/dns/dns.go

	// if fkr0, ok := h.fdns.(dns.FakeDNSEngineRev0); ok && len(ips) > 0 && fkr0.IsIPInIPPool(net.IPAddress(ips[0])) {
	// 	ttl = 1
	// }

我注释掉了这个,是因为此PR已经实现其功能
但从没深入了解过FakeDNS,也不方便去配置和测试
代码角度我认为没啥问题

如果一切正常应该删掉
已经删了,等yuhuan review

@Fangliding
Copy link
Member

我的想法
回这个ttl没啥很大用 很多地方还要变成 ips, _, err := 这样 原函数的签名不用改 改成包装一个新的 QueryIPAndTTL 之类的就行了
以及AAAA记录的TTL会覆盖A记录的(虽然它们和原始记录没关系 是xray内部缓存expire的时间)
总的来说还是觉得没啥必要 回个600和回个距离xray的expire时间区别不大 FakeDNS回1我说不准 我没用过但是见过一些讨论 如果真有需要 就单要一个fakedns回1直接拿着响应IP滤一遍FakeDNS pool就行了不用改DNS模块

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

其实我也感觉必要性不大,这东西基本上就是有个缓存就行,总不会过了 TTL 那个 IP 就用不了了,都会给几天过渡期

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 21, 2025

关于_变丑问题,其实大多都是test,真正变丑的地方没几个
我当时就是这么考虑的因此没做lookupIPAndTTL

TTL理应准确,因为没啥开销
不准的话其实还是有副作用的
例如DDNS
例如有人花大钱买了贵的权威套餐好不容易把TTL弄到1,就因为用了Xray直接给人干废了

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 21, 2025

关于fakeDNS

被我注释掉的代码和此PR重复
对Xray代码不熟,又没配过FakeDNS
因此只是注释掉没删

谨慎起见应该让用过FakeDNS的人测一下,但凭感觉我认为没啥问题

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 21, 2025

关于AAAA记录的TTL会覆盖A记录的(虽然它们和原始记录没关系 是xray内部缓存expire的时间)

我不清楚在什么条件下能够同时返回a+aaaa
我自己透明代理v4环境,总是只返回a

如果确有需求,可修改问题不大

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

例如有人花大钱买了贵的权威套餐好不容易把TTL弄到1,就因为用了Xray直接给人干废了

考虑到这一点的话,Xray 作为基础工具,这个 PR 还是可以接受的

@yuhan6665 看一下?

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 21, 2025

总的来说我认为作为dns模块理应遵守规范

要不是go不熟,我甚至想让它像个完整的递归dns

psping ping traceroute dig+trace用不了、dig不给看ttl感觉天都塌了

@RPRX RPRX requested a review from yuhan6665 March 21, 2025 17:46
@Fangliding
Copy link
Member

要把它放到基础工具的地位它可能得返回真正的ttl而不是 expire time 不然可能会某个域名的查询会被集中到某个时间点而不是更健康的分散开(当然一般遇不到)
而且这个dns模块一直是土质级别 我还记得老文档里提了这个DNS功能很简单要更高级的逻辑请考虑其他软件 除了这PR里的AAAA的expire会覆盖A的 一个域名回5个IP有5个TTL xray里的是expire time是用的最后一个record里的TTL

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 21, 2025

要把它放到基础工具的地位它可能得返回真正的ttl而不是 expire time 不然可能会某个域名的查询会被集中到某个时间点而不是更健康的分散开(当然一般遇不到) 而且这个dns模块一直是土质级别 我还记得老文档里提了这个DNS功能很简单要更高级的逻辑请考虑其他软件 除了这PR里的AAAA的expire会覆盖A的 一个域名回5个IP有5个TTL xray里的是expire time是用的最后一个record里的TTL

作为递归DNS,本就应当返回过期时间作为TTL,这是标准
这个PR问题在于所有IP返回一样的expire time,但Xray确实是这样管理所有IP的有效期的,因此就应当这样返回
除非再开一个新的PR,让Xray基于每个IP而不是record来管理缓存

至于你说的AAAA覆盖A,我刚又看了下代码,似乎本来就不会同时返回A+AAAA
proxy->dns->dns.go->handleIPQuery

@Fangliding
Copy link
Member

DNS出站的不会 但是如果传进去的querystrategy不是单的会返回AAAA的expire
要是都觉得没问题那就这样吧 小改动没啥好再review的了

@RPRX
Copy link
Member

RPRX commented Mar 21, 2025

@Fangliding 要不你再看看,我是觉得动了 24 个文件,review 起来有点麻烦

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 21, 2025

DNS出站的不会 但是如果传进去的querystrategy不是单的会返回AAAA的expire 要是都觉得没问题那就这样吧 小改动没啥好再review的了

好了,4和6现在各自独立的ttl 不完美但够用,至少dig的46 ttl是分开的

@Fangliding
Copy link
Member

没必要啊我说了DNS出站那样可以用 这是你写的吗 你之前说的可以取消注释的那段代码怎么还给删了

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 21, 2025

考虑到用户或许配了UseIP,既然4和6的ttl不一样索性拆了,大不了再回滚这个提交
无所谓,你决定,反正我只用4

想让46的ttl真正各自独立,要动的地方太多了,那还不如直接实现各ip独立的expire,总之现在够用


那段注释掉的代码是 @yuhan6665 去年 commit a0f1e1f
此PR的app/dns/nameserver_fakedns.go 第43行 应该能代替它

之前注释掉,没直接删是因为没用过FakeDNS,拿不准
既然要让yuhan来看了索性删了先 反正他兜底

@KobeArthurScofield
Copy link
Contributor

KobeArthurScofield commented Mar 22, 2025

FakeDNS TTL 返回 1 之前有讨论过,是在手机上面或者透明代理下面用 FakeDNS 时,Xray 被关闭/重启会导致下挂的设备在拿到的 FakeIP 过期之前上不了网,设为 1 的话可以尽量降低问题影响(大概只有 1 秒)(一些 DNS 缓存比较奇葩的应用除外不过也的确没必要为这种情况擦屁股)。只不过手机在 VPN 服务变化的时候会向其它应用发送 flag 所以影响不太大,透明代理没有这种机制问题才大。FakeIP 映射记录在 Xray 运行期间只要 Pool 没满基本都会在内存里面。

FakeDNS 是用另一种方式记录请求域名,因为透明代理主要还是有 DNS 查询和实际请求 IP 映射多对多,分流时多少会受限(用黑名单非常麻烦),加上 *ray 一开始只考虑了 HTTP 上网场景,于是 sniffer 只有 HTTP 和 TLS SNI (最近才加入 QUIC SNI),遇到别的协议要用域名分流就不太方便(以及应用用了 domain-fronting 也会在这时出现意外情况)。另外也可以顺便降低因为查询海外 DNS 引入的所需等待时间。

(我要测也麻烦,因为我这 FakeDNS 是在手机上面用的,测试还得编译个 v2rayNG)

Copy link
Member

@yuhan6665 yuhan6665 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看了一下没啥问题 风扇说的有道理 parseResponse 这块将来应该改成每个 IP(Answer) 对应一个 ttl
测试好像坏了。。

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 23, 2025

d2f10b两天前我那边跑三个都是好的

这边的test三个炸俩很没道理

我看了下日志似乎跟EDNS请求长度有关

HEAD is now at bb0ca6f Merge d2f10db into 532261d

似乎是RPRX前几天搞EDNS的问题

2025-03-23T13:53:23.7080900Z 2025/03/23 13:53:18.665998 [Error] app/dns: failed to retrieve response for google.com. > DOH server returned code 413
2025-03-23T13:53:23.7082016Z --- FAIL: TestDOHNameServerWithIPv4Override (5.00s)

2025-03-23T13:52:35.2761860Z 2025/03/23 13:52:29.883389 [Error] app/dns: failed to retrieve response for google.com. > DOH server returned code 413
2025-03-23T13:52:35.2762290Z --- FAIL: TestDOHNameServerWithIPv6Override (5.00s)

@Meo597
Copy link
Collaborator Author

Meo597 commented Mar 23, 2025

破案了,当时我commit d2f10b的时候这边的main不稳定,当时RPRX正在弄EDNS
我那边刚跑了一下这个commit 没毛病 https://github.com/Meo597/Xray-core/actions/runs/13999414918
要我rebase一下还是?

@yuhan6665
Copy link
Member

rebase 或者 merge 都行

@RPRX RPRX merged commit 4afe2d0 into XTLS:main Mar 24, 2025
35 checks passed
@RPRX
Copy link
Member

RPRX commented Mar 24, 2025

既然 @yuhan6665 approve 了那就先合了,感谢 PR

@Meo597 Meo597 deleted the dns-ttl branch April 5, 2025 14:38
maoxikun pushed a commit to maoxikun/Xray-core that referenced this pull request Aug 23, 2025
it2konst pushed a commit to it2konst/gametunnel-core that referenced this pull request Mar 1, 2026
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.

功能请求:DNS响应应包含正确的TTL

5 participants