概要
当記事は、Dockerを使って最速でDNSを構築してみたを参考にLAN内にDNSサーバーを立てた時に、結構色々と躓いたところがあったので、それらをメモ程度に書いた記事である。
環境
- CoreDNS 1.10.1 (Docker)
- Ubuntu 22.04 LTS(デスクトップ版, 20.04からのアップグレード)
- Docker 23.0.5
authbind 2.1.3
動機
ドメイン名をLAN内のIPアドレスに解決するには、/etc/hosts
を記述するのが定石であるが、これを組み込み機器のような自分で設定をいじれないマシンについて行いたい。
手順
Dockerのインストール
Dockerはcomposeの扱いが変わったので、Ubuntuのリポジトリからではなく、Dockerのリポジトリから入れたものを以前から使っている。
root権限がなくても使用可能にしてある。docker-ce-rootless-extrasパッケージとかがあるようだが、こういうパッケージが出来る前にdockerグループを作成する方法で実現しているので、ここでは深入りしない。よその記事をあたって欲しい。
CoreDNSサーバーの作成
といっても、Dockerを使って最速でDNSを構築してみたをほぼそのまま実施しただけ。
変えた点としてはforward . 8.8.8.8:53
はルーターのアドレスにしたことと、ドメイン名未取得なので、example.comのような、いわゆる予約済みドメイン名のサブドメインを使用したこと。
組み込み機器によっては解決すべきドメイン名が固定というケースが多いかもしれない。
Privlieged Portの問題
組み込み機器では当然DNSのポート番号は53番から変更できない。Ubuntuに限らずLinux系のOSでは、1024番未満のポートを使用するアプリケーションにはroot権限を要求される…のだが、前述したdocker-ce-rootless-extrasの影響なのか何なのか普通にホスト側1024番未満のポートが使用できた。
もちろんファイアウォールの開放は別途行った。
systemd-resolved.serviceの停止
実際にはDockerを起動するとPrivlieged Portの問題がなくてもport 53 is already used.
と言われてうまく行かない。調べると
$ sudo systemctl disable systemd-resolved.service
$ sudo systemctl stop systemd-resolved.service
で元からあるサービスを止めないといけないらしい。systemd-resolved自体はDNSクライアントで、止めるとそのホストマシン自体は名前解決が出来なくなる。
正しい解決法かはわからないが、この辺りを参考に、/etc/resolv.conf
内の127.0.0.53
を127.0.0.1
にして再起動したら何とかなった。
systemd-resolvedをDNSサーバーに出来たらCoreDNSいらないのでは、という考えが今頭をよぎったが試していない。systemd-resolvedの説明を少し見た限りでは"to local applications"と書かれているので、外部のマシンに公開して大丈夫なのか分からないし。
Docker起動
上記2つの問題を乗り越えた上で、compose.yaml
のあるフォルダに移動し、
$ docker compose up -d
で起動に成功。
DHCPサーバーへの登録
ルーターのDHCPサーバー機能を使っているので、ルーターの設定をいじった。
DHCP設定で通知するプライマリDNSサーバーのアドレスを新規DNSサーバーにして、元のプライマリDNSサーバー(ルーターのアドレス)をセカンダリDNSサーバーに移して終わり。
後は組み込み機器がDHCPからローカルIPアドレスを取得する時にDNSサーバー情報も一緒に受け取って設定するはず。
組み込み機器を再起動させた後に、ルーターの設定画面でDHCPサーバーのリース期限を表示すると、組み込み機器が情報を更新したか分かるかもしない。
動作確認
PCから
Dockerホスト以外のPCからもdig
などのコマンドで動作確認出来た。
Ubuntuからnslookup
で確認すると、DNSキャッシュが効いているのかすぐに反映されなかったが、ネットワーク接続を切断して再接続するとDNSサーバー側での変更が反映された。
組み込み機器から
機会があれば別途書くが、組み込み機器側の動作が予想と異なっていたので、残念ながら自分自身の組み込み機器からの動作確認はできていない。
また、自分自身の目的が果たせず運用をやめてしまったので長期間の運用確認などもしていない。
考察
あまりないとは思うが、組み込み機器がDHCPからのDNSサーバー指定を使用せずに8.8.8.8
など固定されたDNSを使用している場合や、そもそも機器内部で名前解決が済んでしまっている場合などは、この方法は使えない。
組み込み機器にローカルIPアドレスへのアクセス制限がかけられているということはあるかもしれない。
参考: authbind
Linuxの1024番未満のポート使用制限の回避方法はマニュアルにもあるようにCAP_NET_BIND_SERVICE
を使うのが定番のようだが、さらに調べるとauthbindを使う方法というものが見つかり、Ubuntuのリポジトリからインストール可能。
$ authbind docker compose up -d
で起動でき、停止はdocker copose down
でauthbindなしで出来る。実際にはDockerに限って言えばauthbind自体がいらなかったようだ…orz
改訂履歴(表現の修正などは除く)
- 2023/5/6: 元となる記事の作成開始。
- 2023/5/7: 上記から分離独立。authbind不要と判明して改訂。投稿。
- 2023/5/14: 環境に補足。