Windowsの名前解決の順序 ── hosts・DNSキャッシュ・LLMNR/mDNS・DoH

· 更新日: · · Windows, DNS, 名前解決, ネットワーク, 障害調査, PowerShell, TCP/IP, 情シス

更新履歴(1件・最終更新 2026年09月05日)

この記事に加えた変更の記録です。アーカイブした更新前のバージョンは、DOI付きの固定URLから読めます。

Windowsの名前解決の技術的主張と条件を維持し、症状別の案内、比較表、切り分け手順で記事構成を整理した。
初版公開
この記事を引用する(DOI(登録済みアーカイブ): 10.5281/zenodo.22313854)

以下のDOIは過去に登録されたアーカイブを指しており、現在の本文とは一致しない場合があります。現在の本文を参照するときは、このページのURLを使用してください。

小村 豪(2026)「Windowsの名前解決の順序 ── hosts・DNSキャッシュ・LLMNR/mDNS・DoH」合同会社小村ソフト. https://comcomponent.com/blog/windows-name-resolution-order-hosts-dns-cache-llmnr-mdns-doh/

DOI(登録済みアーカイブ)
10.5281/zenodo.22313854
DOI(前回登録した版)
10.5281/zenodo.22313855

「同じ設定なのに、このPCだけ社内サーバーに繋がらない」「ブラウザーでは開けるのに、業務アプリでは名前解決に失敗する」「hostsに書いたのに効かない」。

こうした問題を調べるとき、最初に確かめたいのはその名前に、どの仕組みが答えているかです。Windowsにはキャッシュ、hosts、DNSサーバー、LLMNR、NetBIOS、mDNSという複数の経路があり、アプリによってはWindowsとは別の経路を使います。

この記事では、まず全体像をつかみ、名前の形と各経路の違いを整理してから、実際の切り分け手順へ進みます。急いで調査したい方は、次の表から該当箇所へ進んでください。

困っていること 最初に確認すること 読む箇所
hostsが効かない/一部のPCだけ古いIPを返す キャッシュの内容と、使ったツールの経路 キャッシュとhosts手順2
app01のような短い名前で、一部のPCだけ失敗する サフィックスによる補完とLLMNR・NetBTの有無 名前の形単一ラベル名の典型例
VPNに繋ぐと結果が変わる 複数NICの優先順位とNRPT 複数NICNRPT
数秒待つと繋がる 無応答のDNSサーバーと再送時間 タイムアウト
ブラウザーと業務アプリで結果が違う 内蔵リゾルバー、セキュアDNS、プロキシ アプリの入口ブラウザーのDoH
どこから調べるか分からない 名前の形から順に、経路を限定して比較する 切り分け手順

この記事の前提

項目 内容
対象読者 「名前解決できない」「一部のPCだけ繋がらない」を調べる情シス担当者と、業務アプリの通信を設計・保守するWindowsアプリ開発者
前提知識 IPアドレスとDNSの基本(Aレコード、FQDN)、PowerShellのコマンドレットを管理者権限で実行できること
前提環境 Windows 10 / Windows 11。DoHの節はWindows 11またはWindows Server 2022以降1。確認コマンドはDnsClientモジュール(Windows 8 / Windows Server 2012以降)2
扱わないこと DNSサーバー側(Windows Server DNSのゾーン・フォワーダー・再帰)の設定と障害。Zero Trust DNS(ZTDNS)の展開手順

パケットキャプチャ記事が扱うのは線を流れるパケット、プロキシ記事が扱うのは「誰のプロキシ設定を読むか」です。本記事は、その手前の「宛先のIPアドレスはどこから来たのか」をMicrosoftの一次情報にもとづいて整理します。

1. まず結論

覚えておきたいのは、次の三点です。

  • Windowsの名前解決は、いつも一本の列を順番に進むわけではありません。キャッシュとhostsが先ですが、単一ラベル名では既定でDNSとLLMNR・NetBTが並行して動きます。34
  • 同じ名前でも、PCの設定とアプリの経路が違えば結果は変わります。サフィックス、VPN、NRPT、ブラウザーの内蔵リゾルバーを分けて考えます。567
  • 調査では、使う経路を限定して結果を比べます。Resolve-DnsNameのスイッチでキャッシュ・DNS・リンクローカルを分け、繋がるPCとの設定差分とキャプチャで確かめます。8

まずは次の図を、全体の見取り図として使ってください。

名前解決は層の重なり名前解決の依頼はアプリのAPIからDNSクライアントサービスに渡り、キャッシュとhostsが先に見られ、次にDNSサーバーと、単一ラベル名のときだけLLMNR・NetBIOS(既定ではDNSと並行)が試される。.local名には設定済みDNSに加えてmDNSという経路も加わる。ブラウザーはこの列の外に独自のリゾルバーを持つ無ければ無ければ・単一ラベル名(既定はDNSと並行).local名(追加の経路)独自リゾルバー・DoHアプリ(getaddrinfo)DNSクライアントサービスキャッシュ(hostsを含む)DNSサーバーへ問い合わせLLMNR / NetBIOSmDNSブラウザー別経路

キャッシュを先に見て、その先でDNSと、単一ラベル名ならLLMNR・NetBIOSが並行して動く。ブラウザーは別経路を持つ。

以下では「どこが答えるか」を3〜5章、「どう送るか」を6章、「どう確かめるか」を7〜8章に分けます。DoHはDNSサーバーへの輸送路をHTTPSに替える機能であり、hosts・キャッシュ・NRPTの順序を置き換えるものではありません。9

図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全48件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle

2. 「名前解決」はひとつの処理ではない

アプリに返るのは、アドレスかエラーだけ

アプリがwww.example.comのような名前で接続するとき、Winsockのgetaddrinfo(Unicode版はGetAddrInfoW)が呼ばれます。この関数はNS_DNS名前空間に対して、DNS、ローカルのhostsファイル、その他の仕組みで名前をアドレスに変換します。複数の名前空間プロバイダーが応答すれば、それを集約して返します。10

つまり、アプリが結果を受け取っただけでは、どの層が答えたかまでは分かりません

.NETのDns.GetHostAddressesも、Windowsではgetaddrinfoを使います。hostsに記述されたホストなら、DNSサーバーに問い合わせずそのアドレスを返します。HttpClientもこのDnsクラスの上で動くため、宛先へ直接接続する.NETアプリはWindowsの名前解決の順序を引き継ぎます。11

HTTPプロキシ経由では、解決する名前が変わります。ローカルで解決するのはプロキシの名前で、宛先の名前はプロキシ側で解決されます。この場合、ローカルのhosts・キャッシュ・サフィックス・NRPTは宛先の解決に関与しません。どのプロキシ設定が使われるかはプロキシ記事で扱っています。

2.1 DNSクライアントサービスが順序を決める

getaddrinfoの下で働くのが、DNSクライアントサービス(サービス名Dnscache)です。Microsoftの資料は、基本の順序を次のように説明しています。3

  1. キャッシュを確認する。
  2. hostsファイルを確認する。
  3. DNSサーバーに問い合わせる。

hostsの内容はサービス起動時にキャッシュへ読み込まれるため、本記事では最初の二つをまとめて第1層「キャッシュとhosts」として扱います。5

その先は、名前とポリシーによって分かれます。

役割 順序を読むときの注意
第1層: キャッシュとhosts PC内にある答えを返す ここで答えが出ればDNSサーバーには聞かない
第2層: DNSサーバー DNSへの問い合わせで答えを得る サフィックス、複数NIC、NRPTなどが関わる
第3層: LLMNR・NetBT 単一ラベル名を別の手段でも解決する 既定では第2層と並行。DNS失敗後の直列になるのは最適化を無効にしたときだけ

既定の「スマートマルチホーム名前解決」は、DNS・LLMNR・NetBTの問い合わせを全ネットワークへ並行して出します。どの応答を採用するかは、4.3節と5.2節の規則で決まります。4

したがって、「問い合わせを出すタイミング」と「返った答えを採用する優先順位」は別の話です。キャプチャにLLMNRやNetBTが見えても、それだけで「DNSが失敗した」とは言えません。本記事の「3層」は整理のための区分であり、常に時間順に直列に動くという意味ではありません。

2.2 列の外にいるもの

特に混同しやすいのが、次の二つです。

ツール・アプリ Windowsの経路との違い 調査時の注意
nslookup OSのリゾルバーを使わず、キャッシュ・hosts・NRPTを迂回し、先頭のDNSサーバーへ直接聞く123 pingや業務アプリと結果が違っても不思議ではない
Microsoft Edge 既定で内蔵DNSクライアントを使う。DoHも常に内蔵リゾルバーで処理する7 「ブラウザーでは開ける」はOSの名前解決が健全である証明にならない

Edgeの内蔵クライアントを使うこと自体は、DNSサーバーの変更を意味しません。別のプロバイダーを選ぶセキュアDNSの設定とは分けて、6.2節で確認します。

3. 第1層 ── キャッシュとhosts

この層で知りたいのは、PC内にどんな答えが残っているかです。キャッシュには、正しい答えだけでなく、古い答えや「名前が無い」という答えも残ります。

3.1 hostsはキャッシュに読み込まれる

