DNSmasq を使うと iPhone/iPad 等で名前解決できない?

背景: DNSmasq でローカル・ネットワークの名前を簡単に解決

ローカル・ネットワークのサーバで DNSmasq を走らせ,DNS サーバとして指定しておくと,ローカル・ネットワーク上のクライアントから,サーバを 192.168.1.1 のような IP アドレスではなく,www.local のように名前で指定できて便利である.クライアントからの DNS 問い合わせ (クエリ) に対し,サーバの /etc/hosts に書かれているホスト名なら解決して返事してくれるのだ (解決できなければ外部の DNS サーバにフォワードする).内向け DNS サーバを建てて設定ファイルを書く,という作業が不要だ.

問題: Apple 製品からだけ,うまくいかない

ところが,LinuxWindows, Android といったクライアントは問題なく www.local といったローカルなホスト名が解決できるが,Apple 製の MacOS/iOS 搭載のクライアント (iPhone/iPad/iPod touch 等) は www.local を解決できないようなのである.Apple 製品だけというのが理由が分からなくてしばらく困っていた.

原因: ".local" ドメインは特別扱い

Apple 製品は "local" というトップドメインを特別扱いするようだ. "www.local" は通常の DNS ではなく Apple 独自の Bonjour で解決しようとする.

「.local」ドメインを使うと、Bonjourマルチキャスト DNS 機能により、別個の DNS サーバを設置せずにローカルネットワーク上のデバイスを相互に接続できます。
Mac OS X v10.4, 10.5, 10.6:「.local」ホスト名を Bonjour および標準 DNS を介して検索する方法

解決: ".local" 以外を使う

従って,ローカル・ネットワークを示すトップドメインとして ".local" 以外を使えばよい. 例えば ".local-net" を使うことにして,サーバの /etc/dnsmasq.conf に,以下のように書けばよい.

domain=local-net

調査

これは次のような調査で判明した.

DNSmasq にクエリを記録するオプション -q を付けて起動し,システム・ログを観察してみた.
Apple 製品のブラウザから www, www.local, www.local-net を参照すると次のようなログが記録される.

www → dnsmasq: query[A] www from 192.168.1.xx
www.local → 記録なし
www.local-net → dnsmasq: query[A] www.local-net from 192.168.1.xx

すなわち,".local" ドメインに対するクエリが飛ばない.ということは MacOS/iOS が ".local" ドメインを特別扱いしているのだろうということで検索すると,上記のページに到達して,予想があっていることが確認できた.上記ページによると,

末尾が「.local」のドメインのネームリクエストに答えるネームサーバを設定している場合、Mac OS X v10.6 は 自動的に検出します。Macトップレベルドメイン「local」にSOA (Start Of Authority) レコードがあるかどうか確認することによりこれを行います。
Mac OS X v10.4, 10.5, 10.6:「.local」ホスト名を Bonjour および標準 DNS を介して検索する方法

のだそうだが,DNSmasq は検出されなかった.内向きに正式なフルセットの DNS サーバを建てた場合は検出されるのだろうが,DNSmasq は A レコードの問い合わせを横取りして答えるだけの簡易版で,SOA レコードの問い合わせがあるなんて思って作られていないのであろう.もちろん,この単純さが DNSmasq の設計思想なので,DNSmasq はこのままでよい.Apple はうまくやったつもりだったが副作用があったということ.