ClashのDNSリークを検出する方法:ブラウザテスト・ログ解析・漏洩防止設定

検出結果、システムの名前解決経路、クライアントログを確認し、fake-ip・リモートDNS・フォールバックを設定します。

まずDNSリークの定義を確認する

Webサイトにアクセスすると、通常はアプリがまずドメイン名をDNSリゾルバーに渡し、返されたIPアドレスを使って接続します。プロキシ接続がClashを経由していても、ドメイン名の問い合わせまで同じ経路を通るとは限りません。システムがルーター、通信事業者のリゾルバー、または社内ネットワークの内部DNSへ問い合わせを続ける場合があります。このとき、対象サイトの本文トラフィックはプロキシを通る一方、ドメイン名の問い合わせだけがローカルネットワークから送信されます。これがClashのDNSリークを調べる際に注目すべき核心的な現象です。

判定は、検査ページに複数のDNSサーバーが表示されたかどうかだけで行えません。パブリックDNSサービスはエニーキャスト、転送クラスター、異なる出口を利用するため、検査サイトに表示されるサーバーアドレスが設定に記入したアドレスと一致するとは限りません。複数の結果が同じDNSサービスに属していることもあります。より確実なのは、リゾルバーのネットワーク事業者と地理的位置、テスト中のClashログ、そして端末から実際に送信された53・853番ポートまたはHTTPSのリクエストを照合する方法です。

DNSリーク、WebRTCによるアドレス露出、プロキシ出口の変化も区別する必要があります。WebRTCテストに表示されるLANアドレスやパブリック候補アドレスは、ブラウザのリアルタイム通信経路に属するもので、DNS問い合わせが迂回したことを意味しません。プロキシ出口の検査でローカルのパブリックIPが表示された場合は、まずプロキシモード、ルールのマッチ状況、UDPの取り込みを確認し、いきなりDNSを変更しないでください。3種類の問題は、それぞれ別に証拠を集める必要があります。

よくあるリークの兆候

  • プロキシを有効にしても、DNS検査ページに自宅のブロードバンド回線やモバイル通信事業者のリゾルバーが表示される。
  • 別地域のプロキシノードへ切り替えても、DNS問い合わせがローカルネットワークから直接送信され続ける。
  • ClashのログにはWebサイトへの接続が記録されるのに、対応するドメインが内蔵DNSモジュールに入った記録がない。
  • ブラウザとコマンドラインでテスト結果が異なり、片方のアプリだけが想定した名前解決経路を迂回している。
  • システムプロキシモードではWebページを正常に開けるのに、端末のパケットキャプチャにはルーター宛てのUDP 53番ポート通信が残っている。

ブラウザテスト、コマンドライン確認、パケットキャプチャを段階的に実行する

ブラウザのDNS検査は、切り分けの入口として適しています。この種のページでは通常、ランダムなサブドメインを複数生成してブラウザに新しい問い合わせを発生させ、権威DNS側で実際の再帰リゾルバーを記録します。テスト前に、通信中の他のアプリを終了し、OSとブラウザのDNSキャッシュを消去して、新しいプライベートウィンドウを使ってください。キャッシュがヒットすると問い合わせが省略され、実際よりきれいな結果に見えることがあります。

標準テストと拡張テストを実行したら、まずリゾルバーのIP、ネットワーク事業者、国または地域を記録します。期待される結果は設定の目的によって異なります。Clashが指定したリモートDoHを使う場合、結果はそのサービスの再帰問い合わせの出口に対応するはずです。ドメイン名のルールにより、中国本土のドメインをローカルの暗号化DNSへ、それ以外をリモートDNSへ振り分ける場合は、2組のサービスが表示されることがあります。重要なのは、各組が明確な設定に沿っているかであり、ページに1つのアドレスだけを表示させることではありません。

コマンドラインでシステムDNSと指定リゾルバーを切り分ける

