Skip to content
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

由于UDP DNS响应长度超过512B进行截取导致某些域名无法获取IP信息 #1448

Closed
4 tasks done
yvvw opened this issue Feb 6, 2024 · 11 comments
Closed
4 tasks done
Labels

Comments

@yvvw
Copy link

yvvw commented Feb 6, 2024

Operating system

Linux

System version

openwrt 23.05

Installation type

Original sing-box Command Line

If you are using a graphical client, please provide the version of the client.

No response

Version

sing-box version 1.8.5

Environment: go1.21.6 linux/arm64
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_ech,with_utls,with_reality_server,with_acme,with_clash_api
Revision: b27bc45cf2550e00823e799a313f8226443aa58e
CGO: disabled

Description

17aebc5cn-beijing-data.aliyundrive.net 这类响应超出 512B 的域名进行修复后,又出现 api.aliyundrive.com 连续AAAA记录,最后一个A类记录IP信息,由于sing-box DNS响应没有进行压缩,导致这类地址被截断后拿不到ip信息。我猜测压缩会影响处理性能,但又觉得能正确处理更重要些,是否可以在超出限制的情况下尝试压缩再去截取那。

$ nslookup api.aliyundrive.com
Server:         127.0.0.1
Address:        127.0.0.1:53

Non-authoritative answer:

Non-authoritative answer:
api.aliyundrive.com     canonical name = beijing.tfe.alibaba-clould.alibabacorp.com
beijing.tfe.alibaba-clould.alibabacorp.com      canonical name = beijing.tfe.alibaba-clould.alibabacorp.com.gds.alibabadns.com
beijing.tfe.alibaba-clould.alibabacorp.com.gds.alibabadns.com   canonical name = bj-static.tfe.alibaba-clould.alibabacorp.com
bj-static.tfe.alibaba-clould.alibabacorp.com    canonical name = bj-static.tfe.alibaba-clould.alibabacorp.com.gds.alibabadns.com

$ curl api.aliyundrive.com
curl: (6) Could not resolve host: api.aliyundrive.com
diff --git a/outbound/dns.go b/outbound/dns.go
index 0f003377..529c796c 100644
--- a/outbound/dns.go
+++ b/outbound/dns.go
@@ -241,7 +241,7 @@ func (d *DNS) newPacketConnection(ctx context.Context, conn N.PacketConn, readWa
                                        return err
                                }
                                timeout.Update()
-                               response = truncateDNSMessage(response, 512) // TODO: add an option to custom UDP buffer size
+                               response = compressAndTruncateDNSMessage(response, 512) // TODO: add an option to custom UDP buffer size
                                responseBuffer := buf.NewSize(dns.FixedPacketSize)
                                responseBuffer.Resize(1024, 0)
                                n, err := response.PackBuffer(responseBuffer.FreeBytes())
@@ -265,12 +265,17 @@ func (d *DNS) newPacketConnection(ctx context.Context, conn N.PacketConn, readWa
        return group.Run(fastClose)
 }