hostsファイルはC:\Windows\System32\drivers\etc\hostsにあります。DNSクライアントサービスの起動時に、名前とIPアドレスの対応がリゾルバーキャッシュへ読み込まれます。DNSへの問い合わせで得たレコードも、TTL(生存時間)のあいだ同じキャッシュに保持されます。5

ipconfig /displaydnsには、hostsから読み込んだ項目と、最近のDNS問い合わせで得た項目の両方が表示されます。13 Microsoftの例でも、hostsにcontoso.comを書けばResolve-DnsName contoso.comはそのアドレスを返し、DNSの通信は流れません。3

DNSパケットが無いときの読み方

FQDNをDoH・DoTなしで引き、名前解決が成功しているのに53番の問い合わせが無ければ、キャッシュかhostsが答えていると考えられます。ただし、先に次の別経路を除外します。

名前・設定 53番以外に確認する通信
.local mDNS(UDP 5353)
単一ラベル名 LLMNR(5355)、NetBTの名前サービス(UDP 137)
DoHが有効 HTTPS(443)
DoTが有効 TLS(853)

「53番が無い」だけでキャッシュと決めつけず、使われ得る経路を併せて見ます。開発機に残った検証用hostsの1行が、調査を迷わせることもあります。

hostsの編集には管理者権限が必要で、変更をセキュリティ製品が検知する場合もあります。業務アプリの運用をhostsに依存させる設計は避けるべきです。

3.2 否定応答もキャッシュされる

「見つからなかった」も、キャッシュされる答えの一つです。DNSクライアントは肯定応答だけでなく否定応答も保存します。5

ipconfig /displaydnsで対象名に「Name does not exist」と表示されるなら、DNSサーバーの否定応答がクライアントに残っています。Microsoftの手順は、ipconfig /flushdnsでそれを捨てるよう案内しています。1413

否定キャッシュの保持時間は、HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\ParametersMaxNegativeCacheTtlで、既定は5秒です。15 DNSにレコードを追加した直後でも、そのPCが数秒間は失敗を返すことがあるのはこのためです。

3.3 TTLと「一部のPCだけ古い」

肯定応答もTTLのあいだ残ります。サーバーのIPアドレスを変更する前に名前を引いたPCは古い答えを使い続け、変更後に初めて引いたPCは新しい答えを得ます。同じDNSサーバーを使っていても、引いた時刻が違えば結果は変わります。5

Clear-DnsClientCacheipconfig /flushdnsと同じ動作で、否定応答を含むキャッシュの全内容を削除します。16 Get-DnsClientCacheなら、キャッシュをオブジェクトとして取り出し、レコード種別や残りTTLを確認できます。17

# 特定の名前がキャッシュにあるか、残りTTLは何秒か
Get-DnsClientCache -Entry 'app01.corp.example.com' |
    Select-Object Entry, Type, Status, TimeToLive, Data

# hostsとキャッシュの中身をまとめて確認
ipconfig /displaydns | Select-String -Pattern 'app01' -Context 0,6

# キャッシュを捨てる(否定応答も含めて)
Clear-DnsClientCache

第1層で答えが出れば、今回の検索はDNSサーバーに届く前に決まります。ただし、誤った答えを元々DNSサーバーから学習していた可能性は残ります。消して終わりにせず、8章の手順3で再取得した答えも確かめてください。

4. 第2層 ── DNSサーバーへの問い合わせ

第1層に答えが無ければDNSへ進みます。ここでは、何という名前を、どのサーバーへ、どのタイミングで送るかを分けて考えます。

4.1 単一ラベル名とサフィックス

まず、アプリが渡した名前の形を確認します。5

名前の形 DNSへの送り方
末尾に点があるFQDN(絶対名) www.contoso.com. そのまま送る
点を含むが、末尾に点がない名前 www.contoso.com 既定では末尾に点を付けて送る。複数ラベル名へのサフィックス付加を許可するポリシーが有効なら、サフィックスも試す4
点を含まない単一ラベル名 www PCのサフィックス設定で補完して送る

サフィックスは、短い名前の後ろに補うドメイン部分です。app01corp.example.comを付ければ、問い合わせる名前はapp01.corp.example.comになります。

検索リストがある場合

DNSサフィックス検索リストの先頭から順にサフィックスを付け、末尾に点を付けた名前を送ります。検索リストを構成すると、そのリストだけが使われます。プライマリサフィックス、接続固有サフィックス、名前の切り詰めは使われません。18

検索リストがない場合

プライマリDNSサフィックスを付けて送ります。名前の切り詰め(devolution)が有効なら、失敗するたびに左端のラベルを落として試します。たとえばwww.test.contoso.comからwww.contoso.comへ進みます。アダプターに接続固有のDNSサフィックスがあれば、それも付けて送ります。5

このため、グループポリシーで検索リストを配る環境と、ドメイン参加でプライマリサフィックスが付く環境では、同じserver01でも展開先が違います。

長いリストは待ち時間も増やす

正しいサフィックスがリストの後ろにあれば、そこに到達するまでの問い合わせ時間が積み上がります。Microsoftも、6つのサフィックスを試す例でこの遅延を説明しています。特定の展開結果だけを試すときは、internal.contoso.com.のように末尾に点を付けます。3

# 全体設定: 検索リストと切り詰め
Get-DnsClientGlobalSetting

# インターフェイスごと: 接続固有サフィックスと登録設定
Get-DnsClient | Select-Object InterfaceAlias, ConnectionSpecificSuffix, UseSuffixWhenRegistering

# インターフェイスごとのDNSサーバー(IPv4とIPv6の両方)
Get-DnsClientServerAddress | Where-Object ServerAddresses | Select-Object InterfaceAlias, AddressFamily, ServerAddresses

Get-DnsClientGlobalSettingは検索リストや切り詰めの有無・段数などの全体設定、Get-DnsClientはインターフェイスごとの設定を返します。1920

4.2 複数DNSサーバーの順序とタイムアウト

「失敗しないが数秒待たされる」ときは、無応答のDNSサーバーへの再送を疑います。1枚のNICに設定したDNSサーバーについて、既定の再送タイミングを並べると次のようになります。21

開始から 1台構成 2台構成 3台以上の構成
0秒 サーバーへ問い合わせ 1台目へ 1台目へ
1秒 再送 2台目へ 2台目へ
2秒 再送 2台目へ再送 3台目へ
4秒 再送 全サーバーへ同時 全サーバーへ同時
8秒 再送 全サーバーへ同時 全サーバーへ同時
10秒 打ち切り 打ち切り 打ち切り

これは応答が無い場合の表です。特に、次の二つを混同しないでください。

サーバーの反応 次のサーバーを試すか 読み方
無応答 試す 再送とタイムアウトの問題
「名前が無い」という否定応答 そこで止まる 名前が無いという答えを受け取っている

「片方を止めたのに切り替わらない」とき、古いゾーンを持ったサーバーが動き続けて否定応答を返していれば、次には進みません。21

4番目以降のサーバーには、4秒後まで届かない

応答できるサーバーがリストの4番目以降にあると、最初の問い合わせから最低4秒待ちます。アプリの期限がそれより短ければ、名前解決の段階で失敗します。問い合わせを早めるには先頭3つのどれかへ移す必要がありますが、根本対策は不達の先行サーバーを直すか、設定から外すことです。アプリ側のタイムアウトも見直します。21

Microsoftの例でも、4台中1台しか届かない構成では完了まで約4秒かかっています。Measure-Commandで所要時間を測れ、同資料は1秒未満を許容範囲としています。3

# 特定のサーバーに直接DNSだけで聞き、所要時間をミリ秒で得る
(Measure-Command {
    Resolve-DnsName -Name 'app01.corp.example.com' -Server 10.0.1.2 -DnsOnly
}).TotalMilliseconds

このコマンドはサーバーを固定するため、そのサーバー単体の応答時間を測ります。リストの4番目へ到達するまでの遅延は、-Serverを付けない問い合わせや、そのキャプチャで確認します。

なお、DNSクライアントは応答の速いサーバーを上位へ動かし、無応答のサーバーを記憶して定期的に再試行します。最初のタイムアウトも過去の実績から25〜1,000ミリ秒の範囲で調整されます。上の表は既定の骨格であり、実測にずれがあるのはこのためです。5

4.3 複数NICと「スマートマルチホーム名前解決」

有線とWi-Fiを持つPCや、VPNアダプターが加わるPCでは、DNSサーバーのリストだけでなくネットワーク間の問い合わせと応答の選択も確認します。

複数アダプターへの再送

Microsoftの問い合わせ手順では、優先アダプターの先頭のDNSサーバーへ送り、1秒待ちます。応答が無ければ、候補に残る全アダプターの先頭サーバーへ送って2秒待ち、その後は全アダプターの全サーバーへ、待ち時間を2秒・4秒・8秒と取りながら送ります。あるアダプターのサーバーが否定応答を返すと、そのアダプターの他のサーバーは候補から外れます。5

並行問い合わせを制御するポリシー

グループポリシー「スマート マルチホーム名前解決を無効にする」は、次の動作を制御します。4

ポリシー 動作
既定(未構成) DNS・LLMNR・NetBTを全ネットワークへ並行して問い合わせる。複数の肯定応答があれば、ネットワークのバインド順で採用する
有効 最適化を止める。まず全ネットワークでDNSを試し、失敗したらLLMNR、それも失敗したらNetBTという直列になる

