问题:Google 的公共 DNS 为某些 SLD 返回 NXDOMAIN。
问题证明:
dig vpn.example.com @8.8.8.8
; \<\<\>\> DiG 9.11.5-P4-5.1+deb10u8-Debian \<\<\>\> vpn.example.com @8.8.8.8
; global options: +cmd
; Got answer:
;; -\>\>HEADER\<\<- opcode: QUERY, status: NXDOMAIN, id: 8324
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;vpn.example.com. IN A
;; AUTHORITY SECTION:
example.com. 1800 IN SOA ns1.example.com. root.example.com. 1675851775 28800 7200 604800 86400
;; Query time: 134 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Feb 09 09:52:06 EET 2023
;; MSG SIZE rcvd: 93
如您所见,查询状态为 NXDOMAIN。但是,询问 AUTHORITY 部分中列出的权威 DNS 服务器,会得到正确的答案:
dig vpn.example.com @ns1.example.com
; \<\<\>\> DiG 9.11.5-P4-5.1+deb10u8-Debian \<\<\>\> vpn.example.com @ns1.example.com**
;; global options: +cmd
;; Got answer:
;; -\>\>HEADER\<\<- opcode: QUERY, status: **NOERROR**, id: 37073
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 600
;; QUESTION SECTION:
;vpn.example.com. IN A
;; ANSWER SECTION:
vpn.example.com. 3600 IN A XXX.XX.X.XXX
;; Query time: 128 msec
;; SERVER: XXX.XX.XX.XXX#53(XXX.XX.XX.XXX)
;; WHEN: Thu Feb 09 09:58:05 EET 2023
;; MSG SIZE rcvd: 64
其他公共 DNS 服务器(opendns、cloudflare 等)均可解析 SLD。
权威DNS服务器(所有4条NS记录)的响应一致:
for i in $(seq 1 30)
do
query=$(dig +short us1.vpn.example.com @ns1.example.com)
if [[ -z "$query" ]]
then echo "NO ANSWER"
else
echo "ANSWER"
fi
sleep 2
done | sort | uniq -c
30 回答
我在两个不同的选项卡中尝试了以下操作:
TAB1 客户端//
while true; do dig +short vpn.example.com @8.8.8.8; sleep 1; done
TAB2 dns 服务器端//
tcpdump -vvvvv -w /tmp/dns.pcap udp and port 53
TAB2 dns 服务器端//
tcpdump -n -t -r /tmp/dns.pcap | grep vpn
并尝试辨别此处列出的子网的任何 IP:https://developers.google.com/speed/public-dns/faq#locations_of_ip_address_ranges_google_public_dns_uses_to_send_queries
未找到该特定主机的任何内容。我该如何进一步调试?感谢您提出的任何建议!
答案1
权威DNS服务器(所有4条NS记录)的响应一致:
不是。服务器ns1.exmaple.com
偶尔会在返回此名称的 A 记录和返回 NXDOMAIN 之间切换。(似乎使用 通过 TCP 进行查询dig +vc
是一种可靠的方法,可以使其开始通过两种协议使用 NXDOMAIN 进行响应。)
$ dig vpn.example.com @ns1.example.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24350
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
$ dig +vc vpn.example.com @ns1.example.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 63787
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
$ dig vpn.example.com @ns1.example.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 10815
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
在这种情况下,缓存不一致是正常的(正如 Tomek 所见),因为 Google DNS 不仅仅是全球性的任播——每个位置都有自己的多个解析器,并在负载平衡器后面有独立的缓存,因此即使您看到相同的 NSID,您每次仍会从不同的后端服务器获得回复。(顺便说一句,不要忘记缓存刷新页。)
ns1.example.com
负载均衡器后面的多个服务器可能会以类似的方式处理该问题,其中一些服务器会给出正确的结果,而一些则不会。
答案2
事实证明这是 powerdns 权威服务器的 PIPEBackend 问题。感谢所有参与的人!
答案3
我可以在所有 Google DNS 地址上间歇性地重现它:
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
XXX.XX.X.XXX
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
XXX.XX.X.XXX
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
XXX.XX.X.XXX
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
XXX.XX.X.XXX
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
XXX.XX.X.XXX
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
XXX.XX.X.XXX
triss:~> dig vpn.obfuscated.com @2001:4860:4860::8844 +short
XXX.XX.X.XXX
看起来 Google 存在一些缓存不一致的情况。