ClashのDNSリーク検出と防止設定の手順

オンライン検査とローカルのパケットキャプチャでDNSのプロキシ迂回を確認し、dnsのnameserver・fallback・fake-ipを設定してリークを防ぎます。

まずDNSリークに該当する状態を確認する

ブラウザーでドメインにアクセスすると、先にドメイン名をIPアドレスへ解決する必要があります。プロキシ接続がClash経由でも、DNSクエリまで必ずプロキシ経路に入るとは限りません。Windowsが現在の回線、社内ネットワーク、公共Wi-Fiから通知されたDNSサーバーへUDP 53またはTCP 53でクエリを送信していれば、通信事業者やネットワーク管理者は解決したドメインを確認できます。これがトラブルシューティングで最もよくあるDNSリークです。

検査結果にローカルの通信事業者が表示されても、それだけで設定ミスとは限りません。ルールモードでは、中国本土のドメインをローカルDNSで解決し、海外ドメインを別のDNSグループへ振り分けることがあります。この分流により、検査ページに複数のDNS出口が表示される場合があります。本当に確認すべきなのは、本来プロキシで処理するドメインが物理ネットワークアダプターから直接解決されていないか、またノードを切り替えてもDNS出口がローカルネットワークに固定されたままではないかです。

よくあるリーク経路

オンライン検査で3回比較する

オンラインDNS検査は現象の確認を素早く行うのに適していますが、1回の結果だけでは判断できません。ブラウザーキャッシュ、システムDNSキャッシュ、検査サイトのノード情報データベースが表示結果に影響します。同じブラウザーと同じ検査ページを使って3回連続で確認し、プロキシ出口IP、DNSサーバー数、事業者名、地域を記録してください。

  1. Clashを完全に終了し、30秒待ってから標準検査を1回実行し、ローカルネットワークのDNS基準値を記録します。
  2. Clashを起動し、システムプロキシだけを有効にします。ローカルネットワークとは異なる地域のノードを選び、完全な検査をもう一度実行します。
  3. 同じノードを維持したままTUNとDNSハイジャックを有効にし、キャッシュを削除して3回目の検査を行い、結果の変化を比較します。

WindowsのDNSとブラウザーキャッシュを削除する

管理者としてPowerShellまたはコマンドプロンプトを開き、次のコマンドを実行してWindowsのDNSキャッシュを削除します。

ipconfig /flushdns

Chromium系ブラウザーには、独自のホストキャッシュや接続プールが残っている場合もあります。すべてのブラウザーウィンドウを閉じてから再起動するのが最も確実です。テスト中は、ほかのVPN、ゲーム向け通信最適化ツール、仮想マシンのネットワーク、社内セキュリティクライアントを同時に動かさないでください。別のネットワークコンポーネントがDNSを引き継ぐ可能性があります。

検査結果 考えられる原因 次の手順
ローカル事業者のDNSだけが表示される Clash DNSが引き継いでいない、またはブラウザーがシステムDNSを使っている TUN、dns-hijack、システムプロキシの状態を確認する
ローカルDNSとリモートDNSが同時に表示される ルールによる分流、キャッシュ、複数の名前解決経路が併存している キャッシュを削除して53番ポートの通信をキャプチャする
ノードを切り替えてもDNSが変わらない DNSサーバーが常に直接接続されている、または固定DoHを意図的に使用している DNSリクエストがルールに従ってプロキシ経由になっているか確認する
検査は正常だが一部のアプリでリークする そのアプリが独自DNSを使っている、またはシステムプロキシを迂回している TUNへ切り替えてDNSハイジャックを有効にする

WindowsでDNSが直接接続されていないか確認する

Windows標準のpktmonを使うと、平文の53番ポートリクエストが存在するかを簡単に確認できます。追加ツールのインストールは不要で、TUNの有効化前後に物理ネットワークアダプターからパケットが送信されていないかを確認するのに適しています。実行中のキャプチャを停止してから、管理者としてPowerShellを開いてください。

pktmon stop
pktmon filter remove
pktmon filter add DNS -p 53
pktmon start --etw -m real-time

