systemd-resolved を利用している Ubuntu では初期設定では dig +trace が機能しない件のメモ

Ubuntu 18.04 で dig+trace オプションが, server を指定しないと機能しなくてはまったので, メモを残します。

TL;DR

  • Ubuntu 16.10 くらいから systemd-resolved がスタブリゾルバとして採用されている
    • これに伴い /etc/resolv.confnameserver のデフォルト値が 127.0.0.53 になった
    • このとき, dig+trace は利用できないが dig@ で他のフルリゾルバを明示的に指定してあげると動く

何が起きたか: Ubuntu 18.04 で dig +trace が機能しない

以前の記事, dig コマンドで名前解決が再帰的に行われる様子を確認する では, dig+trace オプションを使って, ルートサーバから順に再帰的に名前解決が行われる様子を確認しました。
最近 DNS を体系的に勉強し直して, 改めて dig コマンドを +trace オプションと共に使用したところ, 以下のようなレスポンスが返ってきました。

kangetsu@ubuntu18:~
$ dig www.google.com +trace

; <<>> DiG 9.11.3-1ubuntu1.13-Ubuntu <<>> www.google.com +trace
;; global options: +cmd
;; Received 51 bytes from 127.0.0.53#53(127.0.0.53) in 0 ms

kangetsu@ubuntu18:~

以前と異なり, 結果が返ってきません。+trace を外して試してみます。

kangetsu@ubuntu18:~
$ dig www.google.com

; <<>> DiG 9.11.3-1ubuntu1.13-Ubuntu <<>> www.google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31929
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
www.google.com.         93      IN      A       216.58.197.164

;; Query time: 8 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sun Jan 03 09:11:13 UTC 2021
;; MSG SIZE  rcvd: 59

kangetsu@ubuntu18:~

ちゃんと A レコードが返ってきました。

色々調べていると, 以前の記事では Ubuntu 16.04 を使っており, Ubuntu 18.04 とは /etc/resolv.conf の内容が異なっていました。

  • 16.04
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 192.168.3.1
  • 18.04
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "systemd-resolve --status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0

man 5 resolv.conf によると, nameserver はリゾルバがクエリを送るネームサーバを記述する箇所です。

[...]
       nameserver Name server IP address
              Internet address of a name server that the resolver should query, either an IPv4 address (in dot notation), or an IPv6 address in colon (and possibly dot) notation as per RFC  2373.
              Up  to MAXNS (currently 3, see <resolv.h>) name servers may be listed, one per keyword.  If there are multiple servers, the resolver library queries them in the order listed.  If no
              nameserver entries are present, the default is to use the name server on the local machine.  (The algorithm used is to try a name server, and if the query times out, try  the  next,
              until out of name servers, then repeat trying all the name servers until a maximum number of retries are made.)
[...]

ただ, DNS 周りは用語の統一があまりされておらず*1, ここで言っている nameserver がネームサーバ (権威サーバ/コンテンツサーバ) なのか, フルリゾルバ (DNS キャッシュサーバ) なのか, 非常に混乱したのですが, JPRS の 2003年の資料 など見る限りフルリゾルバで合ってそうです。
直感的にも, スタブリゾルバであるクライアントがクエリを送る先 = 名前解決要求を送る先だから, フルリゾルバなら納得感があります。

ちなみに JPRS は日本の .jp TLD を管理するレジストリです, レジストリ・レジストラについては次の記事で具体例を紹介しています。 https://www.kangetsu121.work/entry/2021/01/01/233451

脱線しましたが, フルリゾルバとして 127.0.0.53 (ローカルホスト) が指定されていることが影響していそうです。
dig では @ の後に IP アドレスなどを続けることで, 名前解決要求を送るサーバを指定できるので, ここに Ubunutu 16.04 の resolv.conf に記載されている IP アドレスを指定してみます。

kangetsu@ubuntu18:~
$ dig www.google.com A @192.168.3.1 +trace

