Ubuntu 16.10 以降で /etc/resolv.conf
の中身を見てみると DNS による名前解決のために 127.0.0.53 を見に行っていることに気づくことがあります。
これは、最近の Ubuntu では systemd-resolved が 127.0.0.53:53 で local DNS stub listener というものを提供しており、これを経由して外部の DNS リゾルバを参照するような設定が行われていることによるものです。local DNS stub listener が利用されるようになった経緯については以下の記事が詳しいです。
Ubuntu 16.10 その7 - ローカルDNSリゾルバーの仕組みが変わる・systemd-resolvedの採用 - kledgeb
local DNS stub listener を利用することにはさまざまな利点がありますが、この機能をオフにしたい場合もあります。典型的には BIND や NSD のような DNS コンテンツサーバを起動しようとしたときに local DNS stub listener が53番ポートを先に利用してしまうことで起動できなくなるという問題が起こることがあります。
この問題を解決する方法はいろいろ考えられ、状況によって最適な方法は変わってくるのですが、私は以下の方針で解決しました。参考にしてください。
- local DNS stub listener の利用をやめる
- netplan と systemd-resolved の利用を続ける
-
/etc/resolv.conf
が外部の DNS リゾルバを直接参照するようにする
local DNS stub listener の利用をやめる
構築しようとしている DNS サーバと local DNS stub listener が競合しないように設定することができる場合もありますが、この方法は難しそうだったのであきらめて、local DNS stub listener の利用をやめることにしました。
local DNS stub listener を利用しないようにするためには /etc/systemd/resolved.conf
を編集します。
[Resolve]
DNSStubListener=no
設定ファイル変更後には systemd-resolved を再起動して設定を適用したいところですが、このままでは問題が起きるので適用はこの記事の最後まで待ってください。
netplan と systemd-resolved の利用を続ける
local DNS stub listener を起動しないような設定はできましたが、まだ /etc/resolv.conf
を変更していないので名前解決を行うために 127.0.0.53 を見に行こうとしてしまいます。
このため /etc/resolv.conf
を変更したいところですが、方針をよく考えましょう。最近の Ubuntu ではネットワークの設定を行うためのツールのエコシステムが複雑化しており、たとえば Ubuntu 18.04 では
-
/etc/netplan
以下の yaml ファイルをもとに netplan が systemd-networkd の設定ファイルを生成する - 生成された設定ファイルをもとに systemd-networkd がネットワークの設定を変更する
という流れで設定が適用されます。DNS の設定についても同様で、etc/netplan
以下の yaml ファイルをもとに systemd-resolved の設定が変更され、local DNS stub listener が参照する外部の DNS リゾルバが切り替わるようになっています。よって /etc/resolv.conf
を手動で編集してしまうと「DNS 以外のネットワークの設定は netplan で変更できるけど DNS だけは直接 /etc/resolv.conf
を編集しないといけない」という状態になり混乱を呼びそうです。
よって、netplan を使い続けたいと考えている場合は /etc/resolv.conf
を直接編集したり systemd-resolved を disable するのはやめたほうがよいです。
/etc/resolv.conf
が外部の DNS リゾルバを直接参照するようにする
とはいえ /etc/resolv.conf
には外部の DNS リゾルバを直接参照するような設定が必要です。実は man 8 systemd-resolved
にやり方が書いてあり、/etc/resolv.conf
を /run/systemd/resolve/resolv.conf
へのシンボリックリンクとすればよいです。
/run/systemd/resolve/
には resolv.conf
と stub-resolv.conf
という2種類のファイルが含まれています。resolv.conf
は外部の DNS リゾルバを直接参照するような設定が書かれており、stub-resolv.conf
は「外部の DNS リゾルバを参照するように設定された local DNS stub listener」を参照する設定(すなわち 127.0.0.53)が書かれています。これらのファイルの内容は systemd-resolved により管理されているので、間接的に、netplan の設定ファイルに書かれた内容が反映されるようになっています。
要するに、以下のようにすればよいです。
$ cd /etc
$ sudo ln -sf ../run/systemd/resolve/resolv.conf resolv.conf
あとは systemd-resolved を再起動して local DNS stub listener を止めます。
$ sudo systemctl restart systemd-resolved
以上の設定によって次のことが実現できるようになりました。
- local DNS stub listener を止めた(他のプログラムが 53番ポートを bind するときに失敗しなくなった)
-
resolv.conf
が外部の DNS リゾルバを直接参照するようになった(127.0.0.53 を参照するのをやめた) - netplan の設定変更が
/etc/resolv.conf
に自動的に反映されるようになった