Unbound を Docker で構築したのでまとめてみた。
Contents
背景
自分のデスク周りのローカルネットワーク、オフィスのイントラネットや実機環境など、
異なるネットワークやインターフェースから同じ名前で、
各々のサーバーにアクセスできるようにしたかった。
Unbound とは?
DNSキャッシュサーバーと呼ばれるものみたいです。
Bind とか Dnsmasq とか、その辺の近い機能を有するもののなかで、
安全性や設定の手軽さのバランスがよさそうなのでチョイス。
解説できるほど詳しく各々の差も分かっていないので、自分で調べてください。
環境
- Ubuntu Server 20.04
- (Rootless-) Docker (導入)
Ubuntu 18.04以降特有の対処 (systemd-resolved) などがあるので一応。
事前準備
Ubuntu 18.04 以降(?)では、例えば $ nslookup hep.techwp.net
などとすると、
Address: 127.0.0.53#53
Non-authoritative answer:
Name: hep.techwp.net
Address: xxx.xxx.xxx.xxx
というような出力が得られる。
ネットワークのDNS設定は、各々の環境により別の値が設定されていると思うが、
答えているのは 127.0.0.53
となっている。
このように Ubuntu 18.04 以降(?)では名前解決に systemd-resolved.service が一枚噛んでいる。
これにより Unbound を設定した際に干渉するので先にこれを解決する。
具体な修正事項は以下。
- DNSキャッシュ(?)を目的としてポート53を使用してしまう
- 名前解決に割り込むために /etc/resolv.conf 周りを勝手に強制的に随時書き換える
これらを順に解消していく。
ポート53の解放
/etc/systemd/resolved.conf
内でDNSStubListener=yes
をno
に書き換える$ sudo systemctl restart systemd-resolved.service
これをやると systemd-resolved.service
によって設定されていた中継(127.0.0.53)が機能しなくなり、
$ nslookup hep.techwp.net
などとしても名前解決ができなくなるので、
これをバイパスするようにする。
resolv.conf 周りの修正
/etc/resolv.conf
は /run/system/resolve/stub-resolv.conf
へのリンクになっている。
$ sudo unlink /etc/resolv.conf
$ sudo ln -s /run/system/resolve/resolv.conf /etc/
この resolv.conf には、ネットワークで設定した nameserver, search が記述されているので、
$ nslookup hep.techwp.net
には設定されている nameserver が直接応答するようになる。
ただし、リンクを張ったこの resolv.conf 自体も systemd-resolved に管理されているので、
このファイルを直接編集しても、事あるごとに勝手に書き換えられてしまうので注意が必要(後述)。
Unbound のセットアップ
今回hは、Unbound の dockerコンテナとして mvance/unbound を利用した。
他にも klutchell/unbound もあるようだ。
# 他のアーキテクチャもサポートしているので後者の方が汎用的かも?
docker-compose.yml
なんとなく全て docker-compose でやっているので、以下の設定ファイルを用意した。
1 2 3 4 5 6 7 8 9 10 11 12 |
version: '3' services: unbound: image: mvance/unbound:latest container_name: unbound ports: - '53:53' - '53:53/udp' volumes: - './unbound:/opt/unbound/etc/unbound/' restart: always |
起動
docker-compose up [-d]
で起動できる。
最初に起動するときはログ出力が確認できるので '-d' は付けずに起動した方がよいかも。
実際、最初の起動は失敗する。
デフォルトの unbound.conf
で include されるファイルが unbound/ 内に存在しないためだ。
自動生成される unbound/unbound.conf
末尾の include: ~.conf
を外すか、
当該ファイルを生成すれば起動するようになる。
各種 *.conf の設定
必要なところのみを変更していく。
1 2 3 4 |
access-control: 127.0.0.1/32 allow access-control: 192.168.0.0/16 allow access-control: 172.16.0.0/12 allow access-control: 10.0.0.0/8 allow |
デフォルトでは localhost と プライベートIPアドレスに対して全開にしてある。
適宜各々の環境に合わせて限定する(閉じる)とよりセキュアかも?
閉じる際は、docker network は残しておくように注意する。
1 2 3 4 |
forward-zone: name: "." forward-addr: 8.8.8.8 forward-addr: 8.8.8.4 |
知らない名前については上位に再帰的に問い合わせる。
上記は Google Public DNS の例。
あとは適宜 local-data
, local-data-ptr
など必要に応じて個別にを設定する。
例えば local-data: "hep.techwp.net. IN A 192.168.0.2"
などとして、
この Unbound を参照しているローカルのマシンから hep.techwp.net へ参照させて、
ローカルの別の開発機(?) をアクセスさせることができる。
ホスト名の末尾に '.'(ドット) が必要なので注意。
(逆引きが必要な場合は local-data-ptr
も適宜設定)
詳しい設定方法は公式ドキュメントなどを参照してください。
私はローカルネットワーク内での利用前提なので、
とりあえず目的が達成できるように動けばよいという感じになっています。
公開する場合は、セキュリティ関連の設定を確認した方がよいかもしれません。
動作確認
$ nslookup hep.techwp.net 127.0.0.1
などとして、名前解決ができればOK。
local-data
などを設定した場合は、これらの設定が反映されているかも同様に確認できる。
システムへの反映
nameserver として、今回作成した unboundコンテナを指定する (127.0.0.1@53)。
前述のように /run/system/resolve/resolv.conf は systemd-resolved に管理され、随時書き換えられるので、
nameserver はネットワーク(netplan)の設定から行う。
具体的には /etc/neplan/xxxx.yaml
に nameservers: addresses: - 127.0.0.1
を追加する。
$ sudo netplan apply
で適用後、$ nslookup hep.techwp.net
などとして 127.0.0.1 が答えれば完成です。