ウィンドウを開いたまま、これまでアクセスしていないWebサイトをいくつか開き、宛先アドレスとネットワークアダプターを確認します。テストが終わったらCtrl+Cを押し、次を実行します。

pktmon stop
pktmon filter remove

宛先が192.168.1.1:53のようなルーターのアドレス、または回線から通知されたパブリックDNSで、パケットがWi-Fiやイーサネットの物理アダプターから送信されているなら、Clashに引き継がれていない平文クエリが残っています。Clashの起動直後に少数のリクエストだけ確認できる場合は、暗号化DNSのドメインを解決するための初期クエリかもしれません。Web閲覧中も継続して表示される場合は、設定をさらに調整してください。

システムが現在使用しているDNSサーバーを確認する

次のPowerShellコマンドで、すべてのネットワークアダプターのDNSアドレスを一覧表示できます。接続中のWi-Fiまたはイーサネットに加え、Clash、Wintun、Mihomoなどの仮想アダプターを重点的に確認してください。

Get-DnsClientServerAddress |
  Where-Object {$_.ServerAddresses.Count -gt 0} |
  Format-Table InterfaceAlias, AddressFamily, ServerAddresses -AutoSize

nslookupはシステムDNSの基準を確認するのに適していますが、ブラウザーでリークが発生していないことを単独で証明する用途には向きません。通常はシステムに設定されたDNSサーバーを直接呼び出すため、SOCKSやHTTPプロキシ、独自DoHを介したブラウザーのリクエストを再現しないことがあります。トラブルシューティングでは、nslookupの結果をpktmonとClashのログと合わせて確認してください。

nameserver、fallback、fake-ipを調整する

DNS設定の目的はサーバーアドレスを単純に増やすことではありません。Clashが通常のドメインをどのDNSで解決するか、暗号化DNSのアドレスを誰が最初に解決するか、返された結果をルールシステムへどう渡すかの3点を明確にします。以下は構成を確認するための基本例です。YAMLではインデントを必ず統一してください。

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16

  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://8.8.8.8/dns-query

  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4

  fake-ip-filter:
    - "*.lan"
    - "localhost.ptlogin2.qq.com"
    - "+.stun.*.*"
    - "+.stun.*.*.*"

default-nameserver:初期解決専用

default-nameserverには通常、直接アクセスできるIPアドレスを指定し、DoHサーバー自身のドメインを解決します。たとえば、HTTPS接続を確立するには、まずdns.alidns.comのIPを知る必要があります。ここにドメイン名を指定するのは避け、大量のアドレスも設定しないでください。安定したIP解決サーバーを2つ用意すれば、十分な冗長性を確保できます。

nameserverとfallback:分流の目的を明確にする

nameserverは主要なDNSサーバー、fallbackは従来のClash設定における予備DNSサーバーです。fallback-filterと組み合わせると、カーネルはGeoIPや応答アドレスの範囲などの条件に基づいて、どの結果を採用するかを決定します。Clash MetaやmihomoのバージョンによってDNSポリシーの拡張機能は異なります。サブスクリプションで設定を上書きする場合は、クライアントがローカルのDNS設定を保持しているかも確認してください。

DoHはDNSの内容を暗号化するだけで、接続が自動的にプロキシ経由になるわけではありません。リモートDNSサーバーへの接続にもプロキシルールを適用したい場合は、respect-rulesproxy-server-nameservernameserver-policyに対応した新しいmihomoカーネルを使用し、まずプロキシサーバーのドメイン用に独立したDNSを用意してください。「プロキシサーバーを解決するには先にプロキシへ接続する必要がある」という循環依存を避けられます。

fake-ip:ドメインを先にルールシステムへ渡す

fake-ipモードでは、まずアプリに198.18.0.0/16範囲のマッピングアドレスを返し、アプリが接続を確立するときに元のドメインを復元してルールに照合します。アプリが独自に解決して宛先IPだけを送る状況を減らせるため、ルールによる分流とDNSの引き継ぎが安定します。このアドレス範囲はベンチマーク用ネットワークのため、家庭や社内で実際に使っているサブネットと重複させないでください。

