それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

ubuntu systemd-resolved で ローカルドメインの解決をする

ubuntu systemd-resolved で ローカルドメインの解決をする

ubuntu でresolved を使ってる場合にローカルドメインの解決をして増え続けるLXDコンテナの名前解決をなんとかしたい。IPアドレスで覚えきれないよ。

はじめに

ubuntuは systemdに移行しているので、名前解決は systemd-resolved を使う。

ubuntu は netplanもあるのでややこしい。複数インターフェースを使う。

ubuntu のデフォルト設定 resolved

ubuntu server のDNSのデフォルト設定を見てみると、こんな感じだと思う。

  • systemd-resolved が 127.0.0.53 をリッスンする
  • systemd-resolved は 上流をresolved.conf と DHCPから選ぶ
  • DHCP があって、 resolvedもあるとき。調べてみたとろ次のように動作していた。
  • 上流設定があれば、DHCPより優先する。
  • 上流設定を未設定なら、DHCPを使う。
  • 上流で解決できなければ、DHCPを使う。

設定変えて動作チェックを試行した結果を見ると、netplanのDHCPで渡されたDNSはresolvedのfallbackDNSと同等の動作をしている(たぶん)

resolved がどのDNSを使っているか見る。

sudo systemd-resolve --status

status をみれば、どのDNSを使っているかわかる。複数インターフェースがある場合は、インターフェース毎にDNS設定があるのがわかる。

上記の通り、systemd-resolve は resolvectl が最初に使われるはずなので、以下のコマンドと結果がおなじになる。

sudo resolvectl status

systemd-resolve の移譲先がresolvectlである。

status でネットワーク・インタフェースごとに設定されている、DNSサーバーを確認できる。 しかし、statusで表示されたDNSゾルバを使うとは限らない。上書き設定がある。resolvectl は上流でdnsmasqを参照したりする。

そのため、注意深く一つずつ見ていくことになる。

sudo systemd-resolve
 --> resolvectl 
   --> dnsmasq
     --> upstream  resolver
 --> dns of network interface  config
     --> upstream  resolver
 --> dns of DHCP config
     --> upstream  resolver
 --> resolve.conf
    --> upstream 

上記のようになることがある。慎重に考えないと面倒が起きる。

構成例 resolv.conf生成

すべて resolved で解決する 。

/etc/systemd/resolved.conf

[Resolve]
#略
Domains=local
UseDomains=true

すると、次のような resolv.confが生成される。

/etc/resolv.conf

システムは、/etc/resolve.confを使っていて、resolve.conf は systemd-resolvedを参照するように設定されている。

nameserver 127.0.0.53
options edns0 trust-ad
search local

だいたいこの設定がデフォルト設定担っている。

dig example は

search を入れているので。 dig exampledig example.local を探しに行く。

探しに行く先は、上流である。上流に example.localを問い合わせる。 この設定は、resolv.confを自動生成して、example → example.local を自動付記して問い合わせる設定である。

構成例 ローカルドメインの解決先を指定する。(dnsmasq を挟む)

resolved と DNSの間に dnsmasq を挟み込む。resolvedはほとんど何もしない。

resolved は dnsmasq に聞きに行く。dnsmasq がローカルドメインを解決する。

一見すると冗長に見えるが、resolvedより制御がしやすく仕方ないと思う。

準備

sudo apt install dnsmasq

dnsmasq の設定

dnsmasq の設定は、上書き設定を dnsmasq.d/ に書くと便利

sudo touch  /etc/dnsmasq.d/30-overwrites.conf

/etc/dnsmasq.d/30-overwrites.conf

#server=/xxx.internal.com/10.100.100.1
server=/local/192.168.1.1
server=/lxd/10.185.93.1
server=/virt/192.168.122.1
server=192.168.1.2

.lxd は lxc/lxd のネットワークの名前解決

.localルーターからDHCPで配布されたIPの名前解決

.virtlibvirt のネットワーク上のホスト名を名前解決

resolvedの設定

resolved 上流をdnsmasq にする

/etc/systemd/resolved.conf

[Resolve]
DNS=127.0.0.1
#FallbackDNS=
#Domains=

上流にdnsmasq を仕込む。

名前解決の順

dnsmasq を挟んだので、名前解決は次のようになる。

