haku-maiのブログ

インフラエンジニアですが、アプリも作ります。

【docker/dnsmasq】docker containerでdnsmasqを起動しワイルドカードDNSを構築する

f:id:n-guitar:20211010180720p:plain:w800

本記事で行うこと

モチベーション

git repo

  • 参考ように以下repoを用意しています。 github.com

動作確認済環境

$ 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
$ 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ファイルを使います。
  • ロゴはなんだかやらしい・・・

f:id:n-guitar:20211010142749p:plain:w400 ja.wikipedia.org

dnsmasq.confの準備

  • 以下のようにconfファイルを作成します。
  • .wc.haku-maiのように.を先頭に書くことでその部分がワイルドカードになります。
  • 127.0.0.1の部分がどのドメインで返してほしいIPアドレスになります。
  • test001.haku-maiのようにフルドメインで書けばそのFQDNが返ります。
  • .wc.haku-maitest001.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

動作確認

  • 起動したサーバ/Mac上で確認するためにはDNSを指定してnslookup/digを行います。

単一ドメイン

  • 想定通り設定した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

MacDNS を記載する場合の例

*「ネットワークの環境設定を開く」-> 「Wi-Fi」 -> 「詳細」 -> 「DNS」タブから DNSサーバのIP(例:192.168.XXX.XXX)を追加

  • 既存で書いてあるDNSは消すとgoogkeとかにアクセスできなくなるので注意してください。

  • 間違えてけしちゃった場合は、今回追加したものも全部一度消してしまえば戻ります。(自宅ルーターに設定してあるものが入ります)

f:id:n-guitar:20211010155145p:plain:w400

  • DNS キャッシュクリア
$ sudo killall -HUP mDNSResponder

iPhoneDNS を記載する場合の例

*「設定」-> 「Wi-Fi」 -> 接続中のwifiの「infoマーク」 -> 「DNSを構成」-> 「手動」に切り替えて DNSサーバのIP(例:192.168.XXX.XXX)を追加

  • 実際にiPhone(safari)で自作のWEBアプリにアクセスするためには、SSL証明書が必要になります。※自己証明でも個別でプロファイルをインストールすることで可能

  • (自己証明書の作成&インストールはどこかで書きます)

f:id:n-guitar:20211010160214p:plain:w300

f:id:n-guitar:20211010160321p:plain:w300

f:id:n-guitar:20211010160420p:plain:w300

あとがき

  • 自宅環境ではraspberry piDNSサーバとして使っており、自宅PC/スマホにはraspberry piDNSサーバとして見れるように追加しています。
  • ここまで準備しておくと、kubernetesIngressを楽に使うことができます。
  • 自宅では様々な自作アプリをkubernetes上で動作させていて、半年近く立っていますが、何も問題なく動作しています。
  • DNSってちょっとハードルあるように感じますが、簡易的に動かすにはdnsmasqで十分だと感じました。
  • スペックが上がっているraspberry pi 4がほしいです。