ブラウザが独自のセキュアDNSを有効にしている場合があるため、OSの名前解決経路もテストします。WindowsではnslookupまたはPowerShellのResolve-DnsName、macOSとLinuxではdigを使用できます。まず、これまでアクセスしたことのないドメインを問い合わせ、コマンド出力にあるサーバーアドレスを確認します。家庭用ルーターのアドレス、たとえばLANゲートウェイが表示されるなら、システムは依然として問い合わせをルーターへ渡しています。これは最終的に必ずリークしていることを意味しませんが、そのコマンドのDNS入口がまだClashに直接なっていないことを示します。

nslookup example.net

Resolve-DnsName example.net

dig example.net
dig @127.0.0.1 -p 1053 example.net

最後に、Clashまたはmihomoのローカル待受ポートを明示して問い合わせます。システムのデフォルト問い合わせと比較するのに適した方法です。明示的な問い合わせは期待どおりなのに、デフォルトの問い合わせだけがルーターを経由する場合、問題はシステムDNSの向き先か、TUNによるDNSハイジャックの段階にあります。両方の問い合わせが望ましくないリゾルバーに到達するなら、カーネル設定と上流DNSを続けて確認します。

ポートと宛先アドレスをキャプチャする

端末がLANやインターネットへ従来型DNSを直接送信していないか確認するには、テスト中にUDP/TCP 53番ポートの通信をキャプチャします。Linuxではtcpdump、Windowsではシステムのネットワークトレースツール、macOSではアクティブなインターフェース上でtcpdumpを使用できます。インターフェース名は実際の環境に合わせて置き換えてください。

sudo tcpdump -ni any 'port 53 or port 853'

sudo tcpdump -ni en0 'udp port 53 or tcp port 53'

パケットキャプチャに、ルーターや通信事業者のDNS宛ての53番ポート通信が現れれば、直接の名前解決が続いている強い証拠です。53番ポートの通信が見えなくても、すぐに調査を終えてはいけません。アプリがDoHを使い、DNSを443番ポートのHTTPSに包んでいる可能性があるためです。その場合は、Clashの接続ログ、ブラウザのセキュアDNS設定、宛先アドレスを組み合わせて判断します。

システム、Clashカーネル、上流リゾルバーの順に経路を特定する

DNS経路は3つの段階に分けられます。アプリが誰に問い合わせを渡すのか、Clashがその問い合わせを受け取っているのか、そしてClashがどのネットワーク経路で上流へアクセスするのかです。この3点を個別に確認するほうが、パブリックDNSのアドレスを何度も置き換えるより効果的です。

第1段階:アプリからシステムまたはブラウザのリゾルバーまで

多くのデスクトップアプリはOSの名前解決インターフェースを呼び出しますが、ブラウザは独自のDoHを有効にしている場合があり、一部のコマンドラインプログラムは指定サーバーへ直接問い合わせることもあります。システムプロキシは通常、HTTP・HTTPS・SOCKSのプロキシアドレスだけを設定し、すべてのシステムDNSを書き換えるわけではありません。システムプロキシの環境では、ブラウザがまずローカルで名前を解決し、その宛先をプロキシへ渡す経路がよく使われます。

ブラウザのテストだけが異常な場合は、まずブラウザのセキュアDNSを確認します。無効にしてシステムとClashに任せることも、Clashの方針と一致するDoHサービスを明示的に設定することもできます。複数のアプリでローカルの名前解決リクエストが発生するなら、OSのDNS、TUNの取り込み、クライアントのDNSスイッチを優先して確認します。

第2段階:問い合わせがClash内蔵DNSに入っているか

設定でdns.enableが有効になっていることを確認し、ローカルの待受アドレスがクライアント画面の表示と一致するか確認します。グラフィカルクライアントによっては、画面から実行用設定を生成するため、サブスクリプションファイルのDNS項目が上書きされることがあります。トラブルシューティングでは、サブスクリプションの原文だけでなく、カーネルが実際に読み込んだ設定を確認してください。

ログレベルを一時的にdebugへ変更し、ログを消去してからランダムなサブドメインを問い合わせます。ログ形式はClashの派生版やクライアントによって異なりますが、DNS問い合わせ、ルールのマッチ、上流リクエストの失敗、タイムアウト、フォールバックの選択を重点的に確認します。ログにそのドメインがまったくないなら、リクエストはまだカーネルに入っていません。ドメインは記録されているのに上流への接続がDIRECTなら、DNS上流への接続経路を確認します。