「無効にする」という名前のポリシーなので、ポリシーを有効にすると最適化が無効になる点に注意してください。

VPNで結果が変わる例

社内名を聞いたとき、VPN側のDNSは社内アドレスを返し、自宅ルーター側のDNSも別の肯定応答を返すことがあります。社内と同じドメイン名の公開アドレスや、存在しない名前を置き換えた広告ページのアドレスなどです。

肯定応答が二つあれば、採用はバインド順で決まります。現在のWindowsでは、この優先順位はインターフェイスメトリックで決まり、Get-NetIPInterfaceInterfaceMetricが小さいほど優先されます。PCごとの順序の違いが、結果の違いになります。22

一方、自宅側が否定応答を返した場合は、そのアダプターが候補から外れ、VPN側の答えが使われます。5 VPN製品がNRPTや「スマート マルチホーム名前解決を無効にする」を配布するのは、こうした違いを制御するためです。

4.4 NRPT ── 名前空間ごとに問い合わせ先を変える

NRPT(Name Resolution Policy Table、名前解決ポリシーテーブル)は、.corp.contoso.comなどの名前空間ごとに、使うDNSサーバーやDirectAccess・DNSSECの設定を指定する表です。DirectAccessやAlways On VPNのプロファイルが規則を書き込み、「社内名だけ社内DNSへ向ける」といった動作を作ります。236

Get-DnsClientNrptPolicy -Effectiveで、実際に効いている規則を確認できます。

# 実際に効いているNRPTの規則
Get-DnsClientNrptPolicy -Effective

# 特定の名前空間の規則だけを表示する。-NamespaceはNamespace属性で絞るだけで、名前との一致判定はしない。
# 'app01.corp.example.com'を渡しても'.corp.example.com'のサフィックス規則は返らない。
# ある名前にどの規則が効くかは、8章の手順4のように規則を列挙して自分で照合する
Get-DnsClientNrptPolicy -Effective -Namespace '.corp.example.com'

NRPTが効くのは、Windows DNS APIを使うアプリだけです。独自のDNS実装を持つアプリは、その経路を迂回します。VPNv2 CSPの資料はnslookupを例に挙げ、NRPTの確認にはResolve-DnsNameを使うよう求めています。ブラウザーの内蔵リゾルバーやDoHも、Windows DNS APIの外側です。6

5. 第3層 ── 単一ラベル名の逃げ道: LLMNR・NetBIOS、そしてmDNS

5.1 三つのプロトコルの違い

LLMNRとNetBIOS over TCP/IP(NetBT)は、app01のような単一ラベル名を解決する別の手段です。既定ではDNSと並行して動き、DNSが肯定応答を返してもリンクローカルの応答が採用される場合があります。DNS失敗後の直列になるのは、スマートマルチホーム名前解決を無効にしたときだけです。4

mDNSはこれとは別で、.local名に加わる経路です。単一ラベル名のDNS解決に失敗した後の受け皿ではありません。24

プロトコル ポート 届く範囲 位置づけ
LLMNR UDP 5355のマルチキャスト。TCP 5355はユニキャストの再送用2526 同一サブネット内のリンク DNSを構成せず利用できる、二次的な名前解決4
mDNS UDP 5353のマルチキャスト24 マルチキャストが届くローカルネットワーク .local名の解決。Microsoftが今後の軸に選んだ方式27
NetBT UDP 137の名前サービス28 ブロードキャスト、またはWINSサーバーへの問い合わせ29 レガシー。WINSからDNSへの移行が推奨される30

.localでも、DNSの確認を飛ばさない

.localがmDNS専用になるわけではありません。Active Directoryドメインがcorp.localなどの場合、その名前は引き続き設定済みDNSサーバーやNRPTでも解決されます。RFC 6762もユニキャストDNSとの併用を認めています。.local名の調査でも、DNSとVPNのポリシーを確認してください。24

NetBTは、WINSの有無とノードタイプで変わる

ノードタイプ 名前解決の方法
B-node ブロードキャストのみ
P-node WINSへの問い合わせのみ
M-node ブロードキャストの後にWINS
H-node WINSの後にブロードキャスト

WINS未構成ならB-node、1台でも構成されていればH-nodeが既定です。29 LLMNRとNetBTのブロードキャストはサブネットを越えませんが、WINSへの問い合わせはユニキャストなので越えられます。

nbtstat -cでNetBIOS名キャッシュを表示し、nbtstat -Rでキャッシュの消去とLMHOSTSの再読み込みができます。31

5.2 どれが優先されるか

並行して問い合わせた後、どの応答を優先するかもポリシーで変わります。4

条件 単一ラベル名の応答の優先順位
既定・ドメインに属さないネットワーク LLMNRやNetBTのリンクローカル応答をDNSより優先する
ドメインのネットワーク DNS応答を優先する
「スマート プロトコルの並べ替えを無効にする」を有効化 すべてのネットワークでDNS→LLMNR→NetBTの順に優先する

自宅や外出先のネットワークでは、同じ名前を持つ近くの機器の答えがDNSより優先されることがあります。ここでも、応答の優先順位と、問い合わせが直列か並行かを分けて読むことが大切です。

5.3 Microsoftの方針: mDNSへ寄せる

Microsoftは2022年4月、mDNSに揃え、NetBIOS名前解決とLLMNRを段階的に縮退させる方針を公表しました。27 Computer Browserのような、古く安全でない機器探索プロトコルも非推奨になっています。32 単一ラベル名をマルチキャストやブロードキャストで補う設計は、縮小していく方向です。

LLMNRの脆弱性に関するMicrosoftの情報は、回避策としてTCP/UDP 5355の遮断や、グループポリシー「マルチキャスト名前解決を無効にする」の有効化を挙げています。その影響として、コンピューターが他のコンピューターから見えなくなる場合があることも明記しています。25 このポリシーを有効にすると、DNSクライアントの全アダプターでLLMNRが無効になります。4

無効化の方向自体は正しい判断ですが、消える経路の代わりをDNSに用意する必要があります。DNS未登録の機器はAレコードを登録するか、DHCPによる動的登録を有効にし、宛先をFQDNへ変更します。mDNS対応機器なら.local名を使えますが、届く範囲はマルチキャストが通る範囲に限られます。

5.4 「一部のPCだけ繋がらない」の典型: 単一ラベル名

設定ファイルやショートカットに\\fileserver01http://app01/と書かれていると、同じ名前でも次の違いが出ます。

PCの環境 起こり得ること
ドメイン参加のデスクトップ サフィックスでapp01.corp.example.comへ補完され、社内DNSで解決できる
VPN経由のノートPC 補完はVPNプロファイル次第。補完されず、同一サブネットにも対象がいなければLLMNRやNetBTは空振りする
別サブネットの事務所 DNS登録が無ければ、LLMNRとNetBTのブロードキャストは届かない。ただしWINSに登録があれば解決できる場合がある2930
LLMNRとNetBTを両方無効にしたPC DNSに無い名前は解決できない。LLMNRだけの無効化なら、NetBTやWINSで解決する余地が残る

Resolve-DnsName app01 -LlmnrOnlyで分かるのは「LLMNRで解決できるか」です。普段の問い合わせで採用された答えの出所までは分かりません。スイッチなしの結果との比較やキャプチャは、8章の手順5で行います。8

根本対策はFQDN化とDNS登録

単一ラベル名に依存する宛先をFQDNへ変更し、名前解決をDNSに集約します。

SMB2以降はTCP 445で直接接続し、NetBIOSのセッションを使いません。33 しかし、それは輸送路の話です。\\fileserver01\shareという宛先の名前を解決する段階では、LLMNRやNetBTが使われる場合があります。\\fileserver01.corp.example.com\shareのようにFQDNで指定して、単一ラベル名の経路への依存を外します。

ただし、FQDNにも次の注意が残ります。末尾に点のないFQDNは、複数ラベル名へのサフィックス付加ポリシーが有効なら補完も試されます。.localで終わる名前はmDNSを併用し得ます。無条件に固定するための絶対名は末尾に点を付けた形です。実務で「FQDNならDNSに固定される」と扱う前提は、上記ポリシーが無効で、社内ドメイン名に.localを使っていないことです。

6. DNSサーバーへの輸送路 ── DoHは順序を変えない

6.1 Windows 11 / Windows Server 2022のDoH

WindowsのDoHは、DNSサーバーへの問い合わせをHTTPSで送る機能です。既存のhosts・キャッシュ・NRPTや、アダプター・プロファイルごとのリゾルバー指定と統合され、3〜4章の順序は置き換えません。9

Windows 11のDNSクライアントはDoHに対応し、新しいバージョンではDoT(DNS over TLS)にも対応します。ただし、Microsoftの解説はDoTの対応バージョンを明示していないため、本記事の前提環境すべてで使えるとは限りません。以下ではDoHを扱います。9

まず、既知のDoHサーバー一覧を確認する

DDRを有効にしていない場合、使えるのは既知のDoHサーバー一覧に載ったサーバーです。既定の一覧にはCloudflare・Google・Quad9があり、Get-DnsClientDohServerAddressで確認できます。社内DNSなどは、DoHテンプレートとフォールバック・自動格上げの設定を登録します。134

