前の記事
systemd-resolved
がデフォルトのDNSクライアントとなる前後の/etc/nsswitch.conf
を比較しました。
また、興味のある方向けに詳細まで踏み込んで紹介しました。
忙しい方はサマリだけでもご覧ください。
お伝えしたいこと
Fedora33以降で (/etc/hosts
とmulticast DNS
を除けば) デフォルトのDNSクライアントとなったnss-resolve
(systemd-resolved)
について概要を紹介します。
従来のDNSであるnss-dns (/etc/resolv.conf)
との違いに着目しつつ、systemd-resolved
の基本構成や便利機能 (per-link DNS)、使い方について書きました。
設定ファイルである/etc/systemd/resolved.conf
の書きっぷりについては深く触れていませんが、基本動作にてDNSサーバ選出時にどう関わるかのみ紹介しています。
DNSサーバを使い分けない場合は/etc/systemd/resolved.conf
のみに記載するのがシンプルですが、per-link DNSを使う場合は寧ろNetworkManagerのみでほぼ全てを制御するのが良いと思います。
いずれにしても設定箇所をあまり分散せず、可能な限り一つにまとめるのがわかりやすくて良いでしょう。
- 前の記事
- お伝えしたいこと
- systemd-resolved とは
- systemd-resolved のAPI
- systemd-resolved の基本機能
- systemd-resolved と従来型DNSの違い
- per-link DNS (Routing)
- 現在のDNS設定の確認方法
- (参考) D-Bus関連コマンド
- まとめ
systemd-resolved とは
systemd-resolved
は、Linux においてDNSクライアントとして動作します。
多くのLinuxディストリビューションでinitプロセスを管理しているsystemd
の1コンポーネントでもあります。
systemd-resolved
の主要な構成要素は、下表の通りです。
要素 | 説明 |
---|---|
systemd-resolved.service |
systemd に管理されているサービス。systemctl によって起動・停止などを制御する |
/etc/systemd/resolved.conf |
systemd-resolved の設定ファイル |
/run/systemd/resolve/stub-resolv.conf |
Fedora33以降では、/etc/resolv.conf がこのファイルへのシンボリックリンクになっている。dig など/etc/resolv.conf を固定的に参照するプログラムとの互換性のために、systemd-resolved.service が/run/systemd/resolve/stub-resolv.conf を自動的に更新する |
resolvectl |
systemd-resolved のコマンドラインツール。systemd-resolved の動作を確認したり、リアルタイムに変更したりできる |
systemd-resolved のAPI
man systemd-resolved
、またはArch Wiki によると、systemd-resolved
を使う方法 (API: Application Programming Interface) は3種類あります。
いずれのAPIもローカル専用で、ネットワーク越しに外部ホストからアクセスすることはできません。
man systemd-resolved
によると、サポートされる機能の多さとしては(1) > (2) >> (3)
という関係になっており、systemd
の開発者としては(3)よりも(1), (2) のAPIを使うことをより推奨しているようです。
(3) は、古いプログラムへの互換性を保つために残されています。
次のセクションでこれらのAPIがどのような使われ方をするのか、より具体的に紹介します。
# | API | 説明 |
---|---|---|
1 | D-Bus (Desktop Bus) | プロセス間通信機能を提供するAPI |
2 | NSS (Name System Switch) | /etc/nsswitch.conf を介してアクセスする方式。GNU C ライブラリによって実装されている |
3 | Local DNS Stub Listener | TCP/UDP の 127.0.0.53:53 でリッスンしている/etc/resolv.conf を直接参照するプログラムが利用する |
(1) D-Bus (Desktop Bus)
プロセス間で各種設定情報や命令を直接やり取りするための仕組みです (IPC: InterProcess Communication = プロセス間通信)。
基本的には同一OS内のローカルのやり取りのみをサポートします。
ネットワーク越しに外部ホストとメッセージをやり取りするような使い方は、サポートされていないとのことです。
標準入力や標準出力、シェルなどのユーザー操作を介さずにプロセス間で直接やり取りすることで、ユーザーに意識させず、プロセス間でイイカンジに情報連携するための仕組みと理解しています。
アプリケーション開発者がこういった内部処理を作り込むことで、複数プロセスが矛盾なく連携し、粗結合なアーキテクチャで高度な機能や使い勝手を実現できるのでしょう。
D-Busの概要は、下記サイトにとてもわかりやすく解説されていました。
D-Busを利用している身近な例としては、私の知る限り2つあります。
どちらもNetworkManager関連です。
1つ目は、nmcli
です。
nmcli
で設定する際、裏ではNetworkManager.service
の D-Bus API を叩いて設定変更を反映しているようです。
※nmtui
など、その他のコマンドも恐らく同様です
以下の出力からも何となく察せると思います。
nmcli conn up eno1
# Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)
2つ目は、NetworkManager
からsystemd-resolved
への設定情報連携です。
Fedora33以降の構成で、/etc/nsswitch.conf
(resolve
が選出され、DNSクライアントとしてsystemd-resolved
が選択される) や、/etc/resolv.conf
(システムのDNSサーバとして127.0.0.53
を参照する。結果としてsystemd-resolved
がスタブリゾルバとして問い合わせを代行する) だけを見ていると、NetworkManager のDNS設定が挙動に影響しない...と考えたくなるのですが、実は影響を与えます。
それは、NetworkManager
がD-Bus APIによってsystemd-resolved
に設定情報を連携しているためです。
man NetworkManager.conf
に書いてありますが、/etc/NetworkManager/NetworkManager.conf
のsystemd-resolved
という設定項目のデフォルト値がtrue
になっています。
これにより、D-Bus API越しの情報連携が有効になります。
この挙動に馴染みのない方は、ご注意を...。
NetworkManager
とsystemd-resolved
の連携については、記事の後半で具体的な設定手順と共に紹介します。
(2) NSS (Name Service Switch)
DNSクライアントが名前解決をする際、/etc/nsswitch.conf
のhosts:
行を参照してどの方式で名前解決するかを決定します。
Fedora33以降の/etc/nsswitch.conf
は、以下のようになっています。
hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] myhostname dns # 参考情報として、Fedora32 <span style="color: #0000cc">(恐らくRHEL8と同じ)</span> の/etc/nsswitch.confも載せておきます #hosts: files mdns4_minimal [NOTFOUND=return] dns myhostname
詳細は前回の記事に譲りますが、多くの場合は/etc/hosts
に記載がなければsystemd-resolved
によって外部DNSサーバに問い合わせするのが基本の動きです。
(3) Local DNS Stub Listener
Local DNS Stub Listener とは、TCP/UDPでリッスンしている 127.0.0.53:53
のことです。
Fedora33以降では/etc/resolv.conf
が/run/systemd/resolve/stub-resolv.conf
へのシンボリックリンクとなっており、/run/systemd/resolve/stub-resolv.conf
をsystemd-resolved
が自動更新するという構造になっています。
結果として、/etc/resolv.conf
を参照すると、システムのDNSサーバが127.0.0.53
、つまりsystemd-resolved
に設定されていることになります。
dig
コマンドやhost
コマンドのように、/etc/nsswitch.conf
ではなく/etc/resolv.conf
を直接参照するプログラムにも互換性を持たせるため、こういったアクセスの仕方も用意されています。
systemd-resolved の基本機能
前回の記事で紹介しましたが、名前解決に使われるNSS (/etc/nsswitch.conf
の右側に列挙されているもののこと) には様々なものがあります。
systemd-resolved
(=nss-resolve
) は、既存のNSSの多くを置き換える機能性を持っています。
systemd-resolved
の場合はキャッシュが効くため、systemd
のマニュアルでは従来のfiles
やmyhostname
よりも推奨されています (→ 前回の記事)。
既存のNSS名 | 既存NSSの機能 | systemd-resolved での対応 |
---|---|---|
files |
/etc/hosts を読み取る |
デフォルトで有効 |
mdns4_minimal |
mDNS機能 (あまり使わない) | デフォルト無効。/etc/systemd/resolved.conf を書き換えて有効化できる |
dns |
外部DNSサーバにクエリを投げる) | デフォルト有効。 従来の dns は/etc/resolv.conf によるシンプルな制御だった。resolve では、/etc/systemd/resolved.conf でより高度な制御ができる |
myhostname |
自身のホスト名、*.localhost 、localhost などの名前解決(直接は使わないが、この機能を利用するプログラムもある) |
デフォルト有効 |
Fedora33のデフォルトの/etc/nsswitch.conf
はfiles
が最初に検索されるため、/etc/hosts
の検索にsystemd-resolved
が利用されることはありません。
/etc/nsswitch.conf
の順序を入れ替えてresolve
をfiles
よりも左に配置することで、systemd-resolved
で/etc/hosts
を読み取るよう設定することも可能です。
このようにsystemd-resolved
は従来のNSSの大半を置き換える機能性を持ちます。
後続のセクションでは、これらの機能の中でも従来のdns
に相当する、外部DNSサーバへの問い合わせの挙動について紹介します。
systemd-resolved と従来型DNSの違い
systemd-resolved
(nss-resolve
)と従来型DNS (nss-dns
)の違いを示します。
設定ファイルの違い
従来のDNSは/etc/resolv.conf
を参照していました。
一方で、systemd-resolved
は/etc/systemd/resolved.conf
を参照します。
それぞれの設定ファイルの仕様を見比べると、両者の違いがより詳細に見えてきます。
search (ドメイン自動補完)
まずは、search機能についておさらいします。
例えばsearch に xxx.com
を指定していたとします。
ping A
を実行すると、A
が名前解決できなくてもxxx.com
を自動補完してA.xxx.com
にpingを実行してくれます。
従来のDNSでは、/etc/resolv.conf
のndots
というオプションによって「ピリオドをいくつまで含んでいるときに自動補完の対象とするか」を制御できました (man resolv.conf
)。
systemd-resolved
の場合はndots
を敢えて実装しておらず、単一ラベル (つまりピリオドを含まない) の場合のみドメインを補完します(man systemd-resolved
)。
systemd-resolved
がndots
を実装していない理由については、man systemd-resolved
で言及されています。
DNSサーバの複数指定
従来のDNSでは、最大3台までDNSサーバを指定できます。
基本的には1台目のみにクエリを投げます。
1台目のDNSサーバへのクエリがタイムアウトしたら、次のDNSサーバに問い合わせます。
systemd-resolved
では、Routing という仕組みによってDNSサーバが選択されます。
ネットワークのIP Routing とは若干関係ありますが、完全に別物です。
これがper-link DNS
に繋がります。
詳細は次のセクションで紹介します。
per-link DNS (Routing)
基本動作
systemd-resolved
は、ネットワークインターフェースごとにDNSサーバを指定できます。
その上で、Routing という仕組みによって、クエリごとにDNSサーバを使い分けます。
具体的には以下の動きになります (man systemd-resolved
のPROTOCOLS AND ROUTING
より)。
※グレーにした部分はあまり重要ではないので、無視してください
※5. についてはコマンド実行ログは掲載していませんが、私の手元で検証済みです
# | 詳細 |
---|---|
1 | /etc/hosts や自身のホスト名、localhost 、localhost.localdomain 、XXX.localhost などは、ネットワークにクエリを出すことなくローカルのみで名前解決する |
2 | 単一ラベル (ピリオドを含まない) 場合は、Unicast DNS (通常のUDP#53のクエリ) は使われず、LLMNR (mDNSのように同一ネットワーク内の名前解決をするサービス) で名前解決する。 ただし、AレコードやAAAAレコードの場合は search domains によってドメイン名が補完され、Unicast DNS でクエリされる |
3 | *.local という名前はmDNSとして扱われるため、Unicast DNSとしては動作しない |
4 | 複数ラベルA, AAAA, PTRレコードの場合 (ピリオドを含む場合) は、以下のロジックで最適なDNSサーバが選出される (man resolved.conf のDomains= も併せて参照) (※1)(※2)
|
5 | 4 のper-link DNSのsearch domains に一致しなかった場合、以下の挙動となる。
|
(※1) search domains に ~.
を指定することで、どのFQDNにもマッチする指定が可能です (DNS Default Route)。best matching の観点では、最も優先順位が低いです。~
をつけるとRouting Domain の扱いとなり、「DNS Routingの評価対象になるが単一ラベルに対するドメイン補完には利用されない」挙動になります。.
はルートドメインを意味し、全てのドメインにマッチします
(※2) グローバルなDNS設定 (/etc/systemd/resolved.conf
のDNS
やDomains
) もper-link DNSと同様に評価されます。グローバルなDNSサーバがbest matching となれば、グローバルなDNSサーバのみにクエリされます。グローバルなDNSサーバとper-link DNSサーバの両方がbest matching となった場合は、どちらにもクエリされます
(※3) 例えば、www.google.com
というFQDNにはwww
、google
、com
という3つのラベルが含まれます
基本動作の要点
DNS Routing の挙動が非常にややこしいですが、上表の4と5をまとめると、A, AAAA, PTR レコードのクエリ先のDNSサーバは、以下の順序で評価されるようです。
あらゆる状況に対処できるように、systemd-resolved
には細かいルールが設定されていますが、基本的には1か2で確定できるように設計するのがわかりやすくてオススメです。
~.
を含め、search domains に一致したDNS (best matching)。per-link DNS もグローバルなDNSも特に差はなく、同列に評価される- グローバルなDNSが設定されていれば、そこにクエリする
- IP Routing の世界でデフォルトルートと紐づくNICにper-link DNSサーバが設定されていれば、そこにクエリする
- 全てのper-link DNSサーバにクエリする
設定方法
man resolved.conf
によると、/etc/systemd/resolved.conf
ではシステム全体でクエリ先のDNSサーバを設定できますが、 search domains によって優先順位付けするような指定方法 (per-link DNS) はできません。
per-link DNSの設定はsystemd-networkd
、または外部アプリケーション (例えばD-Bus連携しているNetworkManager
) からの同期によって読み込まれます。
次のセクションで具体的な設定例を紹介しますが、設定例は使い慣れた NetworkManager (nmcli)
にて紹介します。
どんな時に役に立つか?
Linux端末がVPNに接続している場合、VPN越しにアクセスするDNSサーバと、通常の物理ネットワーク越しにアクセスするDNSサーバで使い分けたいケースがあると思います。
社内向けドメインはVPN越しのDNSサーバに、その他のgoogle.comなどのドメインは物理ネットワーク越しのDNSサーバに名前解決をしたいときに、per-link DNSが役に立つと思います。
(参考) 具体例
実際にDNS設定がどうなるか、色々な例で試してみました。
systemd-resolvedで/etc/hostsを認識させる
/etc/nsswitch.conf
を変更して、systemd-resolved
しか使わないように変更します。
これは検証のための設定変更であり、本来はこのようにすべきではないのでご注意ください。
#hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] myhostname dns hosts: resolve [!UNAVAIL=return]
また、/etc/hosts
に試験用のエントリを追加します。
8.8.8.8 google-hosts
この状態でgoogle-hosts
にpingしたところ、名前解決できました。
確かに、systemd-resolved
は/etc/hosts
を読み込むようです。
ping google-hosts # PING google-hosts (8.8.8.8) 56(84) bytes of data. # 64 bytes from google-hosts (8.8.8.8): icmp_seq=1 ttl=116 time=2.88 ms # (以下略)
ちなみに、自身のホスト名へのpingも通りました (nss-myhostname
相当)。
ping pc # PING pc.internal1 (192.168.100.155) 56(84) bytes of data. # 64 bytes from pc (192.168.100.155): icmp_seq=1 ttl=64 time=0.252 ms # (以下略)
変更した/etc/nsswitch.conf
を元に戻しておきます。
hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] myhostname dns
search domains にヒットする方を優先する
こちらの構成で検証します。
DNS1, DNS2 という2台のDNSサーバを用意し、PCからそれぞれにクエリを投げて名前解決する構成を組みました。
PCには、DNS1と紐づけてendy1.test
を、DNS2と紐づけてendy2.test
を search domains (ipv4.dns-search
) に設定しています。
systemd-resolved
において、問い合わせ先のDNSサーバは search domains に一致するものが優先される仕様です。
rr.endy1.test
はDNS1に、rr.endy2.test
はDNS2に問い合わせる構成となります。
PCのNetworkManager
設定は、以下のようになっています。
# DNS1向け nmcli connection add \ con-name dnstest1 \ ifname enp7s0 \ type ethernet \ ipv4.method manual \ ipv4.addresses 192.168.100.100/24 \ ipv4.dns 192.168.100.2 \ ipv4.dns-search endy1.test # ★search domains nmcli connection up dnstest1 # DNS2向け nmcli connection add \ con-name dnstest2 \ ifname enp1s0 \ type ethernet \ ipv4.method manual \ ipv4.addresses 192.168.122.100/24 \ ipv4.dns 192.168.122.3 \ ipv4.dns-search endy2.test # ★search domains nmcli connection up dnstest2
DNS1には、 endy1.test.zone
とendy2.test.zone
には、それぞれ以下の行を記載しました。
rr.endy1.test
、rr.endy2.test
に、それぞれ192.168.100.2
(DNS1のIPアドレス) を紐づけました。
ゾーンファイルを2つ作ったのは、ドメイン名を区別するためです。
rr A 192.168.100.2
DNS2には、 endy1.test.zone
とendy2.test.zone
には、それぞれ以下の行を記載しました。
rr.endy1.test
、rr.endy2.test
に、それぞれ192.168.100.2
(DNS2のIPアドレス) を紐づけました。
DNS1とは異なるアドレスを返すため、どちらにPCからDNS1とDNS2のどちらに問い合わせたかわかるようになっています。
rr A 192.168.122.3
ここで、PCから2箇所にdigを実行してみます。
endy1.test
はDNS1に問い合わせており、endy2.test
はDNS2に問い合わせていることがわかります。
この挙動から、 search domains と紐づくDNSサーバに優先して問い合わせることがわかります。
dig rr.endy1.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy1.test. 6779 IN A 192.168.100.2 dig rr.endy2.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy2.test. 6758 IN A 192.168.122.3
resolvectl domain
でsystemd-resolved
が選択するリンクと search domains の関係を確認すると、以下のようになります。
resolvectl domain # Global: # Link 2 (enp1s0): endy2.test # Link 3 (enp7s0): endy1.test
best matching が優先される (longest match)
黄色の部分のみ構成を変更しました。
rr.endy1.test
、rr.endy2.test
共に、.test
ドメインに属します。
ただ、上図の構成においては、仕様上以下の動作になります。
rr.endy1.test
はDNS1とDNS2の両方の search domains に該当するが、best matching の考え方に基づいて2階層分のドメイン名に一致するDNS1が優先されるrr.endy2.test
は、DNS2の search domains にしか一致しないため、DNS2が優先される
黄色部分の変更差分のNetworkManager
設定は、以下のようになります。
sudo nmcli connection modify dnstest2 ipv4.dns-search test
sudo nmcli connection up dnstest2
ここで、PCから2箇所にdigを実行してみます。
endy1.test
はDNS1に問い合わせており、endy2.test
はDNS2に問い合わせていることがわかります。
この挙動から事前の予想通り、より多くの label (ピリオドで区切られた文字列) に一致するDNSサーバが優先されることがわかりました。
dig rr.endy1.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy1.test. 4800 IN A 192.168.100.2 dig rr.endy2.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy2.test. 86400 IN A 192.168.122.3
resolvectl domain
でsystemd-resolved
が選択するリンクと search domains の関係を確認すると、以下のようになります。
resolvectl domain # Global: # Link 2 (enp1s0): test # Link 3 (enp7s0): endy1.test
best matching なDNSサーバが複数存在する場合、全てのDNSサーバにクエリする
次は以下の黄色部分を変更しました。
search domains の条件を両方のリンクで揃えました。
search domains のbest matching でも同等な場合は、それらのDNSサーバ全てに問い合わせる仕様です。
そして、最初にDNS応答を受信した経路が採用されます。
NetworkManager
の設定差分は、以下のようになります。
sudo nmcli connection modify dnstest1 ipv4.dns-search endy1.test,endy2.test sudo nmcli connection up dnstest1 sudo nmcli connection modify dnstest2 ipv4.dns-search endy1.test,endy2.test sudo nmcli connection up dnstest2
dig で確認します。
DNSキャッシュをクリアしながら実行していると、途中で結果が変わっていることがわかります。
DNS1とDNS2のうち、先に受信した応答が表示されています。
どちらもほぼ同時に応答を受信するため、結果が不定になっています。
dig rr.endy1.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy1.test. 6554 IN A 192.168.100.2 dig rr.endy2.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy2.test. 86400 IN A 192.168.100.2 resolvectl flush-caches dig rr.endy1.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy1.test. 86400 IN A 192.168.100.2 dig rr.endy2.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy2.test. 86400 IN A 192.168.122.3
最後に、resolvectl
で設定を確認します。
両方の search domains にbest matching となっていることがわかります。
resolvectl domain # Global: # Link 2 (enp1s0): endy1.test endy2.test # Link 3 (enp7s0): endy1.test endy2.test
DNSデフォルトルート
DNSデフォルトルートの挙動を確認します。
DNS1と紐づくリンクに、デフォルトゲートウェイを設定します。
また、 search domains を空欄にすることで一致しないようにします。
search domains に具体的なキーワードが全く該当しない場合、デフォルトルートが評価されます。
以下の2通りのいずれかの条件に該当するリンクは、デフォルトルートとして扱われます。
- IPルーティングのデフォルトゲートウェイと紐づくリンクであること
- search domains に
~.
が含まれること (※)
(※) .
は、ルートドメインなので全てのドメインに一致します。また、ドメイン名の先頭に~
を付けると、「ホスト名にドメイン名を補う」効果はなく、「best matchingなDNSサーバの選択」のみに寄与するという意味になります (routing domain)。
即ち、今回の場合は全てのクエリがDNS1を向くようになります。
NetworkManager
上は、以下の変更差分となります。
sudo nmcli connection modify dnstest1 ipv4.gateway 192.168.100.1 sudo nmcli connection modify dnstest1 ipv4.dns-search "" sudo nmcli connection up dnstest1 sudo nmcli connection modify dnstest2 ipv4.dns-search "" sudo nmcli connection up dnstest2
digを実行してみると、実際に全てのクエリがDNS1を向くようになります。
dig rr.endy1.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy1.test. 86400 IN A 192.168.100.2 dig rr.endy2.test | sed -ne '/ANSWER SECTION/,/^$/p' # ;; ANSWER SECTION: # rr.endy2.test. 86400 IN A 192.168.100.2
resolvectl domain
からは、両リンクで search domains が空っぽであることがわかります。
resolvectl dns
の出力では、実質的にDNS1にしか問い合わせが向いていないことを反映して、DNS1のみが表示されます。
resolvectl
からは、IPルーティングのdefault routeが反映されて、DefaultRoute
のフラグが片方のリンクで有効 (+
) になっていることがわかります。
resolvectl domain # Global: # Link 2 (enp1s0): # Link 3 (enp7s0): resolvectl dns # Global: # Link 2 (enp1s0): # Link 3 (enp7s0): 192.168.100.2 resolvectl # Link 2 (enp1s0) # Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported # Link 3 (enp7s0) # Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported # Current DNS Server: 192.168.100.2
長くなるのでコマンド実行結果は省きますが、いくつか追加で補足します。
DNS2の search domains に~.
を追加すると、IP Routing のデフォルトゲートウェイよりも優先されてDNS2のみに問い合わせるようになります。
NetworkManager
の設定コマンドとしては、以下のようになります。
sudo nmcli connection modify dnstest2 ipv4.dns-search "~." sudo nmcli connection up dnstest2
更にDNS1の search domains に~.
を追加すると、DNS1とDNS2の両方にクエリを出すようになりました。
search domains に~.
が設定されたリンク同士であれば、ipv4.gateway
の設定有無が優先順位に影響することは無いようです。
現在のDNS設定の確認方法
systemd-resolved
は、/etc/systemd/resolved.conf
やデフォルトルート、他デーモンからのD-Bus連携によって挙動が変わるため、非常に複雑です。
resolvectl
コマンドを使えば、systemd-resolved
の設定情報を確認できるため便利です。
resolvectl
をそのまま実行すると、最も詳細な情報が出てきます。
resolvectl domain
によって、per-link DNSと関係する search domains を確認できます。
resolvectl dns
によって、各リンクと紐づくDNSサーバを確認できます。
具体的な出力例は、(参考) 具体例を参照してください。
(参考) D-Bus関連コマンド
D-Bus周りでそれっぽいコマンドを実行してみました。
D-Busに対応しているプロセスであれば、CLIやGUIだけでなくD-Bus APIでもステータスを確認できます。
--xml
オプションをつければ、XMLで出力することも可能です。
オブジェクトパス (/org/freedesktop/NetworkManager/DnsManager
) はインターネットで「NetworkManager D-Bus」で調べても良いですが、bash-completion の働きでタブ補完することでも簡単に確認できました。
D-Bus オブジェクトにはプロパティとメソッドが紐付いて定義されており、コマンドラインで参照できます。
中々使う機会はないのですが、こういったものも存在することを知っておくとたまに便利かもしれません。
# オブジェクトを指定して、メソッドやプロパティの名前や型情報、持っている値を参照できる gdbus introspect --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/DnsManager # node /org/freedesktop/NetworkManager/DnsManager { # (中略) # interface org.freedesktop.NetworkManager.DnsManager { # methods: # signals: # properties: # readonly s Mode = 'systemd-resolved'; # readonly s RcManager = 'symlink'; # readonly aa{sv} Configuration = [{'nameservers': <['192.168.1.1']>, 'interface': <'eno1'>, 'priority': <100>, 'vpn': <false>}]; # }; # };
まとめ
具体例を入れたら非常に長くなってしまいましたが、systemd-resolvedの挙動についてまとめました。
D-Busの働きにより、NetworkManager
の設定変更によりsystemd-resolved
の設定を変更できるので、使い勝手は従来と大きく変わりません。
一方でVPNを利用している場合など、宛先ドメインによってDNSサーバを使い分けたいときにはsystemd-resolved
の per-link DNS 機能が役に立ちそうです。