第3段階:Clashから上流DNSへの接続

問い合わせが内蔵DNSに入っていても、上流のDoHやDoTがDIRECTで接続される場合があります。暗号化は通信中の問い合わせ内容と読み取れる範囲を保護しますが、上流接続の宛先アドレスまで隠すものではありません。リモートDNSへの接続をプロキシ方針に従わせるなら、現在のカーネルが対応するプロキシ指定方法を使うか、ルールベースのDNS上流接続を有効にし、プロキシサーバーのドメイン名用に独立したブートストラップリゾルバーを用意します。

プロキシノードをドメイン名で指定している場合、カーネルはプロキシトンネルを確立する前にノードサーバーのIPを取得する必要があります。この起動時の依存関係で、まだ確立していないプロキシ接続を使って解決しようとしてはいけません。mihomoのproxy-server-nameserverはプロキシサーバーのドメイン名解決に使われ、default-nameserverはDoH上流自体のドメイン名など、基盤となる名前解決を担当します。両者の役割は異なります。

fake-ip・リモートDNS・フォールバックで問い合わせを集約する

Clash Metaの設定に対応するmihomoカーネルでは、fake-ipがよく使われる高度な名前解決モードです。アプリがドメイン名を問い合わせると、内蔵DNSはまず予約済みアドレスプールから対応アドレスを返します。アプリがそのアドレスへ接続すると、カーネルはマッピングから元のドメイン名を復元し、ルールのマッチとプロキシの選択を行います。これにより、アプリがローカルで実IPを先に取得する可能性を抑え、ドメイン名ベースの振り分けにも役立ちます。

以下は、項目間の関係を理解するための基本的な断片です。パブリックな名前解決エンドポイントは構造を示す例にすぎず、実際の導入ではネットワークからの到達性、サービス規約、プライバシー要件に応じて選択してください。クライアントに組み込まれたmihomoのバージョンによって対応する構文が異なる場合があるため、変更前に現在のカーネルのドキュメントを確認し、元の設定を保存してください。

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter-mode: blacklist
  fake-ip-filter:
    - "*.lan"
    - "localhost.ptlogin2.qq.com"
    - "time.*.com"
  default-nameserver:
    - 223.5.5.5
    - 1.1.1.1
  nameserver:
    - https://dns.alidns.com/dns-query
    - https://1.1.1.1/dns-query
  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query
  respect-rules: true

listenは内蔵DNSの待受位置を決めます。端末内だけで使う場合は、クライアントの実装に応じてアクセス範囲を制限してください。TUNモードでは、クライアントが待受とハイジャックを自動管理することが一般的です。fake-ip-rangeは専用のアドレス範囲でドメイン名のマッピングを管理するため、ローカルLAN、コンテナネットワーク、企業ルーターの範囲と重複させないでください。

fake-ip-filterはfake-ipに適さないドメインを除外します。LAN機器の検出、時刻同期、一部のゲームプラットフォーム、実際のLANアドレスを必要とするサービスでは、実IPを返す必要がある場合があります。除外項目は実際に発生した障害をもとに1つずつ追加してください。広範囲のドメインをすべて除外リストに入れると、多数のリクエストが実IPの名前解決へ戻り、fake-ipによる経路集約の効果が弱まります。

respect-rulesを有効にするとDNS上流への接続がルールに従います。ただし、proxy-server-nameserverでプロキシサーバーのドメイン名を解決できるようにしなければなりません。そうしないと、プロキシの確立を待つためにDNSが必要になり、DNSもプロキシを待つという循環依存が起こる可能性があります。旧版Clashや保守が終了した一部の派生版には同名の項目がない場合があるため、実際のカーネルの対応状況を基準にしてください。

nameserver-policyでドメインごとのリゾルバーを正確に指定する

ドメインごとに異なる名前解決経路が必要なら、nameserver-policyを使用できます。通常は共通のnameserverより優先度が高く、内部ドメイン、特定のルールセット、地域別ドメインにリゾルバーを指定するのに適しています。ポリシーの範囲が広すぎると、検査ページに複数の再帰問い合わせ出口が表示されるため、各ルールには明確な目的を持たせてください。

