Windows 名前解決の順序
こんにちは。Wndows プラットフォーム サポート担当の石丸です。
今日はネットワーク通信を円滑に行うためには欠かせない名前解決が、Windows ではどのような優先順位で行われるかをご紹介します。
一般的に名前解決と言うとまず DNS を思い浮かべるかもしれませんが、Windows では DNS 以外でもブロードキャストや WINS サーバー、HOSTS ファイル、LMHOSTS ファイルなどの様々な仕組みが使われています。このため、自分が今一体何を使って名前解決を行っているかを混乱してしまうかもしれません。システムの設計段階で正しく名前解決が行われる順序を把握しておかないと、突然目的のホストとの通信が行えなくなったりと思いもよらないトラブルの原因となってしまうこともあります。
1. Winsock (Windows Socket)
と NetBIOS Windows ではネットワーク通信を行うための基本的な API を提供するモジュールとして、Winsock と NetBIOS を用意しています。最近では、ほとんどの TCP/IP アプリケーションが Winsock を使用して通信を行っていますが、まだ OS が古いバージョンの頃に開発されたアプリケーションとの互換性を保つために、NetBIOS が使用されることも決して少なくはありません。
** 例えば Windows のファイル共有などに使用される SMB 通信では、Windows Vista がリリースされた現在でも Winsock を使用するDirect Hosting SMB (445/tcp) と NetBIOS over TCP/IP (139/tcp) が併用されています。
重要なのは、Winsock と NetBIOS では、名前解決を行うために使用されるリソースが全く異なることです。このため、どちらの API がネットワーク通信に使用されているかをそれぞれのアプリケーションで確認して、正しい名前解決の順序を把握することが重要となります。
2. Winsock
の名前解決 - Winsock 名前解決の順序
さて、肝心の名前解決の順序ですが、基本的な順序は以下の通りです。
1) DNS リゾルバーキャッシュ (*1) を確認して、指定された名前に対応するレコードがキャッシュされている場合は、そのアドレスを返します。
2) HOSTSファイル (*2) を参照し、指定された名前に対応するレコードが登録されている場合はそのアドレスを返します。
3) 登録されている DNS サーバーに問い合わせを行い、受領したアドレスを返します。
4) 上記 1 ~ 3 で名前解決に成功しない場合は、NetBIOS 名前解決を行います。
(*1) "ipconfig /displaydns" コマンドを使用することで、現在、クライアントが保持している DNS リゾルバーキャッシュを確認できます。
(*2) HOSTS ファイルは、"%SystemRoot%\system32\drivers\etc" に存在します。
- HOSTS ファイルに記載したレコードは・・・?
HOSTS ファイルに記載したレコードは、DNS リゾルバー キャッシュに自動的に格納されます。実は、DNS リゾルバー キャッシュを管理する DNS Client サービスが起動している場合は、名前解決が行われるたびに HOSTS ファイルを参照せず、このキャッシュを使用することでパフォーマンスの向上が図られています。
この様子を、下記で確認してみましょう。
1) HOSTS ファイルを編集します。
2) ipconfig /displaydns コマンドで、リゾルバー キャッシュの内容を確認します。
登録した "2003sp2-01" の順引き、逆引きのレコードがそれぞれ DNS リゾルバー キャッシュに格納されている様子が確認できます。
** なお、DNS Client サービスが停止している場合は DNS リゾルバー キャッシュが使用できないため、HOSTS ファイルが直接参照されます。
- Winsock 名前解決の結果を確認する方法
実際に目的のホスト名が Winsock の名前解決によってどのアドレスに解決されるかを確認する方法として、最も簡単なのは Ping コマンドを使用することです。Ping では、Winsock による名前解決が行われるためです。コマンド プロンプトから
ping hostname
と入力して、期待通りの IP アドレスと通信を行おうとしているかどうかを確認しましょう。
3. NetBIOS の名前解決
NetBIOS 名は DNS の完全修飾名のような階層構造を持たない、単一ラベルの名前です。最大 16 バイトのフィールドを持ちますが、末尾の 1 バイトはサフィックスとして役割を指定するために使用されるため、実際に名前として使用できるのは 15 バイトまでとなります。NetBIOS 名のサフィックスについての詳細は、下記の公開情報をご参照ください。
<参考情報>
NetBIOS サフィックス (NetBIOS 名の 16 番目の文字)
https://support.microsoft.com/kb/163409/ja
- ノード タイプによる違い
さて、NetBIOS の名前解決の順序は、Winsock と比べると少し複雑です。NetBIOS の世界では “ノード タイプ” と呼ばれる概念があり、名前解決を行う自身のコンピューターがどのノード タイプに設定されているかどうかで、名前解決を行う順番が異なるためです。ノードタイプには下記の 4 つがあります。
ノード タイプ |
説明 |
b ノード (ブロードキャスト) |
b ノードでは、NetBIOS 名のクエリをブロードキャストして、名前の登録と解決を行います。通常、ルーターはブロード キャストを転送しないため、同一ネットワークセグメント内のコンピューター名しか解決することはできませんが、一方で、特に事前に WINS サーバーを用意しなくても宛先を見つけて通信することができるというメリットもあります。 |
p ノード (ピア ツー ピア) |
p ノードは、NetBIOS 名を解決するために WINS サーバーなどの NetBIOS ネーム サーバーを使用します。事前にサーバーを用意しておく必要はありますが、ルーターを超えて異なるネットワーク セグメントのコンピューター名も解決できるというメリットがあります。 |
m ノード (混合) |
m ノードは、b ノードと p ノードの両方の名前解決方法を使用するノードです。既定では b ノードとして機能し、ブロードキャストで名前解決ができない場合は p ノードとして機能します。 |
h ノード (ハイブリッド) |
h ノードも b ノードと p ノードの両方の名前解決方法を使用するノードです。こちらは、既定では p ノードとして機能し、WINS サーバーで名前解決ができない場合は b ノードとして機能します。 |
コンピューターが自身をどのノードタイプと認識するかは、OS のバージョンやコンピューターが持つ役割によって異なります。”ipconfig /all” コマンドを使用することで、現在のノード タイプを確認することができます。
一方で、ノード タイプが正しく表示されないという既知の問題もございますので、ご注意ください。
<参考情報>
"Ipconfig /All" コマンドを実行すると Node Type が Unknown と表示される
https://support.microsoft.com/kb/310570/ja
- NetBIOS 名前解決の順序
1) NetBIOS 名前キャッシュ (*1) を確認して、指定された名前に対応するレコードがキャッシュされている場合は、そのアドレスを返します。
2) 自身のノードタイプに従い、ブロードキャスト、および WINS サーバーの照会により指定された名前の解決を行います。
3) LMHOSTS ファイル (*2) の参照が有効になっている場合 (*3) は当該ファイルを参照して、指定された名前に対応するレコードが登録されている場合はそのアドレスを返します。
(*1) "nbtstat -c" コマンドを使用すると、現在クライアントが保持している NETBIOS 名前キャッシュを確認できます。
(*2) LMHOSTS ファイルは、"SystemRoot%\system32\drivers\etc"に存在します。
(*3) "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\netbt\Parameters\EnableLMHOSTS" により指定します。既定値は 1 (有効) です。
- LMHOSTS ファイルに記述したレコードを優先させる方法
上記の通り、NetBIOS 名前解決では、LMHOSTS に記述したレコードよりも NetBIOS 名前キャッシュやノード タイプに従った名前解決が優先されるため、HOSTS ファイルと同じように、強制的に LMHOSTS に記述したアドレスを使用したい場合には不便に感じるかもしれません。
このような要望を満たしたい場合は、下記の手順で LMHOSTS ファイルに記述したレコードに "#PRE" のオプションを追加することで、あらかじめ NetBIOS 名前キャッシュに記述したレコードを登録しておくことができます。
<手順>
1) "%SystemRoot%\system32\drivers\etc\" に、"LMHOSTS" ファイルを作成します。
2) ファイルをメモ帳などのエディタで開き、下記のようにレコードを追加します。
192.168.1.101 hostnameA #PRE
192.168.1.102 hostnameB #PRE
3) コマンドプロンプトを開き、下記のコマンドで NetBIOS 名前キャッシュ テーブルの再読み込みを行います。(現在保持しているキャッシュは削除されますので、ご注意ください。)
nbtstat –R
** "#PRE" は大文字で記述する必要がありますので、ご注意ください。
4. おまけ:トラブルシュート
期待通りに名前解決できない。おかしいなあ・・・と思った時は、一度キャッシュを削除してみましょう。
<コマンド>
Winsock : ipconfig /flushdns
NetBIOS : nbtstat –R
予期せぬレコードがキャッシュに入っていることが原因で名前解決に失敗していることが、意外に多かったりしますよ!
「コミュニティにおけるマイクロソフト社員による発言やコメントは、マイクロソフトの正式な見解またはコメントではありません。」