# 既知のDoHサーバー一覧
Get-DnsClientDohServerAddress

# 社内DNSをDoHサーバーとして登録(平文フォールバックなし・自動格上げあり)
Add-DnsClientDohServerAddress -ServerAddress '10.0.1.2' `
    -DohTemplate 'https://dns.corp.example.com/dns-query' `
    -AllowFallbackToUdp $false -AutoUpgrade $true

netsh dnsclient add encryptionでも登録できます。全体のnetsh dnsclient set global doh=yes|no|autoは、サーバーごとのautoupgradeとは別の設定です。35

全体の設定 意味
doh=no DoHを禁止する
doh=yes サーバーやアダプターの設定に従ってDoHを許可する
doh=auto 既知のDoHサーバーへの問い合わせを自動でDoHに強制する

autoだけでは平文への復帰を禁止しません。失敗時にUDPへ戻すかは、サーバーごとのudpfallback、PowerShellでは-AllowFallbackToUdpが別に決めます。暗号化だけに限定するなら、フォールバックも無効にします。35

DDRが有効なら、動的な発見経路もある

DDR(Discovery of Designated Resolvers)に対応したバージョンでは、平文で設定したリゾルバーが暗号化DNSのエンドポイントを通知できます。静的な一覧への登録なしに暗号化へ格上げされ得るため、「一覧に無いからDoHではない」とは言い切れません。35

DDRが働くには、全体のnetsh dnsclient set global ddr=yesと、アダプターごとのset interface <名前> ddr=yes両方が必要です。DDRで得た暗号化解決に失敗したときの平文復帰はddrfallbackで決まり、既定は無効です。

調査では既知一覧に加え、netsh dnsclient show globalnetsh dnsclient show state、DNSサーバーを持つアダプターにset interfaceで設定した値を確認します。資料に定義されたshowencryptionglobalstateで、アダプター専用の表示サブコマンドはありません。35

「許可」「要求」と平文への復帰を分ける

設定アプリではDNS設定を手動にし、優先DNSサーバーが既知一覧にあるときだけ「優先DNS暗号化」を選べます。選択肢は次の三つです。1

設定アプリの選択肢 動作
暗号化のみ(DNS over HTTPS) 暗号化だけを使う
暗号化を優先し、暗号化されていない通信も許可 DoH失敗時に、通知なしで平文へ戻る
暗号化されていない通信のみ 平文で送る

グループポリシー「DNS over HTTPS (DoH) 名前解決の構成」には、許可・禁止・要求があります。許可の場合は、既知一覧への登録に加え、自動格上げ・アダプターの暗号化設定・全体のdoh=autoなどの条件でDoHを使います。「要求」ではDoH非対応サーバーによる名前解決そのものが失敗します。135

ドメイン参加PCに「DoHを要求」を適用してはいけません。Microsoftは明確に注意しています。Active Directory Domain ServicesはDNSに強く依存し、Windows Server標準のDNSサーバーサービスがDoHの問い合わせに対応していないためです。1

キャプチャでは、設定と実際の通信を分けて読む

実際にDoHで送った問い合わせはUDP 53ではなく、443番のTLSに入ります。ただし「DoHを許可」していても、既知一覧に無いサーバーへの問い合わせや、暗号化失敗後のフォールバックは平文で流れます。DoHの設定があるだけで、53番の通信が消えるわけではありません。

DNSの問い合わせが見えなければ、hosts・キャッシュに加えてDoHとDoT(853番)も確認します。採取方法はパケットキャプチャ記事を参照してください。

6.2 ブラウザーのDoHはOSと別物

Edgeの内蔵DNSクライアントと、セキュアDNSによる問い合わせ先の変更は、二段階に分けると理解しやすくなります。

設定 問い合わせる主体・相手
既定の内蔵DNSクライアント OSのDNSクライアントではなくEdgeが問い合わせる。使うDNSサーバー自体は変わらない
セキュアDNSで現在のプロバイダーを使う 現在のプロバイダーへ暗号化して問い合わせる。失敗すると平文で再試行する
セキュアDNSで別のプロバイダーを選ぶ 選んだDoHリゾルバーへ問い合わせる。失敗しても平文へ戻らない

内蔵クライアントはBuiltInDnsClientEnabledで制御し、DoHの問い合わせは常に内蔵リゾルバーが行います。7 セキュアDNSは組織管理下のPCでは既定で無効で、DnsOverHttpsMode(off / automatic / secure)とDnsOverHttpsTemplatesで構成します。3637

別のプロバイダーを選んだEdgeは、社外サイトを引けても社内DNSしか知らない名前を引けない場合があります。逆に、OSのDNSが不調でもEdgeだけは開けることがあります。現在のプロバイダーのままなら、問い合わせ先が変わるわけではありません。

結論は、ブラウザーの成功と業務アプリの成功を、同じ経路の証拠として扱わないことです。OSの経路はResolve-DnsNamepingで確かめます。

7. アプリはどの経路を通るのか

調査に使うツールを選ぶ前に、見ている経路を揃えます。

呼び出し 通る経路 hosts キャッシュ NRPT LLMNR/NetBT
getaddrinfo / Dns.GetHostAddresses / HttpClient(直接接続時)1011 OSのDNSクライアントサービス。プロキシ経由のHttpClientはプロキシ名だけをローカルで解決し、宛先はプロキシが解決する 見る 見る 効く 単一ラベル名で使う(既定はDNSと並行。失敗後の直列は最適化無効時のみ)
ping OSのDNSクライアントサービス 見る 見る 効く 単一ラベル名で使う(既定はDNSと並行。失敗後の直列は最適化無効時のみ)
Resolve-DnsName8 OSのDNSクライアントサービス(スイッチで層を選べる) -NoHostsFileで外せる -CacheOnlyで限定 効く -DnsOnlyで外せる
nslookup123 先頭のDNSサーバーへ直接 見ない 見ない 効かない 使わない
Microsoft Edge(既定)76 内蔵DNSクライアント(OSのDNSクライアントを通らない) OSの経路とは別 OSのキャッシュとは別 効かない(Windows DNS APIの外) OSの経路とは別

Resolve-DnsNameの主なスイッチを、調査目的で整理すると次のようになります。8

確かめたいこと スイッチ
ローカルキャッシュだけで答えが出るか -CacheOnly
hostsを外して試したい -NoHostsFile
DNSプロトコルだけを使い、LLMNR・NetBIOSを出したくない -DnsOnly
特定のDNSサーバーに聞きたい -Server
LLMNRだけを試したい -LlmnrOnly
LLMNRまたはNetBIOSだけを試したい -LlmnrNetbiosOnly
DNS失敗時にNetBIOSへ落とすことを許可したい -NetbiosFallback
レコード種別を選びたい -Type。既定はAとAAAAの両方を聞くA_AAAA

7.1 AとAAAA、IPv6が先に返る

名前解決が成功していても、その後のアドレス選択で接続が遅くなる場合があります。

DNSクライアントはA(IPv4)とAAAA(IPv6)の両方を問い合わせます。キャプチャでも両方の問い合わせが対で見えます。3 答えを返した後に、getaddrinfoと接続側のスタックが使うアドレスを選びます。Windows Vista以降はRFC 3484のプレフィックステーブルを使い、既定ではIPv6のグローバルユニキャストをIPv4より優先します。38

ただし、AAAAが返っただけで、必ずIPv6接続を試すわけではありません。宛先選択では、IPv6の送信元アドレスや経路が無いなど、使えない宛先を先に外してから候補を並べます。39

問題になるのは、IPv6の送信元アドレスと経路が一見あるのに、実際には通らない環境です。名前解決は成功していても、接続で時間を失います。IPv6が本当に試されたかは、DNS応答だけでなく接続ログやキャプチャで確認します。

Microsoftは対処としてIPv6を無効化することを推奨していません。Windowsの一部コンポーネントが動かなくなるためです。代わりにDisabledComponents0x20にして、プレフィックスポリシーでIPv4を優先する方法を案内しています。38 localhost::1に解決され、127.0.0.1を想定した調査と食い違う例は、パケットキャプチャ記事でも扱っています。

8. 切り分け手順 ── 層を上から順に剥がす

繋がらないPCで、次の順に実行します。各コマンドは経路を限定するためのものであり、成功しただけで普段の解決経路まで証明できるわけではありません。結果の比較と、最後のキャプチャを組み合わせます。

手順 確かめること
1 アプリが渡した名前の形
2 キャッシュとhostsの答え
3 hosts・LLMNR・NetBIOSを外したDNSの結果
4 実際の解決経路にあるDNSサーバーごとの結果
5 単一ラベル名のLLMNR・NetBTによる解決
6 繋がるPCと繋がらないPCの設定差分
7 パケットが出たか、何が返ったか

手順1: 名前の形を確認する

ログか設定ファイルで、アプリが実際に渡している名前を確認します。単一ラベル名か、.localで終わるか、末尾に点があるかで経路が変わります。http://app01/のような短い名前なら、4.1節の補完と5.4節のPCごとの違いから調べます。

手順2: キャッシュとhostsだけで解決できるか

