Chapter 07

systemd-resolvedを使ってみよう

koyamaso
koyamaso
2021.04.05に更新

Arch Wikiより引用すると

systemd-resolvedは127.0.0.53のローカルDNSスタブリスナによるネットワーク名前解決をローカルアプリケーションに提供する systemd サービスです。

systemd-resolvedはスタブリゾルバ(DNSクライアント)なので、自身で名前解決は出来ませんが、レスポンスタイムを短縮させるために、様々な工夫がされています。

最近のUbuntuなどではデフォルトで使われています。

$ systemd status systemd-resolved
● systemd-resolved.service - Network Name Resolution
     Loaded: loaded (/usr/lib/systemd/system/systemd-resolved.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2021-03-31 21:23:59 JST; 19min ago
       Docs: man:systemd-resolved.service(8)
             man:org.freedesktop.resolve1(5)
             https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
             https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
   Main PID: 373 (systemd-resolve)
     Status: "Processing requests..."
      Tasks: 1 (limit: 19063)
     Memory: 7.2M
     CGroup: /system.slice/systemd-resolved.service
             └─373 /usr/lib/systemd/systemd-resolved

推奨されている動作モードで動かす

推奨されている動作モードでは、/etc/resolv.confには127.0.0.53のみが記述された状態にし、127.0.0.53:53で動作しているローカルDNSスタブリスナが名前解決を中継します。

systemd-resolvedが参照するネームサーバは、NetworkManagerの設定またはsystemd-networkdの設定から読み取ります。

推奨されている動作モードで動かすには、/etc/resolv.conf/run/systemd/resolve/stub-resolv.confのシンボリックリンクにすればよいです。

これによって、全ての名前解決がsystemd-resolvedを介して行われるようになるため、レスポンスタイムの短縮が期待できます。

$ cat /run/systemd/resolve/stub-resolv.conf 
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8).
# Do not edit.
#
# This file might be symlinked as /etc/resolv.conf. If you're looking at
# /etc/resolv.conf and seeing this text, you have followed the symlink.
#
# 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 "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs should typically 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
$ ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

manページによると、

スタブリスナを使うよりnss-resolveやdbus APIsを使うことが強く推奨されているようです。

Additionally, systemd-resolved provides a local DNS stub listener on IP address 127.0.0.53 on the local loopback interface. Programs issuing DNS requests directly, bypassing any local API may be directed to this stub, in order to connect them to systemd-resolved. Note however that it is strongly recommended that local programs use the glibc NSS or bus APIs instead (as described above), as various network resolution concepts (such as link-local addressing, or LLMNR Unicode domains) cannot be mapped to the unicast DNS protocol.

nss-resolveを使う

nss-resolveはglibc NSSモジュールの一つです。

/etc/nsswitch.confhosts:resolve [!UNAVAIL=return]dnsより前の方に書くと従来のnss dns、つまりスタブリゾルバ経由の名前解決より優先されるようです。

dbus APIsを使う

writing-resolver-clientssd_bus_call_methodを使うサンプルコードがあります。

それ以外のモードで動かす

manページ /etc/resolv.confによると4つのモードがあります。

どうやってレスポンスタイムを短縮させているのか

manページ Protocols and Routingより

  • /etc/hostsに記述があればフルサービスリゾルバに問い合わせずにそれを使う
  • 複数の最適なリゾルバに同時にリクエストを発行し、最も早く応答した結果を返す

今どのリゾルバが優先されているかはresolvectlCurrent DNS Serverで分かります

$ resolvectl
Global
           Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported                                
    resolv.conf mode: stub                                                                          
Fallback DNS Servers: 1.1.1.1 9.9.9.10 8.8.8.8 2606:4700:4700::1111 2620:fe::10 2001:4860:4860::8888


Link 2 (wlp1s0)
    Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6                                   
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 8.8.8.8                                                     
       DNS Servers: 8.8.8.8 

キャッシュを削除したいときはresolvectl flush-cachesを実行します。