まずClash DNSの処理フローを整理する
ClashのDNSモジュールは、システムの問い合わせを単一のパブリックDNSへ転送するだけの仕組みではありません。有効にするとローカルポートを待ち受け、設定された上流サーバーを読み込み、ドメイン名やルール、応答アドレスに基づいて採用する結果を決定します。TUNとDNSハイジャックを有効にすれば、ルーターやパブリックDNSの53番ポートへ送られる従来のリクエストも、この処理フローへ取り込めます。
一般的な問い合わせは4段階に分けられます。アプリがドメイン名のアドレスを問い合わせ、システムがリクエストをClashへ渡し、Clashがnameserver、該当するポリシーサーバー、またはfallbackへ問い合わせ、最後にfallback-filterと拡張モードに基づいて実IPまたはFake IPを返します。Webページの表示、ドメインルールのマッチ、プロキシノードのドメイン解決は、これらの各段階の影響を受ける可能性があります。
読みやすい基本設定
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
- 1.1.1.1
nameserver:
- https://dns.alidns.com/dns-query
- https://doh.pub/dns-query
fallback:
- https://1.1.1.1/dns-query
- https://dns.google/dns-query
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 240.0.0.0/4
ここでのlistenは127.0.0.1:1053を使用し、ローカルのループバックアドレスでUDP/TCPの1053番ポートだけを待ち受けることを示します。1053は一般的な非特権DNS待受ポートで、システム上の53番ポートサービスとの競合を避けられます。クライアントが待受アドレスを自動管理している場合は、購読ファイルに別の競合設定を重複して追加しないでください。
nameserver、default-nameserver、fallbackの役割
nameserver:通常のドメイン解決に使う入口
nameserverは、ほとんどのドメイン問い合わせで使われる主要な上流サーバーです。通常のUDP DNSのほか、対応するmihomoカーネルではDoHやDoTなども指定できます。家庭内ネットワークで低遅延を重視するなら、近距離で応答が安定したサーバーを選びます。暗号化通信が必要な場合は、HTTPS DNSアドレスを利用できます。
nameserver:
- 223.5.5.5
- 119.29.29.29
- https://dns.alidns.com/dns-query
同じリストに複数のサーバーを入れても、毎回必ず先頭から順番に待つとは限りません。具体的な並列処理や結果の選択方法はカーネルの実装に左右されるため、応答特性が大きく異なるサーバーを4~5台まとめて入れるのは避けたほうがよいでしょう。実際の設定では、安定した上流を2~3台に絞るほうが問題を切り分けやすくなります。
default-nameserver:DNSサーバー自身のドメイン名を先に解決
nameserverにhttps://dns.alidns.com/dns-queryのようなホスト名付きDoHアドレスを指定すると、カーネルはHTTPS接続を確立する前にdns.alidns.comのIPアドレスを知らなければなりません。default-nameserverは主にこのようなブートストラップ解決を担う、いわゆるbootstrap DNSです。
default-nameserver:
- 223.5.5.5
- 1.1.1.1
「DNSサーバーを解決するために、先にDNSサーバーへアクセスする」という循環依存を避けるため、ここには直接アクセスできるIPアドレスを優先して指定します。ログにlookup dns server failedやcontext deadline exceededが連続して出る場合は、DoHアドレスを増やす前に、まず現在のネットワークからこれらのアドレスへアクセスできるか確認してください。
fallback:別の視点から得る並列候補
fallbackは、主要な上流とは異なる解決結果を提供するために使われます。有効にすると、Clashはフィルター条件に基づいてnameserverの結果とfallbackの結果のどちらを採用するか判断します。nameserverがタイムアウトしたときだけ起動するわけではないため、遠距離のDoHサービスを増やしすぎると接続数やリソース消費が増える可能性があります。
ローカルネットワークの主要DNSが安定しており、Fake IPモードと十分なルールセットを組み合わせているなら、必ずしもfallbackを設定する必要はありません。まずシンプルな構成を動かし、DNS汚染、地域違いの結果、特定ドメインの異常が確認された段階で候補経路を追加するほうが、古いテンプレートを長々とコピーするより確実です。
fallback-filterで最終結果を選ぶ仕組み
fallback-filterは、主要な解決結果を置き換える必要があるかどうかを判定します。一般的な条件にはGeoIPの国コード、特定のネットワーク範囲、ドメインリストがあります。拡張フィールドへの対応はカーネルのバージョンによって異なる場合があるため、mihomoを使う際は現在のカーネルドキュメントと起動ログを基準にしてください。
geoipとgeoip-code
fallback-filter:
geoip: true
geoip-code: CN
この設定ではGeoIPデータを使って、返されたアドレスの地理的な所属を判定します。典型的には、主要な上流が期待する地域のアドレスを返した場合はその結果を採用し、返されたアドレスがフィルター条件に合わない場合はfallbackの結果を検討します。判定精度はクライアントが利用するGeoIPデータの更新状況に左右されるため、国コードを絶対に正確な経路測定結果と捉えてはいけません。
ipcidr:明らかに異常なアドレス範囲を除外
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 0.0.0.0/32
- 127.0.0.0/8
- 240.0.0.0/4
ipcidrでは、通常のパブリックドメインから返されてほしくないアドレス範囲を指定できます。たとえば、公開Webサイトが127.0.0.1へ解決されるのは通常不自然です。ただし、社内ネットワーク、家庭内サーバー、検証環境ではプライベートアドレスを実際に使うことがあるため、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16を無条件にすべて遮断しないでください。
domain:指定ドメインでfallbackを優先
fallback-filter:
geoip: true
geoip-code: CN
domain:
- '+.example.net'
- '+.example.org'
ドメインリストは、少数で再現性のある異常サイトへの対処に向いています。+.example.netのような記法は、そのドメインとサブドメインにマッチしますが、実際の構文が使用中のカーネルバージョンに対応している必要があります。リストを際限なく増やすべきではありません。数百ものドメインを手作業で指定しなければならない場合は、主要な上流、ルールセット、ネットワーク出口の選択を見直すべきサインです。
fake-ipとredir-host、どちらを選ぶべきか
enhanced-modeは、Clashがアプリへどのような結果を返すかを決めます。一般的な値はfake-ipとredir-hostです。どちらもプロキシ転送と組み合わせられますが、ドメインの保持方法、互換性、診断方法が異なります。
fake-ip:予約アドレスを返し、カーネル内でドメインにマッピング
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
Fake IPモードでは、198.18.0.23のような予約アドレスプールから一時的なアドレスを返します。アプリがそのアドレスへ接続すると、Clashは内部マッピングから元のドメイン名を復元し、ドメインルールとプロキシポリシーを適用します。実際のDNS結果を待ってから接続を確立する手順を減らせるほか、宛先IPしか見えない通信でもドメインとして復元しやすくなります。
198.18.0.0/15はベンチマーク用の予約ネットワークで、プロキシカーネルがFake IPのアドレスプールとしてよく利用します。LAN、企業VPN、検証環境ですでに同じ範囲を使っている場合は、カーネルが許可する競合しない範囲へ変更してください。pingの結果が198.18で始まっていても、ドメイン解決が誤っているとは限りません。重要なのは、そのリクエストをClashが引き受けているかどうかです。
fake-ip-filter:特殊なドメインには実IPを返す
fake-ip-filter:
- '*.lan'
- localhost.ptlogin2.qq.com
- '+.stun.*.*'
- '+.stun.*.*.*'
LAN機器の検出、プリンター、一部のオンラインゲーム、STUN、時刻同期、実アドレスを必要とするアプリは、Fake IPに適さない場合があります。その場合はfake-ip-filterへ追加します。フィルター項目は実際に発生した障害に基づいて一つずつ加え、変更後にシステムのDNSキャッシュを消去してください。長大なリストをそのままコピーすると、多数のドメインがFake IPを迂回し、ドメインマッピングの効果が弱まります。
redir-host:実IPを返し、互換性を確認しやすい
enhanced-mode: redir-host
redir-hostは、実際の解決アドレスをアプリへ返します。Fake IPと競合し、個別にフィルタリングするのが難しい古いソフトウェアや特殊なLAN環境に適しています。一方、ドメインルールが安定してマッチするかどうかは、スニッフィング、接続メタデータ、実際のトラフィック取り込み方式により強く左右されます。切り分けでは一時的にfake-ipからredir-hostへ切り替えてみてください。問題がすぐ解消するなら、Fake IPのアドレス範囲の競合とフィルターリストを重点的に確認します。
TUNモードでもDNSハイジャックが必要な理由
システムDNSを127.0.0.1:1053に設定するだけでは、すべてのプログラムが従うとは限りません。アプリによっては8.8.8.8:53へ直接UDPリクエストを送り、ルーターから通知されたDNSを使うデバイスもあります。TUNモードはIP通信を取り込み、DNSハイジャックはさらに、該当する53番ポートのリクエストをClash DNSモジュールへ渡します。
mihomo設定でよく使われるTUNの例は次のとおりです。対応フィールドはカーネルやクライアントのラッパー実装によって変わるため、GUIクライアントがTUN設定を自動生成する場合は、画面上のスイッチから操作することを優先してください。画面設定と購読YAMLが互いに上書きしないよう注意が必要です。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
enableでTUNの取り込みを有効にします。stack: mixedで、カーネルがサポートする混合ネットワークスタックを使用します。auto-routeで必要なルートを自動的に追加します。auto-detect-interfaceで現在の出口ネットワークインターフェースを検出します。any:53で、取り込んだ通信に含まれる通常の53番ポートDNSリクエストにマッチさせます。
DNSハイジャックが主に対象とするのは、従来のUDP/TCP 53番ポートです。アプリ内蔵のDoHはHTTPSの443番ポートを使うため、ネットワーク層では通常のHTTPSに見え、dns-hijackだけですべてを書き換えることはできません。ブラウザーで「セキュアDNS」が有効な場合は、一時的に無効にして、ブラウザーとClashのどちらが名前解決しているか確認してください。
日常利用に適したmihomo設定の考え方
普段使いのデスクトップやスマートフォンでは、「ローカルの上流で一般的な名前解決を処理し、暗号化した候補で異常な結果に対応し、Fake IPでドメインをマッピングし、TUNハイジャックで従来のDNSを取り込む」という方針から始められます。以下の例は構造上の関係を示すもので、すべてのネットワークで同じサーバーを使うことを推奨するものではありません。
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
use-hosts: true
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
- https://doh.pub/dns-query
fallback:
- https://1.1.1.1/dns-query
- https://dns.google/dns-query
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 0.0.0.0/32
- 127.0.0.0/8
- 240.0.0.0/4
fake-ip-filter:
- '*.lan'
- localhost
- '+.stun.*.*'
- '+.stun.*.*.*'
ローカルネットワークにIPv6の出口がない場合は、ipv6をfalseにすると、アプリがAAAAレコードを受け取って到達不能な経路を試すのを防げます。安定したネイティブIPv6があり、プロキシノードとルールもIPv6を正しく処理できる場合は有効にできます。通信事業者からIPv6アドレスが割り当てられているかだけでなく、デフォルトルート、DNS応答、プロキシ出口が完全に機能するかも確認してください。
mihomoにはnameserver-policy、proxy-server-nameserver、direct-nameserverなどの拡張フィールドもあり、特定のドメイン、プロキシノードのドメイン、ダイレクト接続のそれぞれに専用のリゾルバーを指定できます。これらは解決経路を明確に分けた構成に適しています。基本設定がまだ動いていない段階で高度なフィールドを一度に追加すると、循環解決が起きたり、ノードのドメインが誤った出口を通ったりしやすくなります。
プロキシノードがドメイン名の場合の注意点
購読設定のサーバーアドレスがnode.example.comのようなドメイン名の場合、プロキシ接続を確立する前にカーネルがその名前を解決しなければなりません。そのドメインのDNS解決自体が、まだ確立していないプロキシ経由でなければ実行できない設定だと、「プロキシがないとノードを解決できず、ノードがないとプロキシを確立できない」という循環が生じます。mihomoではproxy-server-nameserverを使い、ノードのドメインだけに直接接続可能なリゾルバーを指定できます。
proxy-server-nameserver:
- 223.5.5.5
- https://dns.alidns.com/dns-query
DNS異常を段階的に切り分ける方法
ステップ1:設定がカーネルに読み込まれているか確認
- YAMLを保存したら、クライアントの「設定を再読み込み」を実行してください。エディターを閉じるだけでは不十分です。
- カーネルログを開き、
DNS、listen、timeout、parseを検索します。 - YAMLのインデントエラーが出る場合は、
dns:の下が同じスペース幅でインデントされているか、リスト項目の前にハイフンが残っているか確認してください。 - 現在選択している購読設定が、自動更新時にローカルの変更を上書きしていないか確認します。
YAMLはインデントに敏感です。次のようにfallbackを誤ってnameserverのリスト内へインデントすると、意図した構造を表現できません。各レベルは2スペースで統一し、Tabは使わないことをおすすめします。
ステップ2:Clashの待受ポートへ直接問い合わせる
WindowsではPowerShellまたはコマンドプロンプトでnslookupを使い、macOSとLinuxではdigを使えます。問い合わせ先を待受アドレスに指定すると、「Clash DNS自体の失敗」と「システムがリクエストをClashへ渡していない」問題を切り分けられます。
nslookup example.com 127.0.0.1
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA
nslookupは通常53番ポートへ接続します。Clashが1053番ポートだけを待ち受けている場合は、ポートを指定できるツールを使うか、クライアント側でシステムの53番ポートのリクエストを1053番へ転送してください。Fake IPモードで198.18.x.xが返るのは想定どおりです。タイムアウトが続く場合は、ポートの占有状況、ファイアウォール、上流サーバーへの到達性を確認します。
ステップ3:解決できるかだけでなく上流の応答を測定する
一度正常に応答したからといって、経路が安定しているとは限りません。20回ほど連続して問い合わせ、断続的なタイムアウトがないか確認します。LAN内の通常DNSは5~30ミリ秒程度、地域をまたぐDoHは80~250ミリ秒に達することがあります。具体的な値は接続環境に左右されるため、単発の最小値ではなく、タイムアウト率と変動幅を重視してください。
- DoHだけタイムアウトする:システム時刻、TLS接続、DoHドメインのブートストラップ解決を確認します。
- 通常のUDP DNSとDoHの両方がタイムアウトする:現在のネットワーク、デフォルトルート、ファイアウォールを確認します。
- 問い合わせは成功するのにWebページが開かない:プロキシルール、ノード接続、TUNルートを引き続き確認します。
redir-hostへ切り替えると復旧する:Fake IPのアドレス範囲の競合とフィルター項目を確認します。- LAN内ドメインだけ失敗する:内部ドメイン用の解決ポリシーを設定するか、必要なFake IPフィルターを追加します。
ステップ4:古いキャッシュを消去して再テスト
上流サーバーや拡張モードを変更した後も、システム、ブラウザー、Clashが古い結果を保持している可能性があります。Windowsではipconfig /flushdns、systemd-resolvedを使うLinuxではresolvectl flush-cachesを実行できます。ブラウザーが独自のホストキャッシュを持つこともあります。キャッシュを消去したら設定を再読み込みし、同じドメインを再テストしてください。古いレコードを新設定の結果と取り違えないことが重要です。
これらのフィールドを設定する際の最終チェックリスト
enableが有効で、待受ポートが本機のほかのDNSサービスと競合していない。default-nameserverへ、プロキシを確立する前でも直接アクセスできる。nameserverは安定した上流を2~3台に絞り、大量の重複サービスを詰め込まない。fallbackは異なる解決視点を提供するために使い、タイムアウト後のバックアップとして機械的に扱わない。fallback-filterのGeoIP、ネットワーク範囲、ドメイン条件が現在のネットワーク環境に合っている。fake-ip-rangeが企業VPN、家庭内LAN、検証ネットワークの範囲と競合していない。fake-ip-filterには実IPが必要なドメインだけを追加する。- TUNモードが有効な場合、
dns-hijackとクライアントの自動設定が重複・競合していないことを確認する。 - プロキシノードにドメイン名を使う場合、ノードのドメイン解決がまだ確立していないプロキシに依存していないか確認する。
- 変更するフィールド群は毎回1つだけにし、変更前後の問い合わせ結果とログを記録する。
Clash DNS設定で重要なのは、あらゆるネットワークで使える固定テンプレートを探すことではありません。解決の入口、候補結果、フィルター条件、拡張モード、通信の取り込みを、検証可能な一連の経路としてつなぐことが大切です。まず最小限の項目で問い合わせが届くことを確認し、そこからFake IP、fallback、TUNハイジャックを段階的に追加すれば、問題が起きても原因の箇所を正確に特定できます。