上級設定 読了まで約12分

ClashのDNS設定を徹底解説:nameserver・fallback・fake-ipの仕組み

ClashのDNS設定を項目別に解説。nameserverやfallback、fake-ipとredir-hostの違い、DNS hijackが有効になる条件を、すぐ使える設定例とともに紹介します。

まず結論:DNSの上流・応答アドレス・通信の取り込みを分けて確認

ClashのDNS設定で混同しやすいのは、実は次の3点です。どのDNSサーバーに問い合わせるか、アプリにどのアドレスを返すか、アプリのDNSリクエストがカーネルに届いているか。nameserverとfallbackは1つ目、enhanced-modeは2つ目を担当します。3つ目はシステムDNS、待ち受けポート、TUNのdns-hijackによって決まります。モードをfake-ipに変えただけでは、端末全体のDNS通信は自動的に取り込まれません。

以下の主な設定例はmihomoを対象にしています。Clashはクライアントのエコシステムで広く使われる呼称ですが、画面が似ていても内部の設定項目が完全に同じとは限りません。オリジナル版Clash、過去の各種フォーク、現行のmihomoでは、TUNやDNSの拡張項目への対応に差があります。クライアントのカーネル情報または起動ログで実装を確認してください。コマンドラインで運用している場合はmihomo -vを実行して環境を確認し、画面のバージョンからカーネルの機能を推測しないでください。

  • サブスクリプションの読み込みに成功:設定を読み込めたことを示すだけで、システムがそのDNSを使っているとは限りません。
  • ノードの遅延テストに成功:テスト対象への接続を確認しただけで、すべてのドメインが正しく解決されるとは限りません。
  • 198.18のアドレスが返る:fake-ipモードでは想定どおりの場合があり、直ちにDNS汚染と判断する必要はありません。

nameserverとdefault-nameserver:通常の名前解決とブートストラップ

dns.nameserverは、通常のドメイン名解決に使う上流DNSサーバーのリストです。上流には通常のDNSサーバーのIPアドレスのほか、カーネルが対応するDoHやDoTのアドレスも指定できます。リストは「常に1台目を優先し、2台目は障害時だけ使う」という固定の優先順ではありません。複数の上流をどう扱うかはカーネルの問い合わせ・応答処理に依存するため、記述順だけで厳密なプライマリ/バックアップ構成を実現しようとしないでください。

DoHを設定したのに、なぜ通常のDNSも使われる?

たとえばhttps://dns.alidns.com/dns-queryはDoHサービスのアドレスですが、HTTPS接続を確立するには、先にdns.alidns.comのIPアドレスを知る必要があります。default-nameserverは、このようなDNSサービスのドメイン名を最初に解決するために使います。以下では223.5.5.5と119.29.29.29を指定しています。依存関係を分かりやすくするための例であり、すべてのネットワークに適したアドレスという意味ではありません。

項目役割よくある誤解
enableカーネルのDNS機能を有効にする有効にすればシステムが必ず使う
listenDNSサービスの待ち受けアドレスとポートを指定する1053番ポートとシステム標準の53番ポートは自動で連携する
default-nameserverDNS上流サーバーのドメイン名を解決するすべての通常のドメイン名解決で優先される
nameserver通常の上流DNSサーバーを指定するリストの順番どおりに厳密なフェイルオーバーが行われる
enhanced-modefake-ipやredir-hostなどの処理方式を選ぶモードを選べばシステムの通信も取り込まれる

DoHの暗号化が保護するのは、クライアントからDNSサービスまでの区間です。リクエストがプロキシノードを経由することを自動的に意味するものではありません。上流への到達性、DNS接続の送信経路、通常の通信に適用されるルールは、それぞれ確認が必要です。mihomoにはproxy-server-nameserverなどの拡張項目もあり、プロキシサーバーのドメイン名解決を個別に設定できます。依存関係を把握しないまま、ノード自身のドメイン名解決をそのノードに依存させないでください。

fallbackとfallback-filter:候補の応答を選別する設定で、ルール用のポリシーグループではない

fallbackは「予備DNS」と呼ばれることがありますが、nameserverが完全にタイムアウトしたときだけ使うバックアップリストではありません。fallbackを設定すると、カーネルが通常のグループとfallbackグループの両方に問い合わせ、フィルター条件に基づいて応答を選ぶ場合があります。ここでいう「グループ」はDNS上流の集合です。proxy-groupsに設定するノード選択や自動遅延測定のグループとは別のものです。

geoip・ipcidr・domainはそれぞれ何を判定する?

  • geoip: trueとgeoip-code: CNを組み合わせると、通常グループから返されたアドレスの地域を判定します。指定地域に該当しない応答では、fallbackの応答を使う処理が行われます。利用可能な地理情報データがカーネルに必要です。
  • ipcidr:240.0.0.0/4など、特定のアドレス範囲をフィルター対象として扱います。確認するのは名前解決の応答であり、通常の通信にプロキシルールを追加する設定ではありません。
  • domain:一致したドメイン名にfallbackの応答を使います。ドメイン名に対する指定条件であり、通常グループから異常なIPアドレスが返るのを待つ必要はありません。

これらの条件は、すべてを満たした場合にだけ実行される連続チェックではありません。「リスト内のドメインであり、CN以外のアドレスが返り、さらに予約済みアドレス範囲にも一致すること」が唯一の発動条件だと考えないでください。また見落としやすい制約として、誤ったアドレスが地理情報データ上でCNと判定される場合、geoipだけでは異常を検出できないことがあります。fallbackは応答を選ぶ仕組みであり、名前解決の正しさを保証するものではありません。

特定のドメインをどのDNSサーバーで解決するか明示したい場合、mihomoのnameserver-policyを使うと分かりやすく設定できます。これは名前解決に使う上流を決める項目で、通常の通信の送信先はrulesで決まります。互いの代わりにはなりません。ドメインを海外のDNSで解決しても、通信が自動的にプロキシルールに一致するわけではありません。

fake-ipとredir-host:仮想アドレスを返すか、実際のアドレスを返すか

fake-ip:ドメイン名との対応関係を保持する

enhanced-mode: fake-ipは、対象となる問い合わせに仮想アドレスを返し、ドメイン名と仮想アドレスの対応関係をカーネル内に保持します。その後、アプリがこのアドレスに接続すると、カーネルが対応関係から接続先を特定できるよう、通信が同じカーネルを通る必要があります。例にある198.18.0.1/16はベンチマーク用に予約されたアドレス範囲であり、接続先サイトの実サーバーアドレスではありません。

この方式では接続時にもドメイン名の情報を保持しやすく、実際の接続先アドレスの解決を待たずに接続できる場合があります。ただし、「どのドメインも実際のDNS解決が不要になる」わけではありません。直接接続する宛先、IPアドレスを使うルール判定、カーネルごとの処理経路によっては、実際のDNS解決が必要です。fake-ipなら上流DNSは不要だと考えると、原因を特定しにくい接続エラーにつながります。

redir-host:実際のアドレスを返し、ドメイン名との関連付けを確認する

redir-hostは上流DNSが返す実際のIPアドレスを返し、カーネルはDNSキャッシュなどを使ってドメイン名と関連付けます。実際のアドレスを必要とするプログラムとの互換性は高めやすい一方、DNS応答の異常を解消するものではなく、すべての接続でドメイン名の情報が保持されるとは限りません。アプリによる独自の名前解決、キャッシュの期限切れ、カーネルを経由しない接続などによって、ルールの適用結果が変わる可能性があります。

  • デスクトップでTUNを日常利用する場合:まずfake-ipを検証し、DNSと後続の通信が同じカーネルで処理されることを確認できます。
  • LAN内の機器、プリンター、社内サービスで問題が起きる場合:モードを切り替える前に、LANのDNS設定と除外リストを確認してください。
  • 実際のIPアドレスを必要とする特定のアプリ:対象ドメインをfake-ip-filterに追加できます。すべてのアプリをすぐにredir-hostへ切り替える必要はありません。

