Edited at

mDNSを使ってローカルDNSサーバーを廃止する


はじめに

ローカルネットワーク内のホスト名でのアクセスはNetBIOS時代から試みてきたものの、WindowsとmacOSの間は統一された規格がなく相互通信が出来ない状態が続いてきた。

突然消失するかもしれないブログさんの記事の説明を拝借

その状態が、Windows10 1803(April 2018 Update/Redstone 4/RS4)が出荷されたことで、ようやくmDNSという規格により統一され、Windows macOS Linux間のホスト名でのアクセスが可能になりました。

mDNSはDNSの代わりにIPアドレスを返してくれるため、今までローカルにDNSサーバーを立て、ローカルエリア内の名前解決をされていた方はDNSサーバーの撤去が出来ます。

Windows10 1803でもほぼ動作に支障ない状態でしたが、Windows10 1903(Windows 10 May 2019 Update/19H1)ではResolve-DnsNameコマンドの動作が改善されています。まだ完全ではないのですが、おかしなIPを返すことはなくなりました。

後述するsshの標準搭載と合わせて、Windows10 1903はLinuxと非常に相性が良いOSとして仕上がっているので、いろいろバグレポートは上がってきているものの、アップグレードして損はなかったと筆者は考えている。


サーバー、デスクトップ用OSからの検索

macOS、Windows、Linuxでは、相互にホスト名での通信が可能です。

ブラウザに「http://hogehoge.local」と入力したり、sshに入るのに「ssh root@hogehoge.local」と入力したりすればアクセスできます。もちろんサーバー側にサービスが立ち上がっていることが前提です。

後記しますが、pingは相互にホスト名で打ち合うことが可能です。

以下では、名前だけ解決したい場合のコマンドと設定方法をまとめます。


クライアントがmacOSの場合

mDNSのご本家のAppleであれば、なんの設定もなく名前が引けます。ただし、IPv6は他のOSと違い0を省略せずフル表記されたものを返してきます。

明示せずに名前解決をするとmacOSだけIPv4が優先で通信しようとします。IPv4で通信できないとIPv6でフォールバックしてくれるようです。

macOSに向かっての問い合わせは、IPv6では応答しません。

また、digを用いた正引き/逆引きもIPv6では応答がありません。

一応コマンドだけは書いておく

#正引き(1)

$ dns-sd -G v4v6 hogehoge.local
DATE: ---Tue 01 May 2018---
12:34:56.789 ...STARTING...
Timestamp A/R Flags if Hostname Address TTL
12:34:56.789 Add 3 7 hogehoge.local. 192.168.1.10 120
12:34:56.789 Add 2 7 hogehoge.local. 2100:000A:000A:0000:0000:0000:0001:0001%<0> 120

#正引き(2)

$ dig hogehoge.local. @224.0.0.251 -p 5353
; <<>> DiG 9.10.6 <<>> hogehoge.local. @224.0.0.251 -p 5353
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7851
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;hogehoge.local. IN A

;; ANSWER SECTION:
hogehoge.local. 10 IN A 192.168.1.10

;; Query time: 1 msec
;; SERVER: 192.168.1.10#5353(224.0.0.251)
;; WHEN: Thu Aug 01 21:00:36 JST 2019
;; MSG SIZE rcvd: 46

$ dig hogehoge.local. @ff02::fb -p 5353
; <<>> DiG 9.10.6 <<>> hogehoge.local. @ff02::fb -p 5353
;; global options: +cmd
;; connection timed out; no servers could be reached

#逆引き

$ dig -x 192.168.1.10 @224.0.0.251 -p 5353
; <<>> DiG 9.10.6 <<>> -x 192.168.1.10 @224.0.0.251 -p 5353
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64092
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;10.1.168.192.in-addr.arpa. IN PTR

;; ANSWER SECTION:
10.1.168.192.in-addr.arpa. 10 IN PTR hogehoge.local.

;; Query time: 1 msec
;; SERVER: 192.168.1.10#5353(224.0.0.251)
;; WHEN: Thu Aug 01 21:15:52 JST 2019
;; MSG SIZE rcvd: 69

$ dig -x 2100:a:a::1:1 @ff02::fb -p 5353
; <<>> DiG 9.10.6 <<>> -x 2100:a:a::1:1 @ff02::fb -p 5353
;; global options: +cmd
;; connection timed out; no servers could be reached


クライアントがwindows10の場合

Windows10 1607/1703/1709(RS1~3)でもmDNSが実装されていたようですが、ファイアウォールの設定がおかしかったようです。以下の手順でファイアウォールを正しく設定すれば正常に動くようになるようです。

マイクロソフト Network & AD サポートチーム公式ブログ参照

Windows10 1803(April 2018 Update/Redstone 4/RS4)では初期状態でmDNSが正常に動くようになりました。

