DNSクエリの入口・上流サーバー・応答の選別を理解する
ClashのDNSトラブルを解決するには、クエリの経路を順に確認します。アプリがどこへリクエストを送り、コアが受け取っているか、どの上流サーバーを選び、最終的にどの応答をアプリへ返しているかを調べましょう。nameserverを変更しただけでは、ブラウザーのクエリがClashに届くとは限りません。TUNを有効にしても、アプリ内蔵の暗号化DNSが通常のポートへのリダイレクトで処理されるとは限りません。
この記事ではmihomoコアを前提に設定を説明します。旧Clashや各クライアントでは、対応フィールドや設定の上書き方法が異なる場合があります。まずクライアントのコア情報で実際に動作しているコアを確認し、そのうえで最終的に適用された設定を調べてください。クライアント画面のスイッチ名は、YAMLのフィールド名の代わりにはなりません。
| フィールド | 階層 | 役割 |
|---|---|---|
enable / listen | dns | 内蔵DNSを有効にするか、どのアドレスとポートでクエリを受け付けるか。 |
nameserver | dns | 通常のドメイン名解決に使う主な上流サーバー。 |
fallback | dns | 予備の名前解決に使い、選別ロジックの対象となる上流サーバー。 |
fallback-filter | dns | fallbackの応答を採用する条件を判定する。 |
dns-hijack | tun | TUN経由のDNSトラフィックを内蔵DNSへ渡す。 |
nameserver:コアが使う上流DNSサーバー
nameserverは内蔵DNSが名前解決に使う主要なサーバーのリストです。通常のDNSアドレスのほか、コアが対応するDoHやDoTのアドレスも指定できます。ここに指定するのはDNSサービスであり、プロキシノードではありません。ノードのサーバーアドレスを入力しても、通常は有効なDNS応答を得られません。
まずは検証しやすい最小構成から
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: redir-host
nameserver:
- 223.5.5.5
- 119.29.29.29
これは既存の設定に追加するDNS部分であり、プロキシ設定全体ではありません。1053は内蔵DNSのテスト用待ち受けポートで、一般的な混合プロキシポート7890とは異なります。ループバックアドレスは同じ端末からの接続専用です。まず名前解決の経路を確認するのに適しています。LAN内の端末にもDNSサービスを提供する場合は、待ち受けアドレス、ファイアウォール、アクセス範囲を別途検討してください。
redir-hostは実際の名前解決結果を確認しやすいため、この記事の初期テストに適しています。ただし、常にこのモードを使う必要があるという意味ではありません。ipv6: falseは、この例でAAAAレコードの切り分けを簡単にするための設定です。OSのIPv6を無効にしたり、すべてのIPv6接続を遮断したりするものではありません。- 上流サーバーを複数指定しても、必ず先頭から順に応答を待つわけではありません。また、リストの順序だけで各クエリがどのサーバーを使ったかを判断することもできません。
DoHの接続先アドレス自体にも名前解決が必要な場合がある
上流サーバーをhttps://dns.alidns.com/dns-queryに変更すると、コアはまずdns.alidns.comのIPアドレスを調べる必要があります。default-nameserverはDNSサーバー自身のドメイン名を解決するための設定で、通常のWebサイト向けデフォルトDNS一覧ではありません。ドメイン名の初期解決を必要としないIPアドレスを指定すると、起動時の依存関係が循環するリスクを減らせます。
dns:
enable: true
listen: 127.0.0.1:1053
enhanced-mode: redir-host
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
DoHが暗号化するのは、クライアントからDNSサービスまでのDNS通信です。すべてのアプリの接続が自動的にプロキシ経由になるわけではありません。上流サーバーへの到達性、DNSクエリの送信経路、Webサイトへの接続に適用されるルールは、それぞれ個別に確認してください。
fallbackとfallback-filter:単純な障害時の切り替えではない
fallbackは「最初のDNSがタイムアウトした後に使う2台目のDNS」と考えるべきではありません。設定すると、コアは主な上流サーバーと予備の上流サーバーへ並行して問い合わせ、fallback-filterの条件に応じてどちらの応答を採用するか決めることがあります。実際のクエリ回数は、キャッシュや名前解決の方針、コアの実装にも左右されます。
選別条件にはドメイン名を指定する方法と、主な上流サーバーの応答IPを調べる方法があります。ドメイン名が指定条件に一致すると、fallbackの応答をそのまま採用できます。IP条件は、主な応答を予備の応答に置き換える必要があるかを判定します。いずれも接続先を振り分けるルールではありません。fallbackのDNS応答を選んでも、そのWebサイトへの接続が必ずプロキシ経由になるわけではありません。
地域判定を持ち込まず、明確なIP条件を使う
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: redir-host
default-nameserver:
- 223.5.5.5
nameserver:
- https://dns.alidns.com/dns-query
fallback:
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
fallback-filter:
geoip: false
ipcidr:
- 0.0.0.0/32
- 127.0.0.0/8
この例ではGeoIPによる選別を明示的に無効にし、2つのアドレス範囲だけを条件にしています。主な上流サーバーが返したIPアドレスが0.0.0.0/32または127.0.0.0/8に一致した場合、予備のDNS応答を採用します。これは仕組みを理解するための例で、あらゆる異常なDNS応答を検出できるルールではありません。導入前に、2つの予備DoHサービスへ現在のネットワークから接続できることも確認してください。
ループバックアドレスが、ローカル開発や広告ブロック、組織内のポリシーで意図的に返されている場合もあります。特殊なアドレスだからといって、すぐに誤りと決めつけないでください。また、プライベートアドレス空間全体を安易に条件へ追加すると、イントラネットのドメイン名が従来どおりに解決されなくなる可能性があります。
geoipとdomainの違い
geoip: trueとgeoip-code: CNを設定すると、主なDNS応答のIPアドレスが属する地域を基準に選別します。指定地域に該当しない応答は、fallbackに切り替わる場合があります。判定に使うのはIPアドレスの地域データであり、ページの内容ではありません。- GeoIPの判定には対応するデータが必要です。データがない、古い、またはIPアドレスの地域情報が実際のサービス設置場所と異なる場合、結果に影響します。地域判定だけで名前解決の正しさが保証されるわけではありません。
domainには、fallbackを使うドメインパターンを指定できます。たとえば+.example.comのように記述します。ここでのexample.comは構文例です。実際の設定には、必要性が明確なドメインだけを追加してください。fallback-filterは、予備の上流サーバーから返されるあらゆる不適切な内容を除外する機能でも、広告ブロック用のリストでもありません。
dns-hijack:ポート53のDNSクエリを内蔵DNSへ渡す
上流サーバーを設定したら、アプリのクエリが実際にコアへ届いているかも確認する必要があります。TUNモードでは、dns-hijackでTUNを通るDNSトラフィックを照合し、内蔵DNSへ渡して処理します。解決するのはクエリの入口の問題です。nameserverの代わりにはならず、到達できない上流サーバーを使えるようにするものでもありません。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
この設定例は、前述のdns:セクションと同じ階層に追加します。any:53はUDPポート53のクエリに一致し、tcp://any:53はTCP DNSを補います。通常のDNSはUDPだけではありません。応答が切り詰められた後の再試行や、一部アプリの動作ではTCPが使われることがあります。
auto-routeは、TUNにトラフィックを通すためのルートを自動設定します。通常、システムに応じた権限が必要です。クライアントがサービスモードや認証手順を通じてコアを起動する場合もあり、具体的な方法はプラットフォームによって異なります。ルートの作成に失敗しているときは、画面上で「TUN」が有効になっているだけでは、トラフィックが正しく取り込まれているか確認できません。
DNSのリダイレクト範囲は、プラットフォームによっても異なります。ローカルネットワークのDNSやループバックアドレス、特定のインターフェース宛てのクエリは、想定したTUN経路を通らないことがあります。特にシステムDNSにルーターのアドレスを指定している場合は、実際のクエリとログで確認してください。anyがOS内のすべてのDNSリクエストを意味するわけではありません。
Fake-IPとサブスクリプションの上書き:誤解しやすい2つの現象
198.18で始まるアドレスが返っても、必ずしも名前解決の異常ではない
enhanced-mode: fake-ipでは、コアがアプリにマッピング用アドレスを返し、その対応関係を使ってドメイン名と後続の接続を関連付けます。よく使われる設定例はfake-ip-range: 198.18.0.1/16です。このアドレス範囲が表示されたら、すぐにfallbackを変更するのではなく、まず現在の拡張モードを確認してください。
Fake-IPの応答が返っても、コアが実際の名前解決をまったく必要としないわけではありません。その後に解決するか、どの上流サーバーを使うかは、接続処理とポリシーによって変わります。fake-ip-filterはFake-IP応答を使わないドメインを指定するもので、上流サーバーの応答を選別するfallback-filterとは別の機能です。実IPアドレスが必要なイントラネットアプリでは、まずドメインの例外設定とイントラネット向けの名前解決経路を確認してください。
サブスクリプションのキャッシュを編集すると、更新時に変更が失われることがある
多くのクライアントでは、サブスクリプション、ローカルの上書き設定、画面上の設定を統合して実行用の設定を作成します。サブスクリプションから取得したファイルを直接編集すると、次回の更新で置き換えられる場合があります。また、DNSの設定場所が複数あると、編集したものとは別の値が最終設定に使われることもあります。
- まず動作中の設定をバックアップし、システムプロキシとTUNの有効・無効を記録します。
- クライアントが対応する、変更が保持される上書き設定を選び、DNSの変更元を一つに整理します。
- 設定を再読み込みしたら、最終的に適用された
dnsとtunのセクションを確認し、待ち受けポートとインデントの階層を照合します。 - サブスクリプションを一度更新し、上書き設定が残っているか確認します。初回のインポートだけでテストを終えないでください。
検証の手順:まず内蔵DNSを確認し、次にシステムからのDNS処理を確認
上流サーバーの変更、Fake-IPの有効化、TUNの有効化を一度に行うと、障害の原因を切り分けにくくなります。まずredir-hostと127.0.0.1:1053を使ってDNSサービスを検証し、必要な機能を一つずつ戻すのがおすすめです。以下のコマンドは確認方法の例であり、当サイトのネットワーク環境で実行した結果ではありません。
手順1:設定を検証し、待ち受けポートへ直接問い合わせる
mihomo -t -f config.yaml
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp
最初のコマンドを使うには、mihomoを端末上で直接実行でき、実際の設定ファイルを指定できる必要があります。クライアント管理のコアを使う場合は、対応する設定検証の手順を利用してください。後の2つのコマンドは、digがインストールされたシステムでUDPとTCPの問い合わせをそれぞれ確認します。コマンドが終了したかだけでなく、status、ANSWER SECTION、実際の応答を確認してください。
Windowsではnslookupを起動して対話モードに入り、サーバーとポートを指定できます。ここではDNS用の1053番ポートを指定してください。HTTP/SOCKSの混合プロキシポートを指定してはいけません。
nslookup
set port=1053
server 127.0.0.1
example.com
exit
手順2:直接問い合わせた結果とシステム標準の問い合わせ結果を比較
1053番ポートへの直接問い合わせがタイムアウトする場合は、まずコアが起動しているか、ポートで待ち受けているか、ログに上流サーバーへの接続エラーがないか確認してください。- 直接問い合わせは成功するのに、サーバーを指定しない
nslookup example.comが失敗する場合は、システムDNS、TUNのルート、DNSのリダイレクト範囲を確認してください。 - コマンドラインでは成功し、ブラウザーだけ失敗する場合は、ブラウザーのセキュアDNS、プロキシ設定、キャッシュを確認してください。名前解決が正常でも、接続先サイトのTCP接続やTLS接続が正常とは限りません。
- 設定を変更した直後も古い結果が返る場合は、コアを再読み込みし、関連アプリのキャッシュを削除してください。Windowsでは
ipconfig /flushdnsでシステムDNSキャッシュを消去できます。ただし、コアやブラウザーが個別に保持するすべてのキャッシュが消えるわけではありません。
| 現象 | 優先して確認する項目 | 最初に避けること |
|---|---|---|
| 1053番ポートから応答がない | enable、待ち受けポートの競合、コアのログ | 接続の振り分けルールを何度も変更する |
| 主な上流サーバーは使えるが、fallbackがタイムアウトする | 予備サービスへの接続可否と送信経路 | 到達できない上流サーバーをさらに追加する |
| イントラネットのドメイン名だけ解決できない | イントラネットDNS、ドメイン別の名前解決、Fake-IPの例外設定 | すべてのクエリをパブリックDNSに送る |
| Fake-IPが返るのにWebページを開けない | 後続の接続が同じコアに取り込まれているか | マッピング用アドレスだけを見てDNS汚染と判断する |
最後に確認する点は3つです。クエリが内蔵DNSに届いているか、上流サーバーから有効な応答が返るか、その後の接続が想定どおりに処理されるかを確認してください。nameserverとfallbackは名前解決に使うサーバーを、fallback-filterは応答の選択を、dns-hijackはTUN経由のDNSクエリの入口を処理します。この役割分担に沿って一つずつ変更すれば、設定変更と症状を結び付けて確認できます。プロキシグループやTUNの設定も見直す場合は、mihomo上級設定ガイドを参照してください。