Resolve-DnsName -Name 'app01.corp.example.com' -CacheOnly
Get-DnsClientCache -Entry 'app01.corp.example.com'
Get-Content "$env:SystemRoot\System32\drivers\etc\hosts" | Select-String -Pattern 'app01'
結果 読み方と次の確認
正しい答えが出る 今回はDNSサーバーに届く前に答えが決まっている
古い・誤った答えが出る hostsならその行を修正する。キャッシュなら消した後、手順3で再取得した答えを確かめる
「Name does not exist」 否定キャッシュ。Clear-DnsClientCacheの後に手順3へ進む
答えが無い 通常のキャッシュミスの可能性がある。手順3へ進む

-CacheOnlyは今回の検索をローカルキャッシュに限定するだけです。誤った答えをDNSサーバーから学習していれば、消しても同じ値が戻ります。キャッシュにあったことは、DNSサーバーが無関係である証明にはなりません。8

手順3: DNSだけで解決できるか

# hostsを外し、LLMNR/NetBIOSも出さず、設定済みDNSサーバーだけで引く
Resolve-DnsName -Name 'app01.corp.example.com' -NoHostsFile -DnsOnly

手順2で答えが無く、ここで成功しただけなら、多くは通常のキャッシュミスです。キャッシュやhostsの問題と言えるのは、手順2に古い答え、誤った答え、否定キャッシュがあった場合です。

ここでも失敗するなら、DNSサーバーへの経路、サーバー側、クライアント側のポリシーを調べます。手順4へ進む前に、次を確認してください。

  • Get-DnsClientNrptPolicy -Effective: 別のDNSサーバーへ向ける規則がないか。
  • Get-DnsClientDohServerAddressとDoHのグループポリシー: 非対応サーバーに「DoHを要求」していないか。

NRPTがあれば手順4の対象サーバーが変わります。「DoHを要求」が原因なら、経路もサーバーも健全なまま名前解決だけが失敗します。4.4節・6.1節の確認を先に済ませます。

手順4: サーバーごとに直接聞く

接続中のアダプターのDNSサーバーを集め、対象名にNRPTが効く場合は、その規則のサーバーへ置き換えます。IPv6だけで設定されたDNSサーバーも対象にします。

$name = 'app01.corp.example.com'
# 接続中のインターフェイスのDNSサーバーをIPv4・IPv6の両方から集める。
# 切断中のVPNや仮想スイッチに残った設定のサーバーは今の解決経路に関わらないので除く(IPv6だけで設定されたサーバーは見落とさない)
$connected = @((Get-NetIPInterface -ConnectionState Connected).ifIndex | Select-Object -Unique)
$servers = @((Get-DnsClientServerAddress |
    Where-Object { $_.ServerAddresses -and ($connected -contains $_.InterfaceIndex) }).ServerAddresses)
# この名前に効いているNRPTの規則のサーバー(Always On VPNやDirectAccessが書き込むもの)はアダプターの設定に現れないので、実効ポリシーから選ぶ。
# Get-DnsClientNrptPolicyの-Namespaceは規則のNamespace属性で絞るだけで、名前との一致判定はしない。
# そこでAny規則(.)・サフィックス規則(先頭が点。名前空間そのものと子ドメインに効く)・FQDN規則・プレフィックス規則(ホスト名部分。web*のようなワイルドカードも可)を自分で照合し、
# より具体的な(長い)規則を採用する。Any規則は最も短いので、他に一致する規則が無いときだけ選ばれる
# Namespaceは文字列の集合(Namespace : {.corp.example.com}のように表示される)なので、規則ごとに要素を展開して照合し、一致した名前空間の長さで並べる
# 末尾に点を付けた絶対名(app01.corp.example.com.)は照合のときだけ点を外す。Resolve-DnsNameには元の$nameを渡す
$matchName = $name.TrimEnd('.')
$label = $matchName.Split('.')[0]
$matched = foreach ($policy in @(Get-DnsClientNrptPolicy -Effective)) {
    foreach ($ns in @($policy.Namespace)) {
        if (-not $ns) { continue }
        $hit = if ($ns -eq '.') { $true }
               elseif ($ns.StartsWith('.')) { $matchName.Equals($ns.TrimStart('.'), [System.StringComparison]::OrdinalIgnoreCase) -or $matchName.EndsWith($ns, [System.StringComparison]::OrdinalIgnoreCase) }
               elseif ($ns.Contains('.')) { $matchName.Equals($ns, [System.StringComparison]::OrdinalIgnoreCase) }
               else { $label -like $ns }
        if ($hit) { [pscustomobject]@{ Namespace = $ns; Policy = $policy } }
    }
}
$rule = $matched | Sort-Object { $_.Namespace.Length } -Descending | Select-Object -First 1
$policyServers = @()
if ($rule) { $policyServers = @(@($rule.Policy.NameServers) + @($rule.Policy.DirectAccessDnsServers) | Where-Object { $_ }) }
if ($policyServers.Count -gt 0) {
    # NRPTがこの名前空間のサーバーを指定しているなら、手順3の問い合わせはそのサーバーへ向かう。アダプターのサーバーは経路の外なので置き換える
    $servers = $policyServers
}
$servers = $servers | Where-Object { $_ } | Select-Object -Unique
foreach ($server in $servers) {
    $sw = [System.Diagnostics.Stopwatch]::StartNew()
    try {
        $r = Resolve-DnsName -Name $name -Server $server -DnsOnly -ErrorAction Stop
        $status = 'OK'
        # 複数レコードは応答ごとに並びが変わり得るので、並べ替えてから比較する
        $answer = ($r.IPAddress | Sort-Object) -join ','
    } catch {
        # 否定応答(名前が無い)・SERVFAIL・タイムアウトはここに来る。理由を捨てずに残す
        $status = $_.Exception.Message
        $answer = ''
    }
    [pscustomobject]@{ Server = $server; Status = $status; Answer = $answer; Milliseconds = [int]$sw.ElapsedMilliseconds }
}

まず、比較するサーバーを揃える

NRPTのNameServersDirectAccessDnsServersは、アダプターのDNS設定には現れない場合があります。手順3でNRPTのサーバーへ聞いているのに、手順4でアダプターのサーバーだけを調べては、別の経路を比較してしまいます。

NRPTにはサフィックス、FQDN、プレフィックス、Any(.)などの規則があり、より具体的な規則が優先されます。40 -Namespaceは規則の属性で絞るだけで、ホスト名との一致判定はしません。そこで、上のコードは規則の名前空間を展開し、対象名と照合しています。23

分割DNSのVPNでは、自宅側のリゾルバーが社内名に否定応答を返し、NRPT側だけが肯定応答を返すのは正常です。経路外のサーバーも比較する場合は「対照」として別に記録し、ゾーンの不一致の判定には混ぜません。切断中のアダプターに残るサーバーへのタイムアウトも、現在の解決経路の遅延とは別です。

次に、結果を読み分ける

結果 調べること
特定サーバーだけタイムアウトする そのサーバーが無応答になっている理由
「名前が存在しない」などの否定応答 タイムアウトとは区別し、名前やゾーンの内容を確認する
応答のIPアドレスが違う 同じ役割のサーバー同士かを確かめ、レコード集合で比較する
レコードの順番だけが違う ラウンドロビンの可能性。並べ替えた集合が同じなら、順番だけでゾーン不一致としない

集合でも違うなら、ゾーンの内容やシリアル番号を確認します。また、ここは-Serverで宛先を固定した測定です。4.2節の「4番目以降に届くまで4秒」というリスト位置による遅延は、手順3やそのキャプチャで確認します。

手順5: リンクローカルの層を確認する

Resolve-DnsName -Name 'app01' -LlmnrOnly          # LLMNRだけ
Resolve-DnsName -Name 'app01' -LlmnrNetbiosOnly   # LLMNRかNetBIOSだけ(DNSは使わない)
nbtstat -c                                        # NetBIOS名キャッシュ

この確認は単一ラベル名が対象です。-NetbiosFallbackはDNS失敗時だけNetBIOSへ落とすため、DNSで引ける名前ではNetBIOSの確認になりません。8

結果は次のように読みます。

結果 分かること/まだ分からないこと
-LlmnrOnlyで成功 LLMNRで解決できる。ただし、普段もその答えを採用したとは限らない
-LlmnrOnlyは失敗し、-LlmnrNetbiosOnlyで成功 NetBIOSが答えたとは断定できない。取りこぼしや相手の起動タイミングにより、後の試行でLLMNRが答えた可能性もある
繋がるPCではこの層だけ成功し、繋がらないPCでは失敗 単一ラベル名の経路への依存を疑う。根本対策はFQDN化とDNS登録

どちらのプロトコルが答えたかは、キャプチャでUDP 5355(LLMNR)とUDP 137(NetBT)を見分けます。普段の解決経路を確かめるには、スイッチなしのResolve-DnsNameが返すアドレスとも比較し、食い違う場合はキャプチャで採用された応答を確認します。既定ではDNSも並行して問い合わせられるためです。

手順6: 設定ダンプの差分を取る

「一部のPCだけ」の調査では、繋がるPCと繋がらないPCで同じスクリプトを実行して比較します。