-func truncateDNSMessage(response *mDNS.Msg, maxLen int) *mDNS.Msg {
+func compressAndTruncateDNSMessage(response *mDNS.Msg, maxLen int) *mDNS.Msg {
        responseLen := response.Len()
        if responseLen <= maxLen {
                return response
        }
        response = response.Copy()
+       response.Compress = true
+       responseLen = response.Len()
+       if responseLen <= maxLen {
+               return response
+       }
        for len(response.Answer) > 0 && responseLen > maxLen {
                response.Answer = response.Answer[:len(response.Answer)-1]
                response.Truncated = true

Reproduction

如上

Logs

No response

Integrity requirements

  • I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
  • I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
  • I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
  • I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.
@mm11253
Copy link

mm11253 commented Feb 24, 2024

最近遇到了一点问题 xiaorouji/openwrt-passwall#2960
我比较好奇的是,为什么 Sing-Box DNS 的响应会比 dns2tcp/Xray DNS 大很多?

Sing-Box DNS

root@OpenWrt:~# dig www.youtube.com -p 15353
;; Truncated, retrying in TCP mode.

; <<>> DiG 9.18.24 <<>> www.youtube.com -p 15353
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48655
;; flags: qr rd ra; QUERY: 1, ANSWER: 17, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; MBZ: 0x0072, udp: 1232
;; QUESTION SECTION:
;www.youtube.com.		IN	A

;; ANSWER SECTION:
www.youtube.com.	114	IN	CNAME	youtube-ui.l.google.com.
youtube-ui.l.google.com. 114	IN	A	172.217.25.14
youtube-ui.l.google.com. 114	IN	A	142.250.66.46
youtube-ui.l.google.com. 114	IN	A	142.250.66.110
youtube-ui.l.google.com. 114	IN	A	142.250.204.110
youtube-ui.l.google.com. 114	IN	A	142.250.66.78
youtube-ui.l.google.com. 114	IN	A	142.250.207.78
youtube-ui.l.google.com. 114	IN	A	172.217.24.238
youtube-ui.l.google.com. 114	IN	A	142.250.204.46
youtube-ui.l.google.com. 114	IN	A	172.217.27.46
youtube-ui.l.google.com. 114	IN	A	172.217.24.110
youtube-ui.l.google.com. 114	IN	A	142.250.204.78
youtube-ui.l.google.com. 114	IN	A	142.250.199.78
youtube-ui.l.google.com. 114	IN	A	142.251.222.206
youtube-ui.l.google.com. 114	IN	A	142.250.66.142
youtube-ui.l.google.com. 114	IN	A	172.217.31.14
youtube-ui.l.google.com. 114	IN	A	172.217.27.14

;; Query time: 29 msec
;; SERVER: 127.0.0.1#15353(127.0.0.1) (TCP)
;; WHEN: Sat Feb 24 02:05:13 CST 2024
;; MSG SIZE  rcvd: 720

dns2tcp

root@OpenWrt:~# dig www.youtube.com -p 15353

; <<>> DiG 9.18.24 <<>> www.youtube.com -p 15353
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7423
;; flags: qr rd ra; QUERY: 1, ANSWER: 17, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.youtube.com.		IN	A

;; ANSWER SECTION:
www.youtube.com.	86	IN	CNAME	youtube-ui.l.google.com.
youtube-ui.l.google.com. 86	IN	A	142.250.204.142
youtube-ui.l.google.com. 86	IN	A	142.250.204.46
youtube-ui.l.google.com. 86	IN	A	172.217.24.78
youtube-ui.l.google.com. 86	IN	A	142.250.204.78
youtube-ui.l.google.com. 86	IN	A	216.58.200.238
youtube-ui.l.google.com. 86	IN	A	172.217.27.46
youtube-ui.l.google.com. 86	IN	A	142.250.204.110
youtube-ui.l.google.com. 86	IN	A	142.251.220.46
youtube-ui.l.google.com. 86	IN	A	172.217.31.14
youtube-ui.l.google.com. 86	IN	A	172.217.25.14
youtube-ui.l.google.com. 86	IN	A	172.217.24.238
youtube-ui.l.google.com. 86	IN	A	172.217.27.14
youtube-ui.l.google.com. 86	IN	A	172.217.24.110
youtube-ui.l.google.com. 86	IN	A	216.58.203.78
youtube-ui.l.google.com. 86	IN	A	142.251.220.14
youtube-ui.l.google.com. 86	IN	A	142.250.199.78

;; Query time: 59 msec
;; SERVER: 127.0.0.1#15353(127.0.0.1) (UDP)
;; WHEN: Sat Feb 24 02:17:57 CST 2024
;; MSG SIZE  rcvd: 334

Xray DNS

root@OpenWrt:~# dig www.youtube.com -p 15353

; <<>> DiG 9.18.24 <<>> www.youtube.com -p 15353
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13693
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 16, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.youtube.com.		IN	A

;; ANSWER SECTION:
www.youtube.com.	600	IN	A	142.250.199.78
www.youtube.com.	600	IN	A	172.217.24.238
www.youtube.com.	600	IN	A	172.217.24.78
www.youtube.com.	600	IN	A	142.250.204.110
www.youtube.com.	600	IN	A	142.250.204.46
www.youtube.com.	600	IN	A	142.250.207.78
www.youtube.com.	600	IN	A	142.250.204.78
www.youtube.com.	600	IN	A	172.217.27.46
www.youtube.com.	600	IN	A	172.217.31.14
www.youtube.com.	600	IN	A	142.250.204.142
www.youtube.com.	600	IN	A	172.217.24.110
www.youtube.com.	600	IN	A	216.58.200.238
www.youtube.com.	600	IN	A	172.217.25.14
www.youtube.com.	600	IN	A	216.58.203.78
www.youtube.com.	600	IN	A	172.217.27.14
www.youtube.com.	600	IN	A	142.250.66.142

;; Query time: 0 msec
;; SERVER: 127.0.0.1#15353(127.0.0.1) (UDP)
;; WHEN: Sat Feb 24 14:46:15 CST 2024
;; MSG SIZE  rcvd: 289

@yvvw
Copy link
Author

yvvw commented Feb 24, 2024

@mm11253 sing-box没有对dns响应体进行压缩,可能出于性能考虑,目前还没选项进行设置,还在等开发者回复 #1442

@mm11253
Copy link

mm11253 commented Feb 24, 2024

@mm11253 sing-box没有对dns响应体进行压缩,可能出于性能考虑,目前还没选项进行设置,还在等开发者回复 #1442

引用隔壁 ChinaDNS-NG 作者的回复 zfl9/chinadns-ng#144 (comment)

拒绝连接是因为 chinadns-ng 目前还没实施 tcp 监听。用 zig 重写的 1.0/2.0 版本已经加入 tcp 支持了。

结合你引用的几个 issue 推测,有这几方面的原因:

  1. 上游未遵循 EDNS 的 udp bufsz 扩展信息,你给出的示例显示 dig 的 bufsz 是 1232 字节,即使超过 512 字节的响应,也不应该设置 TC 标志,因为实际缓冲区大小是 1232 字节,并不会“截断”
  2. 上游未实施 DNS 域名压缩导致响应消息比较大,容易超出传统的 512 字节限制,而又由于第 1 条原因,导致很多“不必要的截断,然后通过 TCP 重试”的行为
  3. chinadns-ng 目前尚未支持 TCP 监听/上游,导致 dig(查询客户端)在收到带 TC 标志的udp响应后,通过 tcp 重试查询时,未能连接上 chinadns-ng,于是出现连接被拒,查询超时。

@mm11253
Copy link

mm11253 commented Feb 24, 2024

所以压缩还是有必要的吧

@mm11253
Copy link

mm11253 commented Feb 24, 2024

Still in Todo.

response = truncateDNSMessage(response, 512) // TODO: add an option to custom UDP buffer size

https://www.rfc-editor.org/rfc/rfc2671 https://www.rfc-editor.org/rfc/rfc1035

I gotcha, but I reckon compressing the response takes precedence over customizing the UDP buffer size.

@nekohasekai
Copy link
Member

应已在最新版本修复。

@lux5am
Copy link

lux5am commented Feb 29, 2024

Most DNS related issues had been fixed. but DNS response still not compressed by default?
Even when the request buffer size larger than 512 bytes it should try to get the response under 512 bytes. The 512 bytes guarantees the DNS packets can be reassembled if fragmented in the transit.

The first one from dnsmasq which is also hijacked by singbox.

root@sam46:~# kdig www.youtube.com
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 43430
;; Flags: qr rd ra; QUERY: 1; ANSWER: 17; AUTHORITY: 0; ADDITIONAL: 0

;; QUESTION SECTION:
;; www.youtube.com.             IN      A

;; ANSWER SECTION:
www.youtube.com.        1794    IN      CNAME   youtube-ui.l.google.com.
youtube-ui.l.google.com.        1794    IN      A       64.233.170.93
youtube-ui.l.google.com.        1794    IN      A       64.233.170.190
youtube-ui.l.google.com.        1794    IN      A       142.251.175.190
youtube-ui.l.google.com.        1794    IN      A       142.251.175.91
youtube-ui.l.google.com.        1794    IN      A       142.251.175.136
youtube-ui.l.google.com.        1794    IN      A       142.251.175.93
youtube-ui.l.google.com.        1794    IN      A       74.125.24.190
youtube-ui.l.google.com.        1794    IN      A       74.125.24.93
youtube-ui.l.google.com.        1794    IN      A       74.125.24.136
youtube-ui.l.google.com.        1794    IN      A       74.125.130.136
youtube-ui.l.google.com.        1794    IN      A       74.125.68.136
youtube-ui.l.google.com.        1794    IN      A       74.125.68.190
youtube-ui.l.google.com.        1794    IN      A       74.125.68.93
youtube-ui.l.google.com.        1794    IN      A       74.125.68.91
youtube-ui.l.google.com.        1794    IN      A       64.233.170.91
youtube-ui.l.google.com.        1794    IN      A       64.233.170.136

;; Received 326 B
;; Time 2024-02-29 17:41:50 WITA
;; From 127.0.0.1@53(UDP) in 0.6 ms
root@sam46:~# kdig www.youtube.com @1.1.1.1
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 23934
;; Flags: qr rd ra; QUERY: 1; ANSWER: 17; AUTHORITY: 0; ADDITIONAL: 0

;; QUESTION SECTION:
;; www.youtube.com.             IN      A

;; ANSWER SECTION:
www.youtube.com.        300     IN      CNAME   youtube-ui.l.google.com.
youtube-ui.l.google.com.        300     IN      A       64.233.170.91
youtube-ui.l.google.com.        300     IN      A       64.233.170.136
youtube-ui.l.google.com.        300     IN      A       64.233.170.93
youtube-ui.l.google.com.        300     IN      A       64.233.170.190
youtube-ui.l.google.com.        300     IN      A       142.251.175.190
youtube-ui.l.google.com.        300     IN      A       142.251.175.91
youtube-ui.l.google.com.        300     IN      A       142.251.175.136
youtube-ui.l.google.com.        300     IN      A       142.251.175.93
youtube-ui.l.google.com.        300     IN      A       74.125.24.190
youtube-ui.l.google.com.        300     IN      A       74.125.24.93
youtube-ui.l.google.com.        300     IN      A       74.125.24.136
youtube-ui.l.google.com.        300     IN      A       74.125.130.136
youtube-ui.l.google.com.        300     IN      A       74.125.68.136
youtube-ui.l.google.com.        300     IN      A       74.125.68.190
youtube-ui.l.google.com.        300     IN      A       74.125.68.93
youtube-ui.l.google.com.        300     IN      A       74.125.68.91

;; Received 709 B
;; Time 2024-02-29 17:41:57 WITA
;; From 1.1.1.1@53(UDP) in 150.9 ms

@lux5am
Copy link

lux5am commented Mar 1, 2024

Looking at popular DNS solution like blocky and adguardhome it force enable compression.
Maybe we should follow that?

diff --git a/client_truncate.go b/client_truncate.go
index a0b4afd..90cf3dd 100644
--- a/client_truncate.go
+++ b/client_truncate.go
@@ -14,6 +14,7 @@ func TruncateDNSMessage(request *dns.Msg, response *dns.Msg, frontHeadroom int)
                }
        }
        response.Truncate(maxLen)
+       response.Compress = true
        buffer := buf.NewSize(frontHeadroom + 1 + maxLen)
        buffer.Resize(frontHeadroom, 0)
        rawMessage, err := response.PackBuffer(buffer.FreeBytes())

https://github.com/0xERR0R/blocky/blob/efc14d25ca57dbc0652d4e9784ba2e61646caeaa/server/server.go#L652
Screenshot_20240301-093309_Kiwi Browser

https://github.com/AdguardTeam/dnsproxy/blob/68d417bfdc10e87e5d268aca3bd055e9fd88d206/proxy/dnscontext.go#L128
Screenshot_20240301-093403_Kiwi Browser

https://github.com/XTLS/Xray-core/blob/8fe8aa5432d6f14f62aaecd57d7f35fda04d5c0e/proxy/dns/dns.go#L276

https://github.com/MetaCubeX/mihomo/blob/7eb16a098a92e43c4a8871c0103d670462252bbc/dns/server.go#L35

@InspoOnU
Copy link

这种情况不是应该用TCP重传吗?为啥要改UDP响应?

Copy link

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days

@github-actions github-actions bot added the Stale label Jun 13, 2024
@yvvw yvvw closed this as completed Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants