UbuntuServer16.04->18.04のネットワーク設定と、Unbound on Dockerの話

はじめに

systemd-resolvedとかnetplan.ioとかのネットワークの設定周りで新機軸が投入されまくった18.04ですが、 0からのセットアップならいろいろ罠は少ないので、既存のドキュメントでなんとかなると思います。

しかし、16.04から18.04のアップデートでネットワーク設定を安定させて、 なおかつ、ローカル用のDNSキャッシュサーバを運用するためには、 そこそこ手間がかかるのでここにメモしておきます。

UnboundとはDNSキャッシュサーバです。 なぜUnboundか、というのはWeb上の記事に書き散らされているのでここでは割愛。

netplan.ioの設定をちゃんとやる

netplan.ioyamlによるネットワーク設定の抽象レイヤです。 要するに、うまい具合にUbuntu全体のネットワーク構成をまとめてしてyamlに書けるようにしたもの……。 と言いたいのですが、NetworkManagerが絡んでくると、NetworkManagerに全部投げるという設定を書くだけの クソみたいなファイルに成り下がるので、現状UbuntuServerでしか利潤を享受できていないように見えます。

apt install netplan.ioで入ります。apt install netplanとか書くと謎のパッケージが入ってわけがわからないことになるので、注意してください。

とりあえず疎通が取れるようにするには、まずここから。

neplan.ioを使うならば、ifupdownはとっとと消し飛ばしたほうがいいです。 特に、sysmted-networkd systemd-resolvedの取扱に苦労しますので、潔く消し飛ばすことを推奨します。

/etc/netowrk/interface(.d/\*)?に該当する設定は、なんだかんだいってかなり書けます。 書き方は、 Examples | netplan.ioとかに転がっているので、 ほとんどの構成はこれで問題ないと思います。

ただし、設定ファイルの拡張子をyamlとしないと読み込まれませんし、 YAMLの文法ミスのデバッグはとても厄介なので、エディタのプラグインでうまい具合にすることを推奨します。

上記の2点に関して注意しないと、netplanのデバッグ出力を見て、キーと値の対応関係が壊れた設定や、 中身のない設定を読み込み続けているのに気づくまでに時間を溶かします。それだけ注意。

netplan.ioをここまでして推す理由はとても明快で、 # netplan tryで設定適用がタイムアウトによるロールバック付きでできるからです。 ifupdown時代のエラーが起きたら諦めるシェル芸を毎回せずに済むのは非常に良いことだと思います。 遠隔からのネットワーク設定適用はなるべくしたくないものですが、かなりハードルが下がりました。

resolvconfを消し、systemd-resolvedを動作させる

systemd-resolvedを有効にしたあと、resolvconfを消します。 16.04からのアップデートだとこのパッケージが残っています。 消す順番を間違えると、名前解決ができなくなって、resolv.confに手を入れることになります。

場合によっては、各種設定の問題で正しくsystemd-resolvedが上がってこない場合があるので、ひたすらデバッグします。

/etc/systemd/resolv.confあたりのDNS=にお好みのDNSサーバを入力して、 systemd-resolvedを再起動すればだいたいなんとかなります。

UnboundをDockerで立てる

この項の一番下にdocker-compose.ymlがあります。

今回用いるリポジトリはこれです。 mvance/unbound - Docker Hub

まずネットワーキングについて。 有無を言わさずhostネットワークを使うのはダサいですが、 一つしか立っていないことを保証するには多分これが一番良い手だと思います。

次にポートについて。 systemd-resolvedがスタブリゾルバを立てて53番ポートを専有しているので退いてもらう必要がありますが、 先にこのスタブリゾルバを殺してしまうと、名前解決ができずにイメージを持ってこられません。 予めをpullしておくか、一度ポート専有で立ち上がらないと怒られる必要があります。 イメージを持ってこれたら、/etc/systemd/resolv.confDNSStubListener=noとし、systemd-resolvedを再起動します。

加えて、ポートを空けてもらったはいいが、そのまま標準設定で立ち上げると、 digの結果に;; reply from unexpected source: 127.0.0.1#53, expected 127.0.0.53#53と出ます。 localhostにリゾルバが立つので、ループバックインタフェースを使って問い合わせたものの 応答するアドレスが期待と食い違うので応答を拒否する現象が発生しているわけです。

このイメージでは、/unbound.shに設定が書かれているので、 interface-automatic: yesを設定に追加して、サービスを上げ直します。

これで終わったかと思ったら、さらにひと手間。 設定内にACLがあり、192.168.0.0/16のネットワークセグメントの 一部からのアクセスしか許可しない設定がされているので、 それを修正しておしまいです。

-  access-control: 192.168.1.1/24 allow
+  access-control: 192.168.0.0/16 allow

以上、お疲れ様でした。

version: '2'
services:
  unbound:
    image: mvance/unbound
    network_mode: "host"
    ports:
      - "53:53"
      - "53:53/udp"
    volumes:
      - ${PWD}/unbound/unbound.sh:/unbound.sh
    restart: always