# name-resolution-dump.ps1 -- 管理者権限で実行し、出力ファイルを2台分並べて比較する
$out = "$env:COMPUTERNAME-name-resolution.txt"
$sections = [ordered]@{
    'Get-DnsClientServerAddress' = { Get-DnsClientServerAddress | Format-Table -AutoSize | Out-String -Width 200 }
    'Get-DnsClientGlobalSetting' = { Get-DnsClientGlobalSetting | Format-List | Out-String }
    'Get-DnsClient'              = { Get-DnsClient | Format-Table InterfaceAlias, ConnectionSpecificSuffix, UseSuffixWhenRegistering -AutoSize | Out-String -Width 200 }
    'Get-DnsClientNrptPolicy'    = { Get-DnsClientNrptPolicy -Effective | Format-List | Out-String }
    'Get-DnsClientDohServerAddress' = { Get-DnsClientDohServerAddress | Format-Table -AutoSize | Out-String -Width 200 }
    'netsh dnsclient show state' = { netsh dnsclient show state 2>&1 | Out-String }
    'Get-NetIPInterface'         = { Get-NetIPInterface | Sort-Object AddressFamily, InterfaceMetric | Format-Table InterfaceAlias, AddressFamily, InterfaceMetric, ConnectionState, Dhcp -AutoSize | Out-String -Width 200 }
    'DNSClient policy registry'  = { Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient' -ErrorAction SilentlyContinue | Format-List | Out-String }
    'ipconfig /all'              = { ipconfig /all | Out-String }
}
$sections.GetEnumerator() | ForEach-Object {
    "===== $($_.Key) ====="
    try { & $_.Value } catch { "ERROR: $($_.Exception.Message)" }  # 無い項目(Windows 10のDoHなど)はエラーとして残す
} | Set-Content -Path $out -Encoding UTF8
Write-Host "wrote $out"

比較するのは、DNSサーバーの並び、検索リスト、接続固有サフィックス、NRPT、DoH、インターフェイスメトリック、ポリシー値です。

HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClientには、「マルチキャスト名前解決を無効にする」のEnableMulticast、「スマート マルチホーム名前解決を無効にする」のDisableSmartNameResolution、検索リストやプライマリサフィックスなどが入ります。4 差分を、ここまで整理した各層の働きと照らし合わせます。

手順7: パケットキャプチャで裏を取る

Microsoftのデータ収集手順は、クライアントとサーバーの両側でnetsh trace start capture=yesを開始し、ipconfig /flushdnsでキャッシュを捨ててから再現し、netsh trace stopで止める流れです。41

Wiresharkでは、dns.qry.name == "app01.corp.example.com"dns.qry.name contains "app01"で絞り、どのサーバーに何を聞き、何が返ったかを確認します。

キャプチャで見えたこと 調べる場所
問い合わせが出ない キャッシュ・hosts、DoH・DoTやリンクローカルなど別経路に加え、送信側ファイアウォールによるUDP 53の遮断を確認する
問い合わせは出るが応答がない DNSサーバーへの経路、ファイアウォール、サーバーの無応答
否定応答が返る 問い合わせた名前とサーバー側のレコード
肯定応答が返る 名前解決の後の接続側。使われたアドレスやIPv6も確認する

送信側のファイアウォールでUDP 53を遮断している場合、Resolve-DnsNameはタイムアウトし、キャプチャにもDNSの問い合わせが現れません。名前解決が成功して通信が出ない場合だけでなく、失敗して通信が出ない場合も切り分けます。3

DNS以外も、LLMNRは5355、mDNSはUDP 5353、NetBTの名前サービスはUDP 137を確認します。DoHは443、DoTは853です。キャプチャの採取と読み方はパケットキャプチャ記事にまとめています。

9. 業務アプリ側の設計 ── 名前解決に強くする

調査を軽くするには、アプリ側が「何という名前を、何に解決し、どこで失敗したか」を残せることが重要です。アプリのログと、情シスが採る設定ダンプ・キャプチャを突き合わせれば、8章のどこから調べるかを決めやすくなります。

宛先はFQDNで持ち、hostsに依存しない

設定ファイルの既定値、ショートカット、UNCパスはFQDNにします。単一ラベル名のサフィックス補完やLLMNR・NetBTへの依存を外すためです。ただし、.local名のmDNS併用と、末尾に点のない名前へのサフィックス付加ポリシーという5.4節の注意は残ります。

hostsは開発中の一時的な上書きには便利ですが、管理者権限と手作業が必要です。配布や変更履歴を管理しにくく、リゾルバーによっては参照もしません(nslookupは参照しません12)。宛先の切り替えは設定ファイルで行います。

名前解決の結果・時間・失敗理由を記録する

起動時などに、主要な宛先のIPv4・IPv6アドレスと所要時間を記録します。Dns.GetHostAddressesgetaddrinfoと同じ結果を返すため、「どのPCで、いつから、何に解決されていたか」を追えます。11

// 起動時に主要な宛先の名前解決結果を記録する(.NET 6以降)
static async Task LogNameResolutionAsync(ILogger logger, string host)
{
    var sw = System.Diagnostics.Stopwatch.StartNew();
    try
    {
        var addresses = await System.Net.Dns.GetHostAddressesAsync(host);
        logger.LogInformation("名前解決 {Host} -> {Addresses} ({Elapsed} ms)",
            host, string.Join(",", addresses.Select(a => a.ToString())), sw.ElapsedMilliseconds);
    }
    catch (System.Net.Sockets.SocketException ex)
    {
        logger.LogError(ex, "名前解決失敗 {Host} エラー {Code} ({Elapsed} ms)",
            host, ex.SocketErrorCode, sw.ElapsedMilliseconds);
        throw;
    }
}

失敗はログに残して投げ直します。別の名前や固定IPへ黙って切り替えると、調査時に実際の経路が分からなくなるためです。エラーコードと所要時間があれば、情シスは手順2〜4のどこから始めるかを判断できます。

タイムアウトとIPv6の答えを見込む

DNSクライアントは、無応答のサーバーに対して問い合わせる候補一つあたり最大10秒を使います。21 サフィックス検索で候補が複数になれば、全体では10秒を超えることもあります。

接続タイムアウトを2〜3秒に詰めると、答えられるサーバーが4番目以降にある構成などでは、期限までに名前解決が終わりません。ただし2台目には1秒後、3台目には2秒後に問い合わせるため、1台落ちただけで必ず失敗するわけではありません。4.2節の再送時間を踏まえて設計します。

また、AAAAが返り、IPv6の送信元アドレスと経路があれば、Windowsは既定でIPv6を優先します。38 IPv4だけを想定した接続コードでは、名前解決に成功したのに接続に失敗することがあります。名前解決の成功と接続の成功を分け、両方のアドレスを扱えるようにします。

10. まとめ

Windowsの名前解決で最初に分けるのは、名前の形、答えを返す層、アプリが通る経路です。

キャッシュとhostsが先に答え、単一ラベル名では既定でDNSとLLMNR・NetBTが並行して動きます。.localにはmDNSも加わります。DNSへ進んだ後は、サフィックス、再送時間、複数NIC、NRPTが結果を変えます。DoHはその輸送路を替える機能で、ブラウザーの内蔵リゾルバーとは分けて考えます。

調査は-CacheOnly-NoHostsFile -DnsOnly-Server-LlmnrOnlyの順で経路を限定し、設定ダンプの差分とキャプチャで確かめます。否定キャッシュ、無応答と否定応答の違い、クライアント側のポリシーを見落とさないことが重要です。

「このPCだけ繋がらない」ときは、まず次の二つを確認してください。

その名前は、どの形で渡されていますか。そのPCでは、どの経路が答えていますか。

この二つを揃えると、調べる場所を絞れます。

関連記事

関連する相談領域

合同会社小村ソフトでは、「一部のPCだけ業務アプリが社内サーバーに繋がらない」「ブラウザーでは開けるのにアプリでは名前解決に失敗する」といった名前解決起因の通信トラブルの原因調査、LLMNR無効化・DoH・VPNといった環境変更に業務アプリが耐えられるかの設計レビュー、名前解決の結果とタイムアウトを記録する通信層の実装を扱っています。繋がるPCと繋がらないPCの設定ダンプを添えてご相談いただければ、調査の入口が早く決まります。

参考リンク

  1. Microsoft Learn, Secure DNS Client over HTTPS (DoH). DoHを構成できるのは優先/代替DNSサーバーが既知のDoHサーバー一覧にある場合だけであること、設定アプリの3つの暗号化選択肢と「暗号化を優先」が通知なしに平文へ戻ること、グループポリシー「DNS over HTTPS (DoH) 名前解決の構成」のAllow/Prohibit/Require、ドメイン参加PCでRequireを有効にしてはいけない理由、既知サーバー一覧(Cloudflare・Google・Quad9)とGet-DnsClientDohServerAddress、Add-DnsClientDohServerAddressによる追加、NRPTとの併用について。  2 3 4 5

  2. Microsoft Learn, MSFT_DNSClientGlobalSetting class. DnsClientコマンドレットの基盤となるWMIクラスの最小対応OSがWindows 8 / Windows Server 2012であることについて。 

  3. Microsoft Learn, Troubleshoot DNS client name resolution issues. DNSクライアントがキャッシュ→hostsファイル→DNSサーバーの順で解決すること、hostsに該当があればDNSの通信が流れないこと、UDP 53を塞ぐとResolve-DnsNameがタイムアウトすること、複数サーバーのうち届くものが少ないと約4秒かかること、nslookupが先頭のDNSサーバーにしか問い合わせないこと、長いサフィックス検索リストによる遅延、末尾の点による特定問い合わせ、Measure-Commandによる所要時間の測定について。  2 3 4 5 6 7 8 9

  4. Microsoft Learn, Policy CSP - ADMX_DnsClient. 「スマート マルチホーム名前解決を無効にする」(既定で全ネットワークへDNS・LLMNR・NetBTを並行して問い合わせ、複数の肯定応答はバインド順で採用。有効にするとDNS→LLMNR→NetBTの直列)、「スマート プロトコルの並べ替えを無効にする」(既定で非ドメインネットワークの単一ラベル名はリンクローカル応答を優先)、「マルチキャスト名前解決を無効にする」(LLMNRが二次的プロトコルであることと全アダプターで無効化されること、レジストリ値EnableMulticast)、DNSサフィックス検索リストと切り詰め、「複数ラベルの非修飾名の問い合わせへのDNSサフィックスの付加を許可する」(点を含むが末尾に点が無い名前にもサフィックスを付けて問い合わせるポリシー)、プライマリDNSサフィックス、接続固有サフィックス、レジストリキーSoftware\Policies\Microsoft\Windows NT\DNSClientについて。  2 3 4 5 6 7 8 9

  5. Microsoft Learn, DNS queries and lookups. hostsの内容がDNSクライアントサービス起動時にキャッシュへ読み込まれ、DNS応答もTTLのあいだキャッシュに保持されること、FQDN・複数ラベル名・単一ラベル名で問い合わせの作り方が変わりサフィックス検索リスト・プライマリサフィックス・切り詰め・接続固有サフィックスが順に使われること、肯定でも否定でも応答がキャッシュされること、複数アダプターでの問い合わせ順序と否定応答によるアダプターの除外、適応的タイムアウトと無応答サーバーのキャッシュについて。  2 3 4 5 6 7 8 9 10

  6. Microsoft Learn, VPNv2 CSP. VPNプロファイルのDomainNameInformationListがNRPTの規則であること、Windows DNS APIを使うアプリだけがNRPTを利用でき独自のDNS実装を持つアプリは迂回すること、その例がnslookupであり、NRPTの確認には必ずResolve-DnsNameを使うべきことについて。  2 3 4

  7. Microsoft Learn, Microsoft Edge policy: BuiltInDnsClientEnabled. Edgeが既定で内蔵DNSクライアントを使うこと、このポリシーがどのDNSサーバーを使うかには影響しないこと、DoHの問い合わせは常に内蔵リゾルバーで行われることについて。  2 3 4

  8. Microsoft Learn, Resolve-DnsName. -CacheOnly(ローカルキャッシュのみ)、-DnsOnly(DNSプロトコルのみでLLMNR・NetBIOSを出さない)、-NoHostsFile(hostsを飛ばす)、-LlmnrOnly、-LlmnrNetbiosOnly、-LlmnrFallback、-NetbiosFallback、-Server、-Type(既定はA_AAAA)、-QuickTimeout、-TcpOnlyの各パラメーターについて。  2 3 4 5 6

  9. Microsoft Learn, Windows security book: Network security. Windows 11のDNSクライアントがDoHとDoTに対応すること、グループポリシーとプログラムからDoHを構成できること、暗号化DNSのサポートがNRPT・システムのhostsファイル・アダプターやプロファイルごとのリゾルバー指定といった既存のDNS構成と統合されることについて。  2 3

  10. Microsoft Learn, getaddrinfo function (ws2tcpip.h). NS_DNS名前空間に対してDNS・ローカルのhostsファイル・その他の仕組みで名前をアドレスに変換し、複数の名前空間プロバイダーの応答を集約すること、Unicode版がGetAddrInfoWであることについて。  2

  11. Microsoft Learn, Dns.GetHostAddresses Method. 基盤となるOSの名前解決API(Windowsではgetaddrinfo)で実装されていること、hostsファイルに記述されたホストはDNSサーバーに問い合わせずそのアドレスが返ることについて。  2 3

  12. Microsoft Learn, Troubleshoot Azure DNS. nslookupがOSのローカルDNSリゾルバーライブラリを使わず、ローカルDNSキャッシュ・hostsファイル・NRPTを迂回すること、それらの層が関係する場合はResolve-DnsNameを使うべきことについて。  2 3

  13. Microsoft Learn, ipconfig. /displaydnsがhostsから読み込んだ項目と最近解決したレコードの両方を含むDNSクライアントリゾルバーキャッシュを表示すること、/flushdnsが否定キャッシュの項目を含むキャッシュを破棄すること、/registerdnsによる動的登録について。  2

  14. Microsoft Learn, Troubleshooting DNS clients. ipconfig /displaydnsで失敗する名前に「Name does not exist」と出ていればDNSサーバーの否定応答がクライアントにキャッシュされていること、ipconfig /flushdnsで解消すること、nslookupがクライアントのDNSキャッシュを使わないことについて。 

  15. Microsoft Learn, Windows Firewall profile doesn’t always switch to Domain when you use a third-party VPN client. Dnscache\ParametersのMaxNegativeCacheTtlの既定値が5秒であること、0で否定キャッシュを無効にできることについて。 

  16. Microsoft Learn, Clear-DnsClientCache. DNSクライアントキャッシュの全内容を削除し、ipconfig /flushdnsと同等であることについて。 

  17. Microsoft Learn, Get-DnsClientCache. ローカルのDNSクライアントキャッシュの内容を取得し、Name・Type・TimeToLive・Sectionなどで絞り込めることについて。 

  18. Microsoft Learn, How to configure a domain suffix search list on the Domain Name System clients. ドメインサフィックス検索リストが構成されるとそのリストだけが使われ、プライマリDNSサフィックスも接続固有サフィックスも切り詰めも使われないことについて。 

  19. Microsoft Learn, Get-DnsClientGlobalSetting. インターフェイスに紐づかないDNSクライアントの全体設定(UseSuffixSearchList・SuffixSearchList・UseDevolution・DevolutionLevel)を取得することについて。 

  20. Microsoft Learn, Get-DnsClient. インターフェイスごとのConnectionSpecificSuffix・RegisterThisConnectionsAddress・UseSuffixWhenRegisteringを取得することについて。 

  21. Microsoft Learn, DNS client resolution timeouts. DNSサーバーが1台・2台・3台以上のときの再送タイミング(開始から1・2・4・8秒の時点で再送し、10秒で打ち切り)、否定応答で処理が止まり無応答のときだけ次のサーバーを試すこと、4番目以降のサーバーには最低4秒後にしか届かないことについて。  2 3 4

  22. Microsoft Learn, Automatic interface metric. 現在のWindowsではインターフェイスの優先順位がインターフェイスメトリックで決まり、Get-NetIPInterfaceでメトリックを確認・変更できることについて。 

  23. Microsoft Learn, Get-DnsClientNrptPolicy. NRPTに構成された名前空間ごとの設定(DNSクライアントの名前サーバー、DirectAccess、DNSSECなど)を取得し、-Effectiveで実効ポリシーを、-Namespaceで特定の名前空間の分を表示することについて。  2

  24. IETF, RFC 6762: Multicast DNS. mDNSがUDPポート5353のマルチキャストで.local名を同一リンク内で解決するプロトコルであることについて。  2 3

  25. Microsoft Learn, Microsoft Security Bulletin MS11-030. LLMNRがTCP/UDP 5355を使うこと、回避策としてのファイアウォールでの5355の遮断とグループポリシー「マルチキャスト名前解決を無効にする」、その影響としてコンピューターが他のコンピューターから見えなくなり得ることについて。  2

  26. IETF, RFC 4795: Link-Local Multicast Name Resolution (LLMNR). LLMNRの問い合わせがUDPのマルチキャスト(ポート5355)で送られ、TCPは切り詰められた応答などのユニキャストのやり取りに使われることについて。 

  27. Microsoft Tech Community, Networking Blog, Aligning on mDNS: ramping down NetBIOS name resolution and LLMNR. 2022年4月にMicrosoftが公表した、mDNSに揃えてNetBIOS名前解決とLLMNRを段階的に縮退させる方針について。  2

  28. Microsoft Learn, How to configure TCP/IP networking while NetBIOS is turned off. NetBIOS名前サービスがUDP 137、データグラムサービスがUDP 138、セッションサービスがTCP 139を使うこと、NetBTを無効にするとそれらを待ち受けなくなることについて。 

  29. Microsoft Learn, Windows security baseline (Azure Policy guest configuration). NetBTのノードタイプ(B-nodeはブロードキャストのみ、P-nodeはWINSのみ、M-nodeはブロードキャスト後にWINS、H-nodeはWINS後にブロードキャスト)、WINSが未構成ならB-node・構成済みならH-nodeが既定であること、推奨がP-nodeであることについて。  2 3

  30. Microsoft Learn, Windows Internet Name Service (WINS). WINSがNetBIOS名をIPアドレスに対応づけるレガシーなサービスであり、新規に展開せずDNSを使い、展開済みならDNSに移行して廃止することが推奨されることについて。  2

  31. Microsoft Learn, nbtstat. /cでNetBIOS名キャッシュを表示し、/Rでキャッシュを消去してLmhostsの事前タグ付き項目を再読み込みし、/RRでWINSへの登録を解放・再登録することについて。 

  32. Microsoft Learn, Features removed or no longer developed in Windows Server. Computer Browserサービスが時代遅れで安全でない機器探索プロトコルとして非推奨になったこと、WINSなどレガシーな名前解決関連機能の扱いについて。 

  33. Microsoft Learn, Direct host SMB over TCP/IP. Windows Vista / Windows Server 2008以降のSMB 2.0.2がTCP 445を必要とし、NetBIOSセッショントランスポートを使わないこと。同資料はその利点として名前解決をDNSに標準化できることを挙げているが、これはSMBの輸送路の話であり、クライアントのDNSクライアントが単一ラベル名をLLMNRやNetBTで解決する挙動を止めるものではない(本文5.4節)。 

  34. Microsoft Learn, Add-DnsClientDohServerAddress. DoHサーバー構成を既知のサーバー一覧に追加し、-DohTemplate・-AllowFallbackToUdp・-AutoUpgradeで暗号化失敗時のフォールバックと自動格上げを指定することについて。 

  35. Microsoft Learn, netsh dnsclient. add/set encryptionによるDoH・DoTサーバーの登録(dohtemplate・dothost・autoupgrade・udpfallback)、set globalによるdoh/dot/ddrの全体設定、show encryption・show global・show stateについて。  2 3 4 5

  36. Microsoft Learn, User data and privacy in Microsoft Edge: Secure DNS. セキュアDNSが既定で現在のプロバイダーを使い、暗号化接続に失敗すると平文で再試行すること、特定プロバイダーを選ぶと平文に戻らないこと、組織管理下のPCでは既定で無効であることについて。 

  37. Microsoft Learn, Microsoft Edge policy: DnsOverHttpsMode. off・automatic・secureの3モードと、管理対象デバイスで未構成ならDoHの問い合わせを送らないことについて。 

  38. Microsoft Learn, Guidance for configuring IPv6 in Windows for advanced users. Windows Vista以降がRFC 3484のプレフィックステーブルで使うアドレスを決め、既定でIPv6グローバルユニキャストをIPv4より優先すること、IPv6の無効化を推奨せずDisabledComponentsの0x20で「IPv4を優先」を使うべきことについて。  2 3

  39. IETF, RFC 3484: Default Address Selection for Internet Protocol version 6 (IPv6). 宛先アドレスの選択規則の第1則が「使えない宛先を避ける」であり、送信元アドレスや経路の無い宛先を先に外してから、プレフィックスポリシーの優先度で候補を並べることについて。 

  40. Microsoft Learn, Configure DNSSEC rules using the Name Resolution Policy Table. NRPTの名前空間の種類(サフィックス・プレフィックス・FQDN・サブネット・Any)と、サフィックスが子ドメインを含む末尾一致であること、より具体的な規則が一般的な規則より優先されることについて。 

  41. Microsoft Learn, Troubleshooting Domain Name System (DNS) issues: Data collection. クライアントとサーバーでnetsh trace start capture=yesを開始し、ipconfig /flushdnsでキャッシュを捨ててから再現し、netsh trace stopで止めるデータ収集手順について。 

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

この記事は次のサービスページにつながります。近い入口からご覧ください。

よくある質問

この記事のテーマについて、相談時によくある質問をまとめています。

hostsファイルを書き換えたのに反映されません。なぜですか?
Windowsのhostsファイルの内容はDNSクライアントサービスの起動時にキャッシュへ読み込まれ、名前解決はキャッシュ→hosts→DNSサーバーの順で進みます。反映されないときは、まずipconfig /displaydnsでその名前の項目を確認し、古い応答が残っていればipconfig /flushdnsで捨ててください。次に、調べているツールがWindowsのリゾルバーを通っているかを疑います。nslookupはOSのリゾルバーを使わず、キャッシュもhostsもNRPTも素通りしてDNSサーバーに直接問い合わせるため、hostsの内容は一切反映されません。hostsを含めた実際の解決結果を見るにはResolve-DnsNameかpingを使ってください。それでも反映されないなら、ブラウザーのように独自のリゾルバーやDoHを持つアプリかどうかを確認します。
ブラウザーではサイトが開けるのに、業務アプリだけ名前解決に失敗します。
ブラウザーとアプリが違う経路で名前を引いている可能性が高い状態です。Microsoft Edgeは、既定でOSのDNSクライアントではなく内蔵のDNSクライアントでDNSサーバーと通信し、セキュアDNS(DoH)で別のプロバイダーを選べば外部のリゾルバーに問い合わせます。一方、.NETのDns.GetHostAddressesや、宛先に直接接続するHttpClientはOSのgetaddrinfoを通るので、hosts・DNSキャッシュ・NRPT・サフィックス検索リストの影響をすべて受けます(HTTPプロキシ経由の要求では宛先の名前はプロキシ側で解決されます)。両者が別の答えを返す場合、どちらの経路がどのDNSサーバーに何を聞いたかをResolve-DnsNameとパケットキャプチャで突き合わせるのが最短です。
同じ設定のはずなのに、一部のPCだけ社内サーバーに繋がりません。何を比べればよいですか?
名前の形と、そのPCがどの層で答えを得ているかを比べます。単一ラベル名(server01のような点を含まない名前)は、PCのDNSサフィックス検索リストや接続固有のサフィックスで補われてDNSに送られ、既定ではそれと並行にLLMNRやNetBIOSブロードキャストといった同一サブネット限定の手段にも問い合わせられます(DNSの失敗後に順に試されるのは最適化を無効にしたときだけです。WINSが構成されていればNetBIOSはユニキャストでサブネットを越えられます)。ドメイン参加PCはサフィックスでFQDNに補完されて解決できても、VPN経由や別サブネットのPC、LLMNRとNetBIOSを無効化したPCでは同じ名前が解決できません。繋がるPCと繋がらないPCの両方でGet-DnsClientServerAddress・Get-DnsClientGlobalSetting・Get-DnsClient・Get-DnsClientNrptPolicy -Effectiveの出力を採り、差分を取るのが確実です。根本対策は、設定ファイルやショートカットの宛先をFQDNにすることです。
名前解決が失敗するのではなく、数秒待たされてからやっと繋がります。原因は何ですか?
DNSクライアントのタイムアウトとリトライの仕組みが表に出ている状態です。Windowsは応答のないDNSサーバーに対して開始から1秒・2秒・4秒・8秒の時点で再送し、10秒で打ち切ります。複数のDNSサーバーを設定していても、応答があるサーバーがリストの4番目以降にあると、最低4秒待ってからでないとそのサーバーに問い合わせません。また、長いDNSサフィックス検索リストは、単一ラベル名の解決でサフィックスを順に試すぶんだけ遅延を積み上げます。Measure-CommandでResolve-DnsNameの所要時間を測り、Wiresharkでdns.qry.nameのフィルターをかけて、どのサーバーへの問い合わせが無応答になっているかを見てください。
セキュリティ対策でLLMNRとNetBIOSを無効化したら、一部の機器に名前で繋がらなくなりました。
想定される副作用です。LLMNRとNetBIOS over TCP/IPは、DNSに登録されていない機器の単一ラベル名を同一サブネット内で解決する二次的な手段で、無効化すればその経路が消えます。Microsoft自身も2022年にmDNSへ寄せてNetBIOS名前解決とLLMNRを段階的に縮退させる方針を示しており、無効化の方向自体は正しい判断です。対策は名前解決をDNSに集約することで、機器のAレコードを社内DNSに登録するか、DHCPによる動的登録を有効にし、アプリや共有の宛先をFQDNに書き換えます。mDNSに対応した機器なら.local名で解決できますが、こちらもマルチキャストが届く範囲に限られます。
Windows 11のDoH(DNS over HTTPS)を有効にすると、社内の名前解決はどうなりますか?
DoHは、DNSクライアントが設定済みのDNSサーバーへ問い合わせる際の輸送路をHTTPSに替える機能で、hosts・キャッシュ・NRPTといった既存の順序はそのまま生きます。DoHが使えるのは、DDR(Discovery of Designated Resolvers)を有効にしていなければ、そのサーバーが既知のDoHサーバーの一覧に載っている場合だけで、社内DNSを使うなら管理者がAdd-DnsClientDohServerAddressで登録する必要があります。グループポリシーの「DNS over HTTPS (DoH) 名前解決の構成」で「DoHを要求する」にすると、DoH非対応のサーバーでは名前解決そのものが失敗します。Microsoftはドメイン参加PCでこの設定を有効にしないよう明記しています。Active Directoryが依存するWindows Server標準のDNSサーバーサービスがDoHの問い合わせに対応していないためです。

著者プロフィール

記事の著者プロフィールページです。

小村 豪

合同会社小村ソフト 代表

Windows ソフト開発、技術相談、不具合調査を中心に、既存資産が残る案件や原因が見えにくい障害調査に強みがあります。

ブログ一覧に戻る