IDCFクラウドの Ubuntu Server 20.04 で DNSサーバの変更が巻き戻る
はじめに
平素は大変お世話になっております。
クイックガードのパー子です。
先日、Ubuntu Server 20.04 の DNSサーバをデフォルトのものから変更したところ、あるタイミングで何者かが勝手に /etc/resolv.conf
を書き換えて、変更を巻き戻してしまう事案が発生しました。
プラットフォームは IDCFクラウド です。
その調査結果と対策をご紹介します。
いきなり結論
お急ぎの方のために結論を述べます。
“IDCFクラウドの Ubuntu Server 20.04 において DNSサーバを変更する場合は、dhcpcd を停止しておく”
/etc/resolv.conf
を書き換えた犯人は、標準でインストールされている DHCPクライアントの dhcpcd でした。
dhcpcd を停止しておけば書き換わりを防げます。
具体的な手順は以下のとおりです。
dhcpcd.service
を無効化する。$ sudo systemctl disable dhcpcd.service
マシンを再起動する。
事案
発生した事案について、順を追って経緯をご説明します。
背景
とある案件にて、IDCFクラウド上に Ubuntu Server 20.04 を構築しました。
仮想マシンのイメージは 標準提供テンプレートの Ubuntu Server 20.04 LTS 64-bit です。
システム内部で利用するドメインの名前解決のために、リゾルバが参照する DNSサーバを変更する必要がありました。
(DNSサーバは仮に 10.3.0.101
, 10.3.0.102
の 2つとします。)
DNSサーバの変更
Ubuntu Server 20.04 では systemd-resolved を使っているため、/etc/resolv.conf
の直接の書き換えは禁止されています。
正しい変更方法はいくつかありますが、今回は Netplan を用いて変更しました。
既存の設定ファイルはいじらずに、カスタム用のファイル /etc/netplan/99-dns.yaml
を作成して、
/etc/netplan/99-dns.yaml
---
network:
version: 2
renderer: 'networkd'
ethernets:
# このマシンのインタフェイス名は `ens160` だった
ens160:
nameservers:
addresses:
- '10.3.0.101'
- '10.3.0.102'
search:
- 'cs106idcfcloud.internal'
dhcp4-overrides:
use-dns: false
use-domains: false
これを Apply しました。
$ sudo netplan apply
正常な状態
Apply の結果、期待どおりの状態となりました。
systemd-resolved は Local DNS stub listener として 127.0.0.53
を提供しているため、/etc/resolv.conf
は以下のようになります。
(Symlink となっており、実体は /run/systemd/resolve/stub-resolv.conf
です。)
/etc/resolv.conf (-> /run/systemd/resolve/stub-resolv.conf)
# 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 "resolvectl 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 trust-ad
search cs106idcfcloud.internal
実際に参照している DNSサーバは resolvectl
コマンドで確認できます。
$ sudo resolvectl status ens160
Link 2 (ens160)
Current Scopes: DNS
DefaultRoute setting: yes
LLMNR setting: yes
MulticastDNS setting: no
DNSOverTLS setting: no
DNSSEC setting: no
DNSSEC supported: no
Current DNS Server: 10.3.0.102
DNS Servers: 10.3.0.101
10.3.0.102
DNS Domain: cs106idcfcloud.internal
事案発生
ある日の AM6時頃、名前解決ができなくなった旨のアラートを監視システムが発報しました。
すぐにインスタンスを確認したところ、IDCFクラウドのデフォルトの DNSサーバを参照するように /etc/resolv.conf
が書き換えられていました。
/etc/resolv.conf (-> /run/systemd/resolve/stub-resolv.conf)
# Generated by resolvconf
domain cs106idcfcloud.internal
nameserver 10.41.0.1
nameserver 158.205.229.244
nameserver 158.205.237.131
ん… Generated by resolvconf
とな?
調査
どうやら resolvconf が悪さをしているようです。
resolvconf も /etc/resolv.conf
を管理するためのツールなのですが、systemd-resolved と競合するので両者の併用は避けるべきです。
resolvconf を発動したのは何者でしょうか?
当該時刻に発生したイベントを調べたところ、APT のアップグレードが走ってネットワーク関連のサービスが再起動されていました。
/var/log/syslog
...
Jan 5 06:00:20 myhost systemd[1]: Starting Daily apt upgrade and clean activities...
...
Jan 5 06:06:19 myhost systemd[1]: Stopping Network Name Resolution...
Jan 5 06:06:19 myhost dhcpcd[1045]: ens160: pid 1 deleted IP address xxx.xxx.xxx.xxx/27
Jan 5 06:06:19 myhost dhcpcd[1045]: ens160: deleting route to xxx.xxx.xxx.xxx/27
Jan 5 06:06:19 myhost dhcpcd[1045]: ens160: deleting default route via xxx.xxx.xxx.xxx
Jan 5 06:06:19 myhost systemd[1]: systemd-resolved.service: Succeeded.
Jan 5 06:06:19 myhost systemd[1]: Stopped Network Name Resolution.
Jan 5 06:06:19 myhost systemd-networkd[120053]: ens160: DHCPv4 address xxx.xxx.xxx.xxx/27 via xxx.xxx.xxx.xxx
Jan 5 06:06:19 myhost dbus-daemon[695]: [system] Activating via systemd: service name='org.freedesktop.hostname1' unit='dbus-org.freedesktop.hostname1.service' requested by ':1.148' (uid=100 pid=120053 comm="/lib/systemd/systemd-networkd ")
Jan 5 06:06:19 myhost systemd[1]: Starting Network Name Resolution...
Jan 5 06:06:19 myhost systemd-networkd-wait-online[120061]: managing: ens160
Jan 5 06:06:19 myhost systemd[1]: Starting Hostname Service...
Jan 5 06:06:19 myhost systemd[1]: Finished Wait for Network to be Configured.
Jan 5 06:06:19 myhost dhcpcd[1045]: ens160: rebinding lease of xxx.xxx.xxx.xxx
Jan 5 06:06:19 myhost systemd-resolved[120078]: Positive Trust Anchors:
Jan 5 06:06:19 myhost systemd-resolved[120078]: . IN DS 20326 8 2 e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d
Jan 5 06:06:19 myhost systemd-resolved[120078]: Negative trust anchors: 10.in-addr.arpa 16.172.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 168.192.in-addr.arpa d.f.ip6.arpa corp home internal intranet lan local private test
Jan 5 06:06:19 myhost systemd-resolved[120078]: Using system hostname 'myhost'.
Jan 5 06:06:19 myhost systemd[1]: Started Network Name Resolution.
...
む… dhcpcd が動いていますね。
こいつが犯人のようです。
$ sudo resolvconf -l
# resolv.conf from ens160.dhcp
# Generated by dhcpcd from ens160.dhcp
domain cs106idcfcloud.internal
search cs106idcfcloud.internal
nameserver 10.41.0.1
nameserver 158.205.229.244
nameserver 158.205.237.131
dhcpcd は フック機能 を持っており、DHCP の状態変化をトリガーに /etc/resolv.conf
を書き換えてしまうのです。
nohook script
Don’t run this hook script. Matches full name, or prefixed with 2 numbers
optionally ending with .sh.So to stop dhcpcd from touching your DNS settings or starting wpa_supplicant you
would do:-
nohook resolv.conf, wpa_supplicant
$ cat /lib/dhcpcd/dhcpcd-hooks/20-resolv.conf | head -n 15
# Generate /etc/resolv.conf
# Support resolvconf(8) if available
# We can merge other dhcpcd resolv.conf files into one like resolvconf,
# but resolvconf is preferred as other applications like VPN clients
# can readily hook into it.
# Also, resolvconf can configure local nameservers such as bind
# or dnsmasq. This is important as the libc resolver isn't that powerful.
resolv_conf_dir="$state_dir/resolv.conf"
NL="
"
: ${resolvconf:=resolvconf}
build_resolv_conf()
{
対策
単純に dhcpcd を停止すれば OK です。
dhcpcd が停止していればフックも走らないため、/etc/resolv.conf
が書き換えられることはなくなります。
Ubuntu Server 20.04 の標準ネットワーク・マネージャである systemd-networkd も DHCPクライアント機能 を持っているため、DHCP はそちらに任せます。
というか、そもそも systemd-networkd の DHCPクライアント機能はデフォルトで ON になっているため、競合しないようにシュッと dhcpcd を停止してしまうことをオススメします。
/etc/netplan/01-netcfg.yaml
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
version: 2
renderer: networkd
ethernets:
ens160:
dhcp4: yes
/run/systemd/network/10-netplan-ens160.network
[Match]
Name=ens160
[Network]
DHCP=ipv4
LinkLocalAddressing=ipv6
[DHCP]
RouteMetric=100
UseMTU=true
停止する際は、いきなり systemctl stop
すると通信が遮断されてしまうので、いったん無効化してからマシンを再起動するとよいでしょう。
$ sudo systemctl disable dhcpcd.service
まとめ
IDCFクラウド Ubuntu Server 20.04 の DNSサーバを変更する際の注意点をご紹介しました。
このインスタンスには DHCPクライアントの dhcpcd が標準でインストールされていますが、systemd-resolved や systemd-networkd と競合します。
dhcpcd は停止してしまいましょう。
今後ともよろしくお願い申し上げます。