fake-ip-filterは「このドメインにはfake-ipを返さない」という意味であり、「このドメインへの通信はプロキシを使わない」という意味ではありません。以下の設定例ではlocalhost、*.lan、*.localを除外しています。ただし、除外しただけでパブリックDNSがルーターのプライベートドメインを解決できるようになるわけではありません。内部ドメインを使うには、利用可能なLAN内DNSサーバーが別途必要です。.localはmDNSが関係することもあり、通常のDNS上流を変更するだけでは解決できない場合があります。

そのまま使えるDNS設定例:まず127.0.0.1:1053で動作確認

以下は既存の設定全体のうちdns:部分だけを置き換える例です。ノード、ポリシーグループ、通常の通信ルールは含みません。サブスクリプションのほかの設定はそのまま残してください。すでにdns:がある場合は統合または置き換えを行い、トップレベルのキーが重複しないようにします。GUIクライアントでは起動時にサブスクリプションの項目が上書きされることがあるため、永続化できるオーバーライド機能を使い、最終的に有効な設定を確認してください。

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "localhost"
    - "*.lan"
    - "*.local"
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
  fallback:
    - https://cloudflare-dns.com/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4
      - 0.0.0.0/8

ここではまずローカル環境だけでテストできるよう、ループバックアドレスで待ち受けます。0.0.0.0:53では待ち受けず、LANにもDNSサービスを公開しません。ipv6: falseは今回のDNS検証範囲を絞るための設定であり、OSのIPv6を無効にするものではありません。また、すべてのIPv6通信がブロックされたと判断することもできません。

まず構文を確認し、次に待ち受けを確認

コマンドライン環境では、設定ファイルのあるディレクトリで次のチェックを実行できます。GUIクライアントが設定ファイルの場所を管理している場合、コマンドで起動オプションを直接置き換えないでください。クライアントの設定チェック機能を使い、ログでDNSサービスが正常に起動したことを確認します。

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

example.comは問い合わせ経路の検証に使える公開ドメインです。fake-ip対応環境で198.18.x.xが返るのは正常な場合があります。UDPとTCPの両方がタイムアウトする場合は、待ち受け、ポートの競合、カーネルログを確認してください。Windowsにdigがインストールされていない場合は、対話型のnslookupでDNSサーバーとポートを指定できます。

nslookup
server 127.0.0.1
set port=1053
set type=A
example.com
exit

TUNでDNS hijackが有効になる条件:53番ポートの通信がカーネルを通ること

OSの通常のDNS通信には、一般にUDPまたはTCPの53番ポートが使われます。前述の1053はテスト用の待ち受けポートであり、システムが53番から自動的に転送することはありません。多くのOSでは、DNS設定画面から任意のポートを指定することもできません。通常のDNS通信を取り込むには、クライアントのTUNによるDNS制御を使うか、明示的なローカル転送を設定します。システムDNSに127.0.0.1を指定しただけで1053番ポートに接続できると思わないでください。

次の項目に対応するmihomo環境では、この設定を既存のtun:設定に統合できます。有効にする前に、仮想ネットワークインターフェースの作成やルート変更に必要な権限を、クライアントまたはOSの手順に沿って付与してください。クライアントがすでにTUNを管理している場合は、設定画面を優先して使い、画面の設定と手書きの設定が上書きし合わないようにします。

tun:
  enable: true
  stack: system
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53