dns:
  nameserver-policy:
    "geosite:cn":
      - https://dns.alidns.com/dns-query
    "+.internal.example":
      - 192.168.10.1
  nameserver:
    - https://1.1.1.1/dns-query

内部ドメインを企業や家庭のDNSへ渡す場合、その問い合わせはローカルネットワークに入ります。これは意図した振り分けであり、意図しないリークと混同してはいけません。ただし、ワイルドカードルールで一般的なパブリックドメインまで覆わないようにし、内部リゾルバーが信頼できるネットワークでのみ使われることも確認してください。

fallbackを理解し、テンプレートを機械的にコピーしない

一部の設定ではfallbackfallback-filterを使用します。カーネルはメインとフォールバックのリゾルバーへ並行して問い合わせ、地理的IP、ドメインの種類、予約済みアドレスなどを基準に採用する結果を決められます。この仕組みは主に、DNS汚染、誤った結果、ネットワークごとの可用性の違いに対処するためのもので、DNS問い合わせが自動的にプロキシを通ることを保証するものではありません。

dns:
  nameserver:
    - https://dns.alidns.com/dns-query
  fallback:
    - https://1.1.1.1/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    geosite:
      - gfw

メインとフォールバックの両方がローカルから直接接続されていれば、検査で望ましくない経路が表示される可能性があります。フォールバックを設定するときは、上流接続のルーティング、リモートエンドポイントの安定性、ルールセットが正常に読み込まれるかを併せて確認してください。現在のmihomo設定ではnameserver-policyによって、より明確なドメイン単位の選択もできます。fallbackを残すかどうかは用途に応じて決めます。

TUNモードではDNSハイジャックとアプリの迂回を同時に処理する

システムプロキシが影響するのは、主にプロキシ設定に従うアプリです。ゲーム、システムサービス、一部のコマンドラインプログラム、独自に接続を確立するソフトウェアは無視することがあります。TUNモードは仮想ネットワークインターフェースを通じて、より広範なIPトラフィックを取り込むため、UDP、プロキシ非対応アプリ、システムDNSをまとめて処理するのに適しています。ただし、管理者権限、ルーティング設定、各プラットフォームのネットワークスタックに依存します。

mihomoのTUN設定には通常、自動ルートとDNSハイジャックが含まれます。具体的な項目はバージョンやクライアントのラッパーによって変わりますが、典型的な構成は次のとおりです。

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

dns-hijackは、TUNを通過する従来型の53番ポート問い合わせを内蔵DNSへ送ります。有効にしたら再度パケットをキャプチャし、通信が物理NICからルーターへ直接送られ続けていないか確認します。プラットフォームのセキュリティソフト、仮想マシン、コンテナ、VPN、企業ネットワーククライアントが、より高い優先度のルートやフィルタードライバーをインストールし、トラフィックの一部がTUNを迂回する場合があります。その場合は、ルーティングテーブル、インターフェースの優先度、クライアントログに記録されたインターフェースの選択を確認します。

DNSハイジャックは通常、従来型のUDP/TCP 53番ポートを対象にします。ブラウザ内蔵のDoHはHTTPSの443番ポートを使うため、53番ポートのハイジャックだけでは取り込めません。ブラウザのセキュアDNSが独立したサービスを指している場合、DIRECTで接続されたり、通常の接続ルールに従ってアクセスされたりする可能性があります。対処方法は2つです。ブラウザ独自の名前解決を無効にして、システムとClashへ統一するか、ブラウザのDoHを残したまま、そのエンドポイントに明確なプロキシルールを設定します。併用する場合は各経路を記録し、ブラウザのテスト結果をカーネルDNSの障害と誤判定しないようにしてください。

IPv6もテスト対象に含める

