ネットワーク設定の永続化


きっかけ

GCPにはInternal DNSやCloud DNSといったDNSがあるのですが、それらを使わずvm上にBIND9を立ち上げて、それをDNSとして使おうとしたときにハマりました。どうやっても、DNSが上書きされてモヤモヤしたので、落ち着いて調べてみることにしました。

普通に/etc/resolv.confを編集しても、再起動すると上書きされてしまいます。原因としては、

  • DHCP client
  • resolvconf
  • NetworkManager

が考えられます。それぞれの原因に対する対策をまとめてみました。

ここでは、上書きを禁止するのではなく、思い通りの値で上書きさせることで問題を回避する方法も解決法として紹介します。

環境

GCP(Google Cloud Platform)上のDebian GNU/LINUX 9 (stretch)です。

DHCP client (ifupdown)が上書きしているとき

DHCP clientの設定を変更します。設定ファイルは、/etc/dhcp/dhcpclient.confです。
そこに、以下の内容を追加します。

/etc/dhcp/dhcpclient.config
prepend domain-name-servers <dns1> <dns2>
supersede domain-name "<domain>";

この設定は/etc/resolv.confファイルでは、

/etc/resolv.conf
domain <domain>
nameserver <dns1>
nameserver <dns2>
nameserver <dhcp dns>

として反映されます。DHCPサーバーから得られるDNSサーバー情報は、上書きせずに残しておきます。
そうすることで、ローカルDNSが落ちても、一般ドメインの名前解決ができます。

もしくは、DHCPを使わないよう、/etc/network/interfacesファイルを編集します。

/etc/network/interfaces
#iface eth0 inet dhcp #コメントアウト
iface eth0 inet static
address <ip addr>
dns-name-servers <dns1> <dns2>

resolvconfが上書きしているとき

https://unix.stackexchange.com/questions/174349/what-overwrites-etc-resolv-conf-on-every-boot などを参考にしてください。記事が書けるほど僕は詳しくない(というか、使ったことがない)ので、ここでは省略します。

NetworkManagerが上書きしているとき

DNSの設定にDHCPを使わないよう設定した上で、DNSを登録します。

nmcli c down eth0
nmcli c m eth0 ignore-auto-dns yes
nmcli c m eth0 +ipv4.dns <dns1> +ipv4.dns <dns2>
nmcli c up eth0

もしくは、NetworkManagerを無効にします。

service network-manager stop
update-rc.d network-manager disable

どのサービスが上書きしているかを調べる方法

とはいっても、愚直な方法です。

以下のように、各サービスの起動状況によって状態に名前をつけます。

resolvconf NetworkManager state
o o A
o x B
x o C
x x D

このとき、各状態とその時に上書きが起こるかを調べることで、どのサービスが悪さをしているかわかります。Dの状態の時に書き換わるなら、それはDHCP clientが書き換えているということです。ただし、複数のサービスが書き換えを行っていることも考慮してください。

僕の場合

僕はDHCP clientが曲者でした。Googleのサイトに説明があります。

Compute Engine instances are configured to renew DHCP leases every 24 hours.
(https://cloud.google.com/compute/docs/internal-dnsより引用)

また、GCPでは/etc/hostsファイルも上書きされるので、FQDNの設定が通常のやり方ではできませんでした。

FQDNを設定するには、/etc/dhcp/dhcpclient.conf

/etc/dhcp/dhcpclient.conf
supersede host-name "<fqdn>";

を追加する必要がありました。この結果を用いて、/etc/dhcp/dhclient-exit-hooks.d/google_set_hostnameスクリプトで/etc/hostsを上書きしていました。

ここで設定したhost-nameは、hostname --fqdnの結果に影響します。これは、SSHでKerberos認証を行うときなどに使われる値なので、重要な人もいると思います。

余談

ifupdownは昔からある仕組みらしいです。Debian系では/etc/network/interfaces、CentOS系では/etc/sysconfig/network-script/ifcfg-ethxが設定ファイルです。NetworkManagerはifupdownと競合する部分については、ifupdownの設定を尊重するみたいです。ifupdown でお世話をしているインターフェースをnmcli d showでみると、Unmanagedとなります。

NetworkManagerを無効化する記事はたくさんあるのですが、ifupdownを無効化する記事はあまり見ません。NetworkManagerも結構便利でいいんですが。。

感想

ネットワークはJUST WORKで良いのですが、それがなかなか難しい。。。