Dockerでdnsmasqを使ってワイルドカードでサブドメインを使う

開発しているとプロジェクトごとにproject1.localhost project2.localhostのようにサブドメインで127.0.0.1にアクセスしたり
社内サーバに適当なドメイン名でアクセスしたい場合にhostsファイルを使っています。

しかし、使いたいサブドメインが増えるたびにhostsに追記するのもめんどくさい。
ワイルドカードを使いたいけどhostsはワイルドカードに対応していない。

そこで、dnsmasqという軽量DNSサーバをDockerで起動してワイルドカードでアクセスできる環境を作ってみました。

環境

Docker 19.03.6

dnsmasqの設定と起動

dnsmasqの起動

docker run -d -p 53:53/tcp -p 53:53/udp --cap-add=NET_ADMIN \
--restart=unless-stopped --name dns andyshinn/dnsmasq \
-D -b --local=/localhost/ -E --domain=localhost \
-A /.example.com/192.168.1.100 \
-A /.localhost/127.0.0.1

-Aのホスト名/アドレスを必要なだけ追記すればOK。

設定値

/etc/dnsmasq.confに設定を書いてもOKだが、引数で指定して起動させると簡単。

-D domain-needed ホスト名だけの名前解決に上位DNSを使用しない
-b bogus-priv プライベートIPアドレスの逆引きに上位DNSを使用しない
-E expand-hosts ドメイン名を自動的に付与する

Aレコードの登録
-A /dev.example.com/192.168.1.100
-A /project1.localhost/127.0.0.1

ワイルドカードで名前解決させる場合
-A /.example.com/192.168.1.100
-A /.localhost/127.0.0.1

DNSの設定

Linux

/etc/resolv.confを編集してnameserver 127.0.0.1を上位に追記。

nameserver 127.0.0.1
nameserver 8.8.8.8

Windows

設定→ネットワークとインターネット→アダプターのオプションを変更する

インターネット プロトコル バージョン4(TCP/IPv4)のプロパティにある
DNSサーバーの設定で
優先DNSサーバーに127.0.0.1を指定。
代替DNSサーバーにデフォルトゲートウェイアドレスや8.8.8.8等のDNSサーバのアドレスを指定。

IPv6のDNSも指定しておかないと名前解決にIPv6を使用されてしまうためIPv6のDNSサーバの指定もしておく。

インターネット プロトコル バージョン6(TCP/IPv6)のプロパティにある
DNSサーバーの設定で
優先DNSサーバーに::1を指定。
代替DNSサーバーにデフォルトゲートウェイアドレスや2001:4860:4860::8888等のDNSサーバのアドレスを指定。

確認

$ dig dev.example.com

; <<>> DiG 9.11.3-1ubuntu1.11-Ubuntu <<>> dev.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14995
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;dev.example.com.          IN      A

;; ANSWER SECTION:
dev.example.com.   0       IN      A       192.168.1.100
$ nslookup project1.localhost
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   project1.localhost
Address: 127.0.0.1

まとめ

dnsmasqをDockerで起動しておくとローカルのDNSサーバが簡単に構築できるので、
毎回hostsに追記しないで済むようになりました。

--restart=unless-stoppedオプションを付けて起動しているのでPCを再起動しても自動で立ち上がってくれます。

複数サービスを起動している場合はNginxやVirtualHost等で振り分けてしまえばOKです。