Ubuntu 20.04 使用 dnsmasq 解决了等待被拒绝的 IPV6 结果的问题

Ubuntu 20.04 使用 dnsmasq 解决了等待被拒绝的 IPV6 结果的问题

总结

我的 DNS 查询速度很慢,因为 systemd-resolved 成功查询了 IPv4 上的 DNS 服务器,但在 DNS 服务器响应 REFUSED 后,重复查询 IPv6 上的 DNS 服务器。这是已发布的已解决配置吗?是 dnsmasq 问题吗?还是错误?

我有一个 Ubuntu 20.04 的安装版本,连接到 dnsmasq,该版本运行在带有顶级域名“bar”的气隙设备(ubiquity edgerouter)上(记住是气隙的,但似乎并不重要,这是什么——即 .com 等)。DNS 请求通过 Mac 和 Windows 客户端快速解析。对于 Ubuntu,DNS 查询大约需要 5 秒钟才能解析。搜索了一下,Ubuntu DNS 问题在很多地方都有讨论,但我所看到的底层行为并不在我的知识范围内。

顶级问题:如果我使用 ubuntu ping 一台机器,大约需要 5 秒钟才能返回响应:

$ ping foo
# about 5 seconds go by
PING foo.bar (10.2.1.132) 56(84) bytes of data.
64 bytes from foo.bar (10.2.1.132): icmp_seq=1 ttl=63 time=1.10 ms
64 bytes from foo.bar (10.2.1.132): icmp_seq=2 ttl=63 time=1.02 ms
...

这似乎是一个明显的超时问题。有趣的是,它确实解决了。运行后,resolvectl status我得到了标准结果,包括 DNS 由 dnsmasq 颁发的 DHCP 租约提供。

$ resolvectl status

...
lots of stuff
...

Link 3 (enp0s25)
      Current Scopes: DNS     
DefaultRoute setting: yes     
       LLMNR setting: yes     
MulticastDNS setting: no      
  DNSOverTLS setting: no      
      DNSSEC setting: no      
    DNSSEC supported: no      
         DNS Servers: 10.1.1.1
          DNS Domain: ~.      
                      bar

停止已解决的问题并以调试模式运行似乎会显示该问题。ubuntu 计算机通过 IPv4 查询 DNS 服务器,并立即收到答复。然后它通过 IPv6 反复查询,DNS 服务器以 REFUSED 响应,直到超时。

$ sudo systemctl stop systemd-resolved
$ sudo SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-resolved
...
lots of startup logging
...
Got DNS stub UDP query packet for id 40457
Looking up RR for foo.bar IN A.
Switching to DNS server 10.1.1.1 for interface enp0s25.
Cache miss for foo.bar IN A
Transaction 42924 for <foo.bar IN A> scope dns on enp0s25/*.
Using feature level UDP+EDNS0 for transaction 42924.
Using DNS server 10.1.1.1 for transaction 42924.
Sending query packet with id 42924.
Processing query...
Got DNS stub UDP query packet for id 59119
Looking up RR for foo.bar IN AAAA.
Cache miss for foo.bar IN AAAA
Transaction 21734 for <foo.bar IN AAAA> scope dns on enp0s25/*.
Using feature level UDP+EDNS0 for transaction 21734.
Using DNS server 10.1.1.1 for transaction 21734.
Sending query packet with id 21734.
Processing query...
Processing incoming packet on transaction 42924 (rcode=SUCCESS).
Verified we get a response at feature level UDP+EDNS0 from DNS server 10.1.1.1.
Added positive unauthenticated cache entry for foo.bar IN A 7200s on enp0s25/INET/10.1.1.1
Transaction 42924 for <foo.bar IN A> on scope dns on enp0s25/* now complete with <success> from network (unsigned).
Sending response packet with id 40457 on interface 1/AF_INET.
Freeing transaction 42924.
Processing incoming packet on transaction 21734 (rcode=REFUSED).
Server returned REFUSED, switching servers, and retrying.
Retrying transaction 21734.
Cache miss for foo.bar IN AAAA
Transaction 21734 for <foo.bar IN AAAA> scope dns on enp0s25/*.
Using feature level UDP+EDNS0 for transaction 21734.
Sending query packet with id 21734.
Processing incoming packet on transaction 21734 (rcode=REFUSED).
Server returned REFUSED, switching servers, and retrying.
...
repeats for ~5 seconds
...
Transaction 44267 for <foo.bar IN AAAA> on scope dns on enp0s25/* now complete with <attempts-max-reached> from network (unsigned).
Freeing transaction 44267.

也表明这是问题所在:

$ nslookup foo
Server:     127.0.0.53
Address:    127.0.0.53#53

Non-authoritative answer:
Name:   foo.bar
Address: 10.2.1.132
...
about 5 seconds go by
...
;; connection timed out; no servers could be reached

# this returns immediately
$ nslookup -query=A foo
Server:     127.0.0.53
Address:    127.0.0.53#53

Non-authoritative answer:
Name:   foo.bar
Address: 10.2.1.132

# while this times out in about 5 sec.
$ nslookup -query=AAAA foo
;; connection timed out; no servers could be reached

问题:

  1. 如果 DNS 服务器提供了良好的 IPv4 答案,为什么 ubuntu 机器会等待并反复尝试获取 IPv6 答案但失败?

  2. 这是 ubuntu 配置问题还是 dnsmasq 问题?

提前致谢。

答案1

systemd-resolved我在配置时遇到了完全相同的问题dnsmasq

对于您的问题1,我无法找到为什么在没有回复的情况下重复systemd-resolved查询记录。AAAAdnsmasq

对于问题 2,dnsmasq配置不正确,无法为 添加记录foo.bar。您只A为此域名添加了一条记录,同时查询和记录。systemd-resolvedA知道此域的记录,因此它将此查询转发给上游服务器。我不清楚接下来会发生什么,但没有给出预期的答案。AAAAdnsmasqAAAAdnsmasq

您没有提到配置方式dnsmasq。在我的测试中,以下任何配置都将按预期工作。请注意,1 和 2、3 之间存在差异。

  1. address=/foo.bar/10.2.1.132/
  2. local=/bar/addn-hosts=/tmp/hosts并添加10.2.1.132 foo.bar/tmp/hosts
  3. host-record=foo.bar,10.2.1.132local=/bar/

来自dnsmasq手册页的选项--local

还允许使用 -S 标志,它提供域但不提供 IP 地址;这告诉 dnsmasq 一个域是本地的,它可能会回答来自 /etc/hosts 或 DHCP 的查询,但绝不会将该域上的查询转发到任何上游服务器。--local 是 --server 的同义词,在这种情况下使配置文件更清晰。

相关内容