cli-->resolved(127.0.0.53#53)->dnsmasq(127.0.0.1#53)

dnsmasq がドメインを名に応じて、問い合わせ先を変えてくれる。

再起動

設定が終わったら再起動

sudo systemctl restart dnsmasq.service
sudo systemctl restart systemd-resolved.service

動作チェック

それぞれのローカルドメインについて、大本・dnsmasq・resolvedにそれぞれ問い合わせる。

# 上流から順に問い合わせる 
dig ubuntu.virt @192.168.122.1
dig ubuntu.virt @127.0.0.1
dig ubuntu.virt @127.0.0.53
# 上流から順に問い合わせる
dig debian.lxd @10.185.93.1
dig debian.lxd @127.0.0.1
dig debian.lxd @127.0.0.53

netplan のDHCP設定

netplan のDHCP設定でDNSを書いていても resolved で DNSを設定しておけば名前解決ができる。

DHCPから割り当てられたDNSは、resolvedからDNS=x.x.x.x への解決失敗時に使われる。

私の設定の場合、次項のようにした。resolved は dnsmasq へ問い合わせる。

Global
MulticastDNS setting: no
  Current DNS Server: 127.0.0.1
         DNS Servers: 127.0.0.1
Link 4 (br0.10)
  Current DNS Server: 192.168.12.1
         DNS Servers: 192.168.12.1

Link 3 (br-lan0)
 Current DNS Server: 192.168.2.2
         DNS Servers: 192.168.2.2

上記の設定が適用されている時、127.0.0.1 で動作中のdnsmasq を停止後でも、名前解決ができる。

dnsmasq 停止時のresolved の動作

sudo systemctl stop dnsmasq.service # dnsmasq 停止
dig dns.google @127.0.0.1 # dnsmasq 応答なし
dig dns.google @127.0.0.53 # resolved 応答あり

resolved は dnsmasq が停止しても、DHCPからのDNSがあるためそちらにDNS問合せを投げるようでした。

もっと省略した設定

systemd-resolvedで

DNS=192.168.122.1  10.185.93.1 192.168.2.2 192.168.12.1

と複数かけば、順番に問合せてくれる。 10.185.93.1 が .lxd をもってるので、そこに到達すれば応答が得られる。

とりあえず、投げつければいいのであれば、DNSを複数列挙で十分である。

ただ、その設定だとどのローカルドメインがどのサーバーかの対応が全くわからないので管理が面倒くさい。

設定ファイルは、辿れるのも大事。どこに何があるが設定をたどってわかるというのは、大事だと思う。

なぜ設定が必要なのか。

ssh で lxd や docker 内部に 多段ログインするときに名前解決をすると格段に管理がしやすい。

仮想マシン上に、lxd をインストールして、lxd 上にdocker を作り、dockerのコンテナを起動していて、

それぞれをssh 踏み台として、多段でsshするならば

host v1
  user takuya 
  hostname ubuntu.virt
host v1-docker
  user root
  hostname docker-host.lxd
  ProxyCommand ssh -t v1 -W %h:%p
host v1-docker-ubuntu
  user root
  hostname ubuntu
  ProxyCommand ssh -t v1-docker -W %h:%p

v1 にssh でログインして、v1-docker にアクセスできるようにして v1-docker にsshでログインして、v1-docker-ubuntu にアクセスできるようにする。

このとき、IPアドレスを直接していると再起動時にIPアドレスが変化して不便なのでDNSから名前解決しておけば安心である。

感想

resolvedで解決するといえど、resolved は機能不足だしresolv.confを生成するだけだし。結局dnsmasqに頼ることになった。networkd/resolvedで netplanやnetwork-managerが共通化されるとはいえ、あまりに冗長じゃないか?

v6 アドレスを作るときに、なんでHEXにしたんだ。。。BASE57 とかにしてくれてば、強引に覚えやすい名前をアルファベットで付けられたからDNSなくても良かったのに・・・

resolved / networkd を調べる時、 Googleなど検索エンジンは検索キーワードをresolve / network に置き換えるので、検索は困難になる。検索インデックスにもかからない systemd-resolved と書く必要がある。めっちゃ面倒くさいし名前付けに失敗してるわけで、これを使い続けるのは初心者には、今後どんんどんしんどくなっていくのだろうなと思う。