【docker/dnsmasq】docker containerでdnsmasqを起動しワイルドカードDNSを構築する
本記事で行うこと
モチベーション
- 自宅kubernetesでingressを利用しているため、ワイルドカードDNSを構築したい
- メンバー検証用にワイルドカードDNSを構築したい
- bindがやや設定が多いので、最も簡単にワイルドカードDNSを構築したい
git repo
- 参考ように以下repoを用意しています。 github.com
動作確認済環境
- M1 Macbook Air
$ sw_vers ProductName: macOS ProductVersion: 11.1 BuildVersion: 20C69 $ uname -m arm64
- Intel macbook pro 2019
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.7 BuildVersion: 19H15 $ uname -m x86_64
- raspberry pi 3 model b+ ubuntu
$ uname -a Linux ubuntu-pi 5.11.0-1008-raspi #8-Ubuntu SMP PREEMPT Thu May 6 17:46:38 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 21.04 Release: 21.04 Codename: hirsute
- Docker Engine
- Version: 20.10.6
dnsmasq
dnsmasqとは
- 小規模向けのDNSで、あまりDNSの知識がない人でも簡易的に構築可能です。
- dnsmasqを入れたサーバの/etc/hostsに書くだけでも、DNSサーバとして動作します。
- 今回はワイルドカードDNSを構築したいため、専用のconfファイルを使います。
- ロゴはなんだかやらしい・・・
dnsmasq.confの準備
- 以下のようにconfファイルを作成します。
.wc.haku-mai
のように.
を先頭に書くことでその部分がワイルドカードになります。127.0.0.1
の部分がどのドメインで返してほしいIPアドレスになります。test001.haku-mai
のようにフルドメインで書けばそのFQDNが返ります。.wc.haku-mai
、test001.haku-mai
をどちらを先に書いても、想定通り動作します。- ドメインを追加したい場合は、confファイルを編集して、docker containerを再作成すれば良いので簡単です。
dnsmasq.conf
port=53 address=/test001.haku-mai/127.0.0.2 address=/.wc.haku-mai/127.0.0.1 log-facility=/var/log/dnsmasq.log
dnsmasq docker image (Dockerfile)の準備
Dockerfile
- 軽量のalpine linuxを使いdnsmasqをインストールします。
- alpineのバージョンは固定しなくても最新のものであれば動作します。
Dockerfile
FROM alpine:3.13.2 RUN apk update && \ apk upgrade && \ apk add bash dnsmasq && \ rm -rf /var/cache/apk/* && \ mkdir -p /etc/default/ && \ echo -e "ENABLED=1\nIGNORE_RESOLVCONF=yes" > /etc/default/dnsmasq CMD ["dnsmasq","--no-daemon"]
image build
- Dockerfileと同じディレクトリでbuild
- tag名はおすきなものを
$ docker build -t dnsmasq:sample .
dnsmasq docker containerの起動
- 作成した、
dnsmasq.conf
をContainerの/etc/dnsmasq.conf
にbindして、NET_ADMIN権限を付けて起動します。
$ docker run -d -p 53:53/tcp -p 53:53/udp --cap-add=NET_ADMIN \ -v $PWD/dnsmasq.conf:/etc/dnsmasq.conf \ --name dnsmasq dnsmasq:sample
動作確認
単一ドメイン
- 想定通り設定したIPが返ってくることがわかります。
nslookup
$ nslookup test001.haku-mai 127.0.0.1 Server: 127.0.0.1 Address: 127.0.0.1#53 Name: test001.haku-mai Address: 127.0.0.2
dig
$ dig test001.haku-mai @127.0.0.1 ; <<>> DiG 9.10.6 <<>> test001.haku-mai @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47722 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;test001.haku-mai. IN A ;; ANSWER SECTION: test001.haku-mai. 0 IN A 127.0.0.2 ;; Query time: 6 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Oct 10 15:38:37 JST 2021 ;; MSG SIZE rcvd: 61
ワイルドカードドメイン
- ワイルドカード部分に何を入れても想定通り設定したIPが返ってくることがわかります。
nslookup
$ nslookup yakiniku.wc.haku-mai 127.0.0.1 Server: 127.0.0.1 Address: 127.0.0.1#53 Name: yakiniku.wc.haku-mai Address: 127.0.0.1 $ nslookup tabetai.wc.haku-mai 127.0.0.1 Server: 127.0.0.1 Address: 127.0.0.1#53 Name: tabetai.wc.haku-mai Address: 127.0.0.1
dig
$ dig yakiniku.wc.haku-mai @127.0.0.1 ; <<>> DiG 9.10.6 <<>> yakiniku.wc.haku-mai @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51347 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;yakiniku.wc.haku-mai. IN A ;; ANSWER SECTION: yakiniku.wc.haku-mai. 0 IN A 127.0.0.1 ;; Query time: 6 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Oct 10 15:41:44 JST 2021 ;; MSG SIZE rcvd: 65 $ dig tabetai.wc.haku-mai @127.0.0.1 ; <<>> DiG 9.10.6 <<>> tabetai.wc.haku-mai @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49729 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;tabetai.wc.haku-mai. IN A ;; ANSWER SECTION: tabetai.wc.haku-mai. 0 IN A 127.0.0.1 ;; Query time: 5 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Oct 10 15:42:00 JST 2021 ;; MSG SIZE rcvd: 64
別の端末(Macなど)から→DNSサーバにアクセスする場合
- 例えば、自宅プライベートアドレス帯の192.168.XXX.XXXが割り振られているサーバで動作させての場合、
127.0.0.1
の部分を動作させているIPアドレスを指定します。
$ nslookup test001.haku-mai 192.168.XXX.XXX $ dig yakiniku.wc.haku-mai @192.168.XXX.XXX
Mac で DNS を記載する場合の例
*「ネットワークの環境設定を開く」-> 「Wi-Fi」 -> 「詳細」 -> 「DNS」タブから DNSサーバのIP(例:192.168.XXX.XXX)を追加
既存で書いてあるDNSは消すとgoogkeとかにアクセスできなくなるので注意してください。
間違えてけしちゃった場合は、今回追加したものも全部一度消してしまえば戻ります。(自宅ルーターに設定してあるものが入ります)
- DNS キャッシュクリア
$ sudo killall -HUP mDNSResponder
iPhone で DNS を記載する場合の例
*「設定」-> 「Wi-Fi」 -> 接続中のwifiの「infoマーク」 -> 「DNSを構成」-> 「手動」に切り替えて DNSサーバのIP(例:192.168.XXX.XXX)を追加
実際にiPhone(safari)で自作のWEBアプリにアクセスするためには、SSL証明書が必要になります。※自己証明でも個別でプロファイルをインストールすることで可能
(自己証明書の作成&インストールはどこかで書きます)
あとがき
- 自宅環境ではraspberry piをDNSサーバとして使っており、自宅PC/スマホにはraspberry piをDNSサーバとして見れるように追加しています。
- ここまで準備しておくと、kubernetesでIngressを楽に使うことができます。
- 自宅では様々な自作アプリをkubernetes上で動作させていて、半年近く立っていますが、何も問題なく動作しています。
- DNSってちょっとハードルあるように感じますが、簡易的に動かすにはdnsmasqで十分だと感じました。
- スペックが上がっているraspberry pi 4がほしいです。