LAN機器の検出、プリンター、ゲームのオンライン接続、STUN、一部のログインドメインはfake-ipに適さない場合があるため、fake-ip-filterへ追加します。フィルターリストに確認していないルールを何百件もそのままコピーするのは避けてください。項目を1つ追加するたびに、そのドメインは実IPで解決されることになります。LAN機器が見つからない、またはアプリのログインが繰り返される場合に、ログから具体的なドメインを追加するほうが管理しやすくなります。

TUNとDNSハイジャックでプロキシ非対応アプリをカバーする

システムプロキシの影響を受けるのは、Windowsのプロキシ設定に従うプログラムだけです。コマンドラインツール、ゲーム、ストアアプリ、一部のランチャーは直接接続することがあるため、System ProxyだけでDNSを完全に引き継ぐのは困難です。TUNモードでは仮想ネットワークアダプターを作成し、IP層で通信を処理します。さらにdns-hijackを組み合わせることで、アプリが送信する53番ポートのクエリを捕捉できます。

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

Clash for Windows 0.20.39では、まず「General」→「Service Mode」でサービスモードをインストールし、その後「General」→「TUN Mode」を開きます。設定ファイルは「Profiles」で現在の設定を確認でき、右クリックメニューの「Edit」からDNSセクションを確認できます。mihomo対応のグラフィカルクライアントではメニュー名が異なる場合がありますが、カーネルの権限、TUNスイッチ、DNSハイジャックの3点を同時に確認してください。

strict-route: trueはWindowsでマルチホームDNSなどの迂回経路を制限するのに役立ちますが、社内VPN、Hyper-V、WSL、仮想マシンのブリッジ、LAN共有によってルーティングが変わることがあります。有効化後にプリンターやNASへアクセスできなくなった場合は、まずルーティングテーブルとClashのログを確認し、すべてのプライベートアドレスをプロキシルールへ追加するのは避けてください。

IPv6も同じ基準で確認する

設定のdns.ipv6: falseは、Clash DNSがAAAAレコードを返さないことを示します。プロキシノードまたは現在のネットワークに安定したIPv6がない場合に適しています。ローカルネットワークとプロキシノードの両方がIPv6に対応しているならtrueへ変更できますが、TUN、ルーティング、ルールがIPv6を処理できることを同時に確認してください。DNSでAAAAの応答を無効にするだけでは、システムレベルのIPv6が無効になったことにはなりません。

決めた順序で再検査し、残った問題を特定する

変更後に複数のノード、モード、ブラウザーを一度に切り替えないでください。ノードを1つに固定し、設定を再読み込みしてから同じ順序で再検査すると、どの手順で変化したかを判断できます。

  1. クライアントのログでYAMLが正常に読み込まれ、インデント、フィールド、DNSサーバーアドレスのエラーがないことを確認します。
  2. 現在の設定でdns.enabletrueになっており、待ち受けポート1053をほかのプログラムが使用していないことを確認します。
  3. TUNとdns-hijackを有効にし、ipconfig /flushdnsを実行します。
  4. ブラウザーを閉じて再起動し、これまで開いていない3つのドメインへアクセスします。
  5. オンラインの完全検査を実行し、DNSの数、地域、サービス事業者を記録します。
  6. 同時にpktmonで、物理ネットワークアダプターがUDP 53またはTCP 53を外部へ送信していないか確認します。
  7. ルールモードとグローバルモードをそれぞれ切り替えて、もう一度検査します。ルールモードでだけローカルDNSが表示される場合は、DNSポリシーと直接接続ルールを確認してください。

検査結果にローカルDNSが表示され続ける

Webページは開けないがリークは消えた

これは通常、検査が成功した正常な状態ではなく、DNSはハイジャックされたもののClash自身が上流DNSを解決できていない状態です。まずdefault-nameserverが純粋なIPアドレスになっているか確認し、次にDoHアドレスへ到達できるか確認してください。プロキシサーバーがドメイン名を使う場合は、直接接続できる初期解決経路も用意する必要があります。ネットワークが復旧してからfallback、ポリシーによる解決、フィルター項目を少しずつ追加し、すべての高度なフィールドを同時に有効にしないでください。

クライアントのダウンロードを見る