; <<>> DiG 9.11.3-1ubuntu1.13-Ubuntu <<>> www.google.com A @192.168.3.1 +trace
;; global options: +cmd
.                       343328  IN      NS      e.root-servers.net.
.                       343328  IN      NS      d.root-servers.net.
.                       343328  IN      NS      g.root-servers.net.
.                       343328  IN      NS      j.root-servers.net.
.                       343328  IN      NS      i.root-servers.net.
.                       343328  IN      NS      k.root-servers.net.
.                       343328  IN      NS      a.root-servers.net.
.                       343328  IN      NS      m.root-servers.net.
.                       343328  IN      NS      f.root-servers.net.
.                       343328  IN      NS      c.root-servers.net.
.                       343328  IN      NS      h.root-servers.net.
.                       343328  IN      NS      l.root-servers.net.
.                       343328  IN      NS      b.root-servers.net.
.                       516960  IN      RRSIG   NS 8 0 518400 20210116050000 20210103040000 42351 . dRIVLaDX3M964hn9zstRtLGSgHeoqdSl/gygnEIdZdDeW0nykd5T+IGN bpr35G8oHBKC9nk8r4WpxxhVxAcLYNnv3zH+1a+se2/NlRSnFSdCtJjj GB0PJSijEpznqtPdBCZaoPjJ/B7VeDLn1MSrcNhiJw5ZzozFOJc6oiRJ va76X5H3lUlz6qZhLW+Zq+qt63eOe67QNwuEP0qYYxDhBcNTWyaN48rp hzGkNqAZcxtL498Dl4cFV/7OlM5kyDqVMKcMYgfRIbI8ZprO64reGFbu 9Ta6Xteb+0ojYST/SU+jeRSixdBthyi3zrJNBGkbEQlrBKQgpoup2uTh 8pcHCw==
;; Received 1097 bytes from 192.168.3.1#53(192.168.3.1) in 12 ms

com.                    172800  IN      NS      l.gtld-servers.net.
com.                    172800  IN      NS      b.gtld-servers.net.
com.                    172800  IN      NS      c.gtld-servers.net.
com.                    172800  IN      NS      d.gtld-servers.net.
com.                    172800  IN      NS      e.gtld-servers.net.
com.                    172800  IN      NS      f.gtld-servers.net.
com.                    172800  IN      NS      g.gtld-servers.net.
com.                    172800  IN      NS      a.gtld-servers.net.
com.                    172800  IN      NS      h.gtld-servers.net.
com.                    172800  IN      NS      i.gtld-servers.net.
com.                    172800  IN      NS      j.gtld-servers.net.
com.                    172800  IN      NS      k.gtld-servers.net.
com.                    172800  IN      NS      m.gtld-servers.net.
com.                    86400   IN      DS      30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766
com.                    86400   IN      RRSIG   DS 8 1 86400 20210116050000 20210103040000 42351 . HhNsG1f41O3quXsdkzVJdvxPO9/1mf/FIbv8NE68B9m/UuRhhr6aGhbn Z8IOKvd5R8EomZSgW+Bwwo9eA1+DrzESwOeANCZpQ2rMXQAw+J6tgiP2 SztHe8s8ZU5ckPE+kzgfiJ4H0HgrmN6C3xI29JTVPrX73y8sTSZeFqvb 3wvmzxmLsR0MW1H5X8BRbIROWDUvh0mD4IYDkXtyRKtKL1UDM0v50/v4 BDdzV4VlDbKg1DHlDu3tR7QUhYSQxzekgCGfCvZ84yb3FFLRoplYcCHE qrQrO7hXB1O0SoEpaxovSzb1l1Z9T80KikiFHIZGtT4NkP1k4A4W0fGg SIlggw==
;; Received 1174 bytes from 192.5.5.241#53(f.root-servers.net) in 6 ms