ローカルネットワークがIPv6に対応していると、アプリがAAAAレコードを優先して問い合わせ、IPv6で直接接続することがあります。IPv4の出口とAレコードだけを確認すると、この経路を見落とします。プロキシノード、ルール、TUNがIPv6を完全にサポートしているなら、DNSのIPv6機能を維持し、A・AAAAの問い合わせとデュアルスタックの出口を個別にテストしてください。現在のプロキシチェーンがIPv6に対応していない場合は、DNSレコードを1項目削除するだけでIPv6の直接接続経路を残すのではなく、カーネル、システムインターフェース、ルーティング層で一貫した対応を行います。

変更後は固定のチェックリストで再テストする

漏洩防止設定の有効性は、キャッシュを消去して新しい問い合わせを発生させたうえで確認します。開いているページを更新するだけでは、ブラウザ、システム、Clashのキャッシュ結果が使われ続ける可能性があります。まずクライアントのカーネルを再起動し、システムDNSキャッシュを消去して、古いブラウザプロセスを終了します。その後、ランダムなサブドメインでテストを始めてください。

  1. カーネル設定が反映されているか確認:クライアントの実行設定と起動ログを確認し、DNSモジュール、fake-ip、TUNで解析エラーが発生していないことを確かめます。
  2. プロキシ出口を確認:ブラウザとシステムプロキシに従わないアプリを個別にテストし、接続がルールに従ってDIRECTまたは対象のプロキシグループへ入ることを確認します。
  3. ブラウザのDNSテストを実行:各再帰リゾルバーのネットワーク上の所属を記録し、nameserver、ポリシーによる名前解決、ブラウザのDoH設定と照合します。
  4. システムコマンドで問い合わせ:デフォルトの名前解決とClashのローカルポートへの直接問い合わせを比較し、システムの入口が統一されているか確認します。
  5. カーネルログを確認:新しいドメイン名で名前解決を発生させ、問い合わせがDNSモジュールに入り、上流リクエストが成功し、ルールとプロキシチェーンが想定どおりであることを確認します。
  6. 物理インターフェースの通信をキャプチャ:ルーターやパブリックサーバーへ向かう予期しない53・853番ポート通信が残っていないか確認します。
  7. デュアルスタックとフェイルオーバーをテスト:IPv4とIPv6を個別に確認し、上流の1つを一時停止して、フォールバックが予定外のローカルリゾルバーへ切り替わらないことを確認します。

よくある障害と確認ポイント

現象 優先して確認する項目 対処の方向性
ブラウザにはローカルリゾルバーが表示されるが、コマンドラインは正常 ブラウザのセキュアDNS、拡張機能、キャッシュ システムの名前解決へ統一するか、ブラウザのDoHを明示的にプロキシ経由にする
システムの問い合わせはルーター経由だが、ローカルポートへの直接問い合わせは正常 システムDNSアドレス、TUN、dns-hijack システムの入口を修正するか、有効なDNSハイジャックを有効にする
respect-rulesを有効にするとノードへ接続できない プロキシサーバーのドメイン名解決 proxy-server-nameserverを設定して起動時の依存関係を解消する
fake-ipを有効にするとLAN機器が使えなくなる fake-ip-filterとローカルアドレス範囲 影響を受けるLANドメインだけに除外項目を追加する
検査結果に想定外のリゾルバーが2組表示される fallback、nameserver-policy、ブラウザのDoH 1項目ずつ無効にし、ログで実際の選択を確認する
IPv6だけローカルの出口が表示される AAAAの名前解決、TUNのIPv6ルート、ノードの対応状況 デュアルスタックを統一して取り込むか、ネットワーク条件に合わせてIPv6を一貫して無効にする

最終的な目標は、検査ページに特定の国や決まった数のDNSアドレスを表示させることではありません。名前解決経路を設定と一致させることです。アプリの問い合わせが想定した入口に入り、Clashがルールに従って上流を選択し、上流接続が計画したDIRECTまたはプロキシ方針で送信され、フォールバックとIPv6も設計を迂回しない状態にします。この4つの段階をログ、コマンドライン、パケットキャプチャで相互に検証できて初めて、DNSリークの調査は完了です。

インストールと設定を続ける

システムとプロセッサーアーキテクチャに合ったClashクライアントを選び、クイックスタートに沿ってサブスクリプションの読み込み、プロキシモード、DNSを設定してください。

Clash をダウンロード