any:53はUDPのDNS通信に、tcp://any:53はTCPのDNS通信に一致します。ここでのhijackは、TUNの処理経路に入ったDNSリクエストをカーネルのDNSモジュールに渡すものです。すべてのリクエストを単純にローカルの1053番ポートへ転送するわけではありません。この経路に通信が入るかどうかは、システムのルート、ほかのVPN、インターフェースの選択、プラットフォームの制約にも左右されます。

dns-hijackを設定しても、次の通信はすべて取り込まれるわけではありません

  • ブラウザー独自のDoH:通常はHTTPS通信として扱われ、53番ポートのルールでは通常のDNSとして直接判別できません。
  • OSやアプリのDoT:通常は853番ポートを使うため、ここで設定した53番ポートの一致条件には含まれません。
  • TUNを通らない通信:ほかのVPNが取り込んでいる通信、別のルートを通る通信、プラットフォームの実装上の制限を受けるリクエストなどが該当します。
  • キャッシュ済みの応答:アプリが新たな問い合わせを行わず、以前のアドレスや確立済みの接続を使い続ける場合があります。

システムプロキシとTUNも混同しないでください。ブラウザーがHTTPプロキシにドメイン名を渡す場合、接続先の名前解決はプロキシ側で行われることがあります。一方、システムプロキシを使わないアプリは、システムDNSを直接使う可能性があります。切り分けの際はブラウザー内蔵のセキュアDNSを一時的に無効にして基準となる状態を確認し、その後、必要な設定に戻してください。

トラブルシューティング:複数の設定を同時に変えず、症状から原因を特定

症状まず確認する項目次に行うこと
ローカルの1053番ポートへの問い合わせがタイムアウトするDNSが有効か、設定が反映されているか、ポートが使用中でないか起動ログを確認し、UDPとTCPを別々にテストする
ローカルの問い合わせは成功するが、アプリの名前解決に失敗するアプリがカーネルのDNSを使っているかシステムDNS、TUNのルート、アプリ内蔵のDoHを確認する
198.18のアドレスが返るが、接続がタイムアウトする後続の通信が同じカーネルに戻っているか仮想ネットワークのルート、TUNの状態、接続ログを確認する
一部のドメインだけ応答に時間がかかるfallbackに接続できるか、フィルター条件によって選択されているか名前解決エラーを確認し、予備の上流を個別に検証する
LAN内のドメインを解決できないパブリックDNSでプライベートな名前を解決しようとしていないかLAN内のDNSサーバー、またはドメイン別の名前解決ポリシーを設定する
設定を変えても動作が変わらないサブスクリプションの上書き、システムのキャッシュ、アプリの長時間接続有効な設定を確認し、キャッシュを消去して接続し直す

モードの切り替えに合わせてキャッシュもクリアする

fake-ipからredir-hostに切り替えた後やTUNを無効にした後も、アプリに仮想アドレスがキャッシュされていることがあります。Windowsではipconfig /flushdnsを実行します。systemd-resolvedを使用するLinuxではresolvectl flush-cachesを実行できます。各コマンドには適用条件があり、どのOSでも使える共通コマンドではありません。ブラウザー独自のDNSキャッシュや接続プールも別途処理が必要です。必要に応じてアプリを完全に終了し、再起動してください。

検証には固定のドメインを1つ選び、まずDNS問い合わせを行ってから該当ページにアクセスします。同時に接続パネルで接続先ドメイン、適用ルール、送信先ポリシーを確認してください。パブリックIP確認ページだけでDNSを判断しないでください。出口IPから分かるのは、そのWeb接続がどこから出ていったかであり、DNS問い合わせに使われたサーバーまでは特定できません。

サブスクリプションの読み込みや基本的な接続手順を確認する場合は、入門ガイドのサブスクリプション設定をご覧ください。DNSとルールの関係については、ユーザーマニュアルのDNSの章で確認できます。基本は変わりません。まずリクエストがカーネルに届いているかを確認し、次に上流DNSとフィルター条件を検討してから、互換性リストを調整します。

Clash最新版をダウンロード