google.com.             172800  IN      NS      ns2.google.com.
google.com.             172800  IN      NS      ns1.google.com.
google.com.             172800  IN      NS      ns3.google.com.
google.com.             172800  IN      NS      ns4.google.com.
CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - CK0Q1GIN43N1ARRC9OSM6QPQR81H5M9A  NS SOA RRSIG DNSKEY NSEC3PARAM
CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20210109045959 20210102034959 31510 com. jaAhMvqXepGlEp5eDn/sqwz9aDzpYyTxq8/upGZoMF4xG+r+zgcP3fVz LvNHVgkd45Ow5nT+saz+Ay+n+YE64jlY41ld/JVlBQZvDV1FKjyIRjVM chujmUc4T6fIBfXvDHFLIl2cZ0yvO4OwtAL0Ii0D5xhoIJwUWxxNo4kQ maeEHfTFVLrLlwgrdbm6zNpmXAOlOcr9P6cs8QvWuHUuWg==
S84BDVKNH5AGDSI7F5J0O3NPRHU0G7JQ.com. 86400 IN NSEC3 1 1 0 - S84CDVS9VPREADFD6KK7PDADH0M6IO8H  NS DS RRSIG
S84BDVKNH5AGDSI7F5J0O3NPRHU0G7JQ.com. 86400 IN RRSIG NSEC3 8 2 86400 20210109130004 20210102115004 31510 com. GDgkLbhWPJNCxdDcDKZRMcMh8TgEiTYuFmsX6cfpr7jpsdPT8neSmDKR 8fI4TnLl7ERhm5xRuKGEjgNsnz/8HNEFoXK/M7ES3RCPoYtYjbNj+k1Q 6kryy9nKNSiisYxg3dj8E2RwVZ2rZGOrNGPSi1yP2jx22qrswUAy1OqZ LNU+WNtgmB1SKL5f7JSt+lxzZrkduhSW8JGsArOOWF44XQ==
;; Received 840 bytes from 192.55.83.30#53(m.gtld-servers.net) in 8 ms

www.google.com.         300     IN      A       172.217.26.4
;; Received 59 bytes from 216.239.36.10#53(ns3.google.com) in 156 ms

kangetsu@ubuntu18:~

この通り, その他の設定は変えていませんが, Ubuntu 18.04 でも +trace が機能しました。

/etc/resolv.conf の変化はいつ入ったか

上記のような変更がいつ, なぜ入ったかについては, 以下の記事にて解説されていましたのでご参照ください。
https://kledgeb.blogspot.com/2016/06/ubuntu-1610-7-dnssystemd-resolved.html

systemd の issue での議論: 仕様だった

どうすれば動くかは分かったけど理屈はわからず, Web をさまよっていたら次の issue を見つけました。

https://github.com/systemd/systemd/issues/5897

一部引用します。

https://github.com/systemd/systemd/issues/5897#issue-226688715

... When the configured nameserver is systemd-resolved’s 127.0.0.53, systemd-resolved refuses this query.

$ dig +norecurse . NS ... Therefore, dig +trace does not work. ...

https://github.com/systemd/systemd/issues/5897#issuecomment-300238951

This is really by design. The DNS stub in resolved is not supposed to be a full DNS server. All it shall be able to do is reply to simply local lookups, i.e. RD lookups done by nss-dns or similar local implementations.

resolved is not a DNS server, and it's not going to become one. Sorry!

このように, systemd-resolved の仕様のようでした。
この後も discussion は続いていますが, 当分改修されることはなさそうです。

dig +trace を使いたい場合は, @ で nameserver を指定する必要があるようです。

おまけ

上では Ubuntu 16.04 の /etc/resolv.conf からフルリゾルバの IP アドレスを持ってきましたが, systemd-resolv --status から参照できます。
一番下の DNS Servers の IP アドレスが, 上で指定したものと一致しています。

$ systemd-resolve --status
Global
          DNSSEC NTA: 10.in-addr.arpa
                      16.172.in-addr.arpa
                      168.192.in-addr.arpa
                      17.172.in-addr.arpa
                      18.172.in-addr.arpa
                      19.172.in-addr.arpa
                      20.172.in-addr.arpa
                      21.172.in-addr.arpa
                      22.172.in-addr.arpa
                      23.172.in-addr.arpa
                      24.172.in-addr.arpa
                      25.172.in-addr.arpa
                      26.172.in-addr.arpa
                      27.172.in-addr.arpa
                      28.172.in-addr.arpa
                      29.172.in-addr.arpa
                      30.172.in-addr.arpa
                      31.172.in-addr.arpa
                      corp
                      d.f.ip6.arpa
                      home
                      internal
                      intranet
                      lan
                      local
                      private
                      test

Link 3 (enp0s8)
      Current Scopes: none
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no

Link 2 (enp0s3)
      Current Scopes: DNS
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no
         DNS Servers: 192.168.3.1

今回は細かい理屈までは追い切れず消化不良ですが, いずれちゃんと調べておきたいです。

*1:RFC 8499 で用語の統一が提案されてはいます