Windows10 1511以前(8.1/7/vistaも含む)でmDNSが使いたい場合は「Bonjour for Windows」をインストールしてください。ただし、こいつはIPv4でしか引けません。

Windows10 1803(April 2018 Update/Redstone 4/RS4)でも少しバグが残っており、Resolve-DnsNameで名前を引いてもIPv6でしか名前を返してくれないという問題がありました。ping,sshなどではIPv4でも正常に動作するのですが、一部のコマンドではIPv6でしか動作しない可能性があります。ちゃんと調査は出来ていません。(申し訳ないです)

ちなみにWindows10 1803にBonjourをインストールすると不具合大発生の模様。中には解決に1日消費した人もいるそうで・・・。それならWindowsを初期化したほうが早くないってなります。筆者も何台か初期化で問題解決してます。

Windows 10 April 2018 Update (バージョン 1803) で共有フォルダの不具合【Ver1803】

1803 にアップデート後,Bonjour (mDNS) で IPv6 のアドレス解決ができません。

windows10からLAN接続されている機器に対してpingが通らないのである。

さて正常動作状態であれば、Windows PowerShellを開いてResolve-DnsNameで名前が引けます。このコマンドはIPv6/4の両方で問合せを行うコマンドです。逆引きも可能です。

ちなみに、おなじみnslookupではIPv6でもIPv4でも引けませんので悪しからず。

Resolve-DnsNameは通常のサーバー問合せを行うDNSも回答できるため、nslookupはもう用済みかも・・・。

linuxやmacOSに対してでも.localを省略して問い合わせができます。

Windows10->Linuxの場合に、Resolve-DnsName hogehoge.local -Type Aで問い合わせが失敗する場合でもResolve-DnsName hogehoge -Type Aは成功したりします。このバグは1903でも健在です。

Windows10->Windows10でResolve-DnsName hogehoge.local -Type Aを行うと、わけのわからないアドレスを返してきます。この場合でもResolve-DnsName hogehoge -Type Aならちゃんと動作します。このバグは1903では解消されています。1809でも2019/4には治っていました。1809に更新当初ば発生していたのですが、修正されたのですかね?未確認ですが。

結論的にResolve-DnsNameはどんな時でも.localを付けない方をお勧めします。

.localをつけると動きがおかしいのは、逆引きしたときには.localがついていないアドレスを返してくるのと関係があるものと筆者は推察しています。

#正引き

> Resolve-DnsName hogehoge
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
hogehoge.local AAAA 120 Answer 2100:a:a::1:1
hogehoge.local A 120 Answer 192.168.1.10

ちなみにWindows10 1903でも逆引きはIPv4のみでIPv6は非対応です。IPv6でもPTRレコードを問い合わせには行っているようだが、残念ながらエラーとなる。

#逆引き

> Resolve-DnsName 192.168.1.10
Name Type TTL Section NameHost
---- ---- --- ------- ---------
10.1.168.192.in-addr.arpa. PTR 1200 Question HOGEHOGE

> Resolve-DnsName 2100:a:a::1:1
Resolve-DnsName : 1.0.0.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.A.0.0.0.A.0.0.0.0.0.1.2.ip6.arpa : DNS 名がありません。
発生場所 行:1 文字:1
+ Resolve-DnsName 2404:7a87:e900:1600::1:1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (1.0.0.0.1.0.0.0....0.1.2.ip6.arpa:String) [Resolve-DnsName], Win32
Exception
+ FullyQualifiedErrorId : DNS_ERROR_RCODE_NAME_ERROR,Microsoft.DnsClient.Commands.ResolveDnsName


クライアントがLinuxの場合

まずパッケージがインストールされていないと始まらないので、avahiとnss-mdnsをインストールします。Ubuntu18.04やDebian9やCentOS7では標準でインストールされている模様ですが、念のため以下のコマンドでインストールしてください。

$ apt install avahi-daemon libnss-mdns

$ yum install avahi avahi-tools nss-mdns

標準だとIPv4では正常に動作しますが、IPv6ではIPv4射影アドレスで返事をしてくるので、nsswitch.confのhostsの項目を編集します。

# nano /etc/nsswitch.conf

hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4

上記を以下に書き換え
hosts: files mdns_minimal [NOTFOUND=return] dns mdns

これで設定完了です。

あとは、Terminalからgetentコマンドで名前を引くことが出来ます。

動作は明示しないとIPv6通信が優先されます。

インストールすればdigコマンドも使えるが、使い方はmacOSの項で説明したため、それより簡単なavahi-resolveを使う。

#正引き(1)

$ avahi-resolve -n hogehoge.local
hogehoge.local 2100:a:a::1:1

$ avahi-resolve -n hogehoge.local -4
hogehoge.local 192.168.1.10

#正引き(2)

$ getent ahosts hogehoge.local
2100:a:a::1:1 STREAM hogehoge.local
2100:a:a::1:1 DGRAM
2100:a:a::1:1 RAW
192.168.1.10 STREAM
192.168.1.10 DGRAM
192.168.1.10 RAW

#逆引き

$ avahi-resolve -a 2100:a:a::1:1
2100:a:a::1:1 hogehoge.local

$ avahi-resolve -a 192.168.1.10
192.168.1.10 hogehoge.local


サーバー、デスクトップ用OS全般

設定が終わってしまえば、相互にホスト名での通信が可能です。

例としてWindowsでpingをIPv6で送信してみます。macOSの場合はping6コマンドを使ってください。

ちなみに明示しない場合は、WindowsとLinuxはIPv6でmacOSはIPv4でアクセスする模様です。

> ping -6 hogehoge.local

hogehoge.local [2100:a:a::1:1]に ping を送信しています 32 バイトのデータ:
2100:a:a::1:1 からの応答: 時間 =2ms
2100:a:a::1:1 からの応答: 時間 =1ms
2100:a:a::1:1 からの応答: 時間 =1ms
2100:a:a::1:1 からの応答: 時間 =1ms

2100:a:a::1:1 の ping 統計:
パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 1ms、最大 = 2ms、平均 = 1ms

もちろんping+IPv4でも問題ありません。

> ping -4 hogehoge.local

hogehoge.local [192.168.1.10]に ping を送信しています 32 バイトのデータ:
192.168.1.10 からの応答: バイト数 =32 時間 =1ms TTL=63
192.168.1.10 からの応答: バイト数 =32 時間 =1ms TTL=63
192.168.1.10 からの応答: バイト数 =32 時間 =1ms TTL=64
192.168.1.10 からの応答: バイト数 =32 時間 =1ms TTL=64

192.168.1.10 の ping 統計:
パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 1ms、最大 = 1ms、平均 = 1ms

自身に設定されている名前がわからない場合は、hostnameコマンドで調べれます。(macOS Windows Linux共通)

この名前に.localを付ければ相手から名前を調べてもらえます。

> hostname

hogehoge

あと、OpenSSHには隠しオプションがあって、「ssh -4 root@hogehoge.local」で明示的にIPv4でアクセスできます。

OpenSSHはLinux版はもとより、macOS Sierra以上、Windows10 1803以上でv7が標準搭載されていますので、気兼ねなく使うことが可能です。

問い合わせ元  
優先通信方式

macOS10.14 Mojave
IPv4

Windows10 1903
IPv6

Ubuntu18.04.2
IPv6(nsswitch.confを書き換えた場合)

問い合わせ先  
発生する問題

macOS10.14 Mojave
IPv6で応答しない

Windows10 1903
.localをつけると動作がおかしい場合がある

Ubuntu18.04.2
特に問題なし

まとめると以下のようになります。

問い合わせ元\先
macOS10.14 Mojave
Windows10 1903
Ubuntu18.04.2

macOS10.14 Mojave
特に問題なし
特に問題なし
特に問題なし

Windows10 1903
IPv4を明示しないと通信不能
.localをつけない方が良い
.localをつけない方が良い

Ubuntu18.04.2
IPv4を明示しないと通信不能
特に問題なし
特に問題なし


モバイル用OSの場合

まだ問題があるのが、モバイル用のOSである。

以下、動作状況だけ説明しておく。


iOSの場合

ブラウザに「http://hogehoge.local」と入力したり、sshアプリなどで、hogehoge.localでアクセスは可能である。

しかし、iOSに対してホスト名でのアクセスが出来ない。

例えば、ping iPhone's-ip-addressはpingが返ってくるが、ping iPhone's-hostname.localでは名前解決に失敗する。


Androidの場合

まったく動かない。

Android9でも対応していただけないので、自力でアプリを作ってみました。

Hostnameを入力するとIPアドレスをv6かv4で返してくれる簡単なソフトです。面倒なので広告もなしです。

https://play.google.com/store/apps/details?id=com.dokoden.dotlocalfinder&hl=ja

だけど、OSレベルで対応してくれると、こんな面倒はないんだけどな。Qなら治っているのかな?

google様・・・お願い


ボヤキ

ああ、熱心なApple信者も、UbuntuやDebianな人も、中にはAndroid好きな人もメジャーアップデートやLTSが出るたびに初期化の儀式を行っていたけど、Windowsもその流れなのね。

後方互換こそWindowsの強みだった時代はどこへやら。

オシャレが売りのmacOSですが、OSインストール時にユーザーアカウントHOGEに設定するとHOGEnomakku.localというオシャレとは程遠い名前になるのは如何なもんじゃいな。