mihomoのDNS設定を解説:nameserver・fallback・fake-ipによるDNSハイジャック

mihomoのdns設定を項目別に解説。nameserver、fallback、fallback-filter、enhanced-mode、DNSハイジャックの役割と、よくある構成例を紹介します。

DNS上流・応答モード・リクエストのリダイレクトを切り分ける

mihomoのDNS設定は、リクエストの受け取り先、問い合わせる上流DNS、アプリに返すアドレスの3層に分けられます。nameserverとfallbackは上流の名前解決を担当し、enhanced-modeは実IPとfake-ipのどちらを使うかを決めます。tun.dns-hijackは、条件に一致するDNS通信を内蔵リゾルバーへ転送します。3層は連携しますが、互いに代用できるものではありません。

設定ファイルにDNSアドレスを書いただけでは、ブラウザーがそのDNSを使うとは限りません。OSがルーターに問い合わせたり、ブラウザー独自のDoHで暗号化された名前解決を行ったりすることもあります。トラブル時は、まずリクエストがmihomoに届いているかを確認し、その後で上流DNSの状態を調べましょう。

設定項目主な役割混同しやすい点
dns.listenローカルDNSの待ち受けアドレスを指定OSのDNS設定は自動で変更されない
nameserverデフォルトの上流DNSを設定プロキシノードの一覧ではない
fallback応答の選別に使う別の上流DNSを指定メイン上流のタイムアウト時だけ使う再試行先ではない
fallback-filterドメイン名や応答アドレスに基づいて結果を選別Web接続で使うノードを直接決める設定ではない
enhanced-modefake-ipまたはredir-hostを選択TUNを有効にする設定ではない
tun.dns-hijack条件に一致するDNSリクエストをリダイレクト任意のDoHやDoTを直接復号できるわけではない

nameserverとdefault-nameserver:上流DNSと名前解決の起点

nameserverは、デフォルトで使用する上流DNSのリストです。通常のDNSやDoHなど、サポートされている形式を指定できます。通常のDNSの例は223.5.5.5、DoHの例はhttps://dns.alidns.com/dns-queryです。DoHが暗号化するのはリゾルバーとの間の問い合わせ通信であり、アプリの接続がプロキシ経由になることを保証するものではありません。

default-nameserverが必要な理由

上流DNSにホスト名を指定した場合、コアは接続先サーバーのIPアドレスを先に調べる必要があります。たとえばdns.alidns.comに接続する前に、そのホスト名を名前解決しなければなりません。default-nameserverは、このような初期の名前解決に使います。IPアドレスを直接指定すれば、「DNSサーバーを調べるために同じDNSサーバーへ問い合わせる」という循環を避けられます。

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: redir-host
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
    - https://doh.pub/dns-query
  • 127.0.0.1:1053はローカル端末だけで待ち受けるため、LAN内のほかの端末にDNSサービスを公開しません。
  • redir-hostは実際の名前解決結果をアプリに返すため、まず疎通を確認する際の基準として適しています。
  • ipv6: falseを設定すると、内蔵DNSはAAAA問い合わせに空の結果を返します。OSのIPv6を無効にする設定ではなく、アプリが既知のIPv6アドレスへ直接接続することも防ぎません。
  • 上流DNSを複数指定しても、「上から順に1つずつ試す」という意味にはなりません。並び順によるドメインごとの振り分けには頼らないでください。

上記は独立したdns設定例で、ノードやプロキシルールは含みません。サブスクリプション全体を置き換えるのではなく、既存の設定に統合してください。ネットワークから特定のDNSサービスに接続できない場合は、現在のネットワークから到達できる上流DNSに変更します。

fallbackとfallback-filter:単なる予備ではなく応答結果を選別

fallbackという名前から、nameserverが使えないときだけ動作すると考えがちです。実際にはfallbackを設定すると、コアは2つの上流DNSへ並行して問い合わせ、fallback-filterに基づいてどちらの結果を使うか判断できます。そのため、通常のアクセス時にfallbackへの問い合わせが見えても、メイン上流の障害とは限りません。

よくある構成では、メイン上流に通常の名前解決を任せ、特定のドメインにfallbackを指定した場合や、メイン上流の応答がフィルター条件に合わない場合にfallbackの結果を使います。ここで選択するのはDNS応答であり、その後の接続先はプロキシルールによって判定されます。

GeoIPとIP範囲で選別する設定例

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: redir-host
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
  fallback:
    - https://dns.google/dns-query
    - https://cloudflare-dns.com/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4
    domain:
      - '+.google.com'
  • geoip: trueとgeoip-code: CNを組み合わせると、GeoIPデータを使ってメイン上流の応答アドレスが指定地域に属するか判定します。条件に合わない場合は、fallbackの結果が優先されます。
  • ipcidrリストにメイン上流の応答アドレスが一致すると、fallbackの結果が使われます。例の240.0.0.0/4はアドレスの選別条件であり、ノード用のネットワーク範囲やTUNのアドレスプールではありません。
  • domainに一致したドメインは、fallbackの結果で名前解決します。+.google.comはgoogle.comとそのサブドメインに一致します。
  • GeoIPの判定はコアが参照するデータに依存します。データベースが古い場合やCDNが複数地域に配置されている場合、想定と異なる上流が選ばれることがあります。

プライベートIPアドレスをすべて汚染された結果と見なさないでください。社内ドメインが10.0.0.0/8を返したり、家庭内の端末が192.168.0.0/16を返したりするのは正常な場合があります。これらの範囲をすべてipcidrに追加すると、内部ドメインの問い合わせがパブリックDNSへ送られるおそれがあります。社内ドメインには、フィルター範囲を広げるのではなく、ドメインごとの名前解決を優先してください。

fake-ipとredir-host:マッピングアドレスか実IPか

enhanced-mode: fake-ipは、ドメインに対してプール内のマッピングアドレスを割り当てます。アプリがそのアドレスへ接続すると通信がmihomoに入り、コアがマッピングからドメインを復元してルールを照合します。アプリ側で実IPを解決する必要を減らせますが、接続が実際にコアへ取り込まれていることが前提です。

redir-hostは実際の名前解決結果を返し、関連するドメイン情報を保持します。一般的なDNSの挙動に近い方式ですが、ドメインとアドレスが常に1対1で対応するとは限りません。接続時のドメイン識別は、通信の取り込み方法、キャッシュ、スニッフィングの設定にも左右されます。どちらのモードも、適切なプロキシルールの代わりにはなりません。

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
    - https://doh.pub/dns-query

fake-ip-filterに登録するドメイン

通常のブラックリスト方式では、fake-ip-filterに一致したドメインにはfake-ipを割り当てず、実際のアドレスを返します。例はローカル端末やLAN内の名前を例外として扱う方法です。設定でfake-ip-filter-modeを別途指定している場合は、まずフィルター方式を確認してください。ここでの説明をそのまま当てはめることはできません。

  • LAN内機器の検出、一部のゲーム、実IPを必要とするアプリなどは、具体的なドメインを例外に追加できます。範囲の広いワイルドカードを安易に登録するのは避けてください。
  • フィルターで変わるのはDNSの応答方式だけです。printer.lanが自動でルーターに問い合わせられるわけではありません。LAN内の名前を解決するには、対応するローカル上流DNSが必要です。
  • .localはmDNSに関係することがよくあります。フィルターリストに追加しても、mihomoがマルチキャストによる機器検出をプロキシしたり、画面ミラーリングを自動で直したりするわけではありません。
  • 198.18.x.xが表示されても、名前解決が汚染されたと判断しないでください。この例では想定どおりのfake-ip応答です。確認すべきなのは、接続がコアに取り込まれ、ドメインが復元されるかどうかです。

fake-ipからredir-hostへ、またはその逆に切り替えた後は、OSのDNSキャッシュを消去し、テストに使うアプリを再起動してください。ブラウザーに古いマッピングアドレスが残っていると、設定を変更しても接続では古いアドレスが使われ続けることがあります。

TUNのDNSハイジャック:ポート53のリクエストを内蔵リゾルバーへ転送

「fake-ipによるハイジャック」という表現には、別の2つの概念が混在しがちです。fake-ipは応答モード、DNSハイジャックはリクエストのリダイレクトです。次のトップレベルのtun設定は、前述のdns設定例のいずれかと統合し、TUNに入った条件一致のUDP・TCPポート53リクエストを取り込みます。

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

any:53はUDP DNS、tcp://any:53はTCP DNSを対象にします。ここでの53は照合する通信の宛先ポートです。前述のdns.listenに指定した1053はローカルテスト用の待ち受けポートであり、同じ値にする必要はありません。コアが一致したリクエストを内蔵DNSへ渡すため、OSが先に1053へ直接接続する設定ではありません。

有効にしても対象外になることがある通信

  1. ブラウザーのDoH:通常はHTTPSの443番ポートを使うため、一般的なポート53の問い合わせには該当しません。診断中はブラウザーのセキュアDNSを一時的に無効にし、テスト後に必要に応じて元に戻してください。
  2. アプリ内蔵のDoT:一般的な宛先ポートは853です。上記の2つのルールを設定しただけでは、内蔵DNSへの問い合わせには変換されません。
  3. TUNに入らない通信:ルーティングの除外設定、ほかのVPN、ネットワークインターフェースの選択、プラットフォームの制限などにより、リクエストが取り込み経路を迂回することがあります。
  4. LAN内の端末:PCでTUNを有効にしても、ネットワーク全体のDNSゲートウェイになるわけではありません。他の端末のゲートウェイ、DNS、転送経路は個別に設定する必要があります。

システムプロキシだけを使っている場合、ブラウザーのHTTP通信はプロキシ経由でも、OSのDNS問い合わせはルーターに送られることがあります。これはdns.enableが機能していないのではなく、リクエストが内蔵リゾルバーに届いていない状態です。利用方法に応じて、OSのDNS設定、TUNによる取り込み、または別の明示的なリダイレクト方式を選んでください。

LAN内ドメインの個別名前解決とプロキシノードのホスト名解決

家庭内NAS、社内サービス、パブリックドメインには、同じ名前解決経路が適さないことがあります。mihomoのnameserver-policyでは、ドメインごとに上流DNSを指定できます。一般的なnameserverとfallbackの組み合わせより優先されます。以下の設定は既存のdns配下に統合してください。例ではルーターのアドレスが実際に192.168.1.1であることを前提としています。

  nameserver-policy:
    '+.home.arpa':
      - 192.168.1.1
  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query

home.arpaは家庭内ネットワークのローカルドメインに使われます。ルーターに該当するレコードがなければ、ポリシーを設定しても名前解決の結果が自動で作られるわけではありません。fake-ipを使っていて、アプリが実際のLAN内アドレスを必要とする場合は、適切なfake-ipフィルターにもこのドメインを追加してください。

proxy-server-nameserverは、プロキシノードのサーバー自体のホスト名を解決する設定です。プロキシ経由でアクセスするすべてのWebサイトの名前解決を担当するものではありません。ノード用に直接到達できるDNSを用意すると、「上流DNSにはプロキシが必要で、プロキシへの接続にはDNSが必要」という循環を避けやすくなります。

DNS通信にもプロキシルールを適用する場合

respect-rules: trueを設定すると、上流DNSへの接続にもルーティングルールを適用できます。使用する場合はproxy-server-nameserverも設定し、最終的にどのルールが選ばれるか確認してください。名前解決の失敗をすべて解決する設定ではありません。ノードの名前解決、上流への接続、ルール選択が互いに依存していると、各アドレスが個別には正しくても全体が起動しないことがあります。

待ち受け・名前解決・取り込み・ルールの4段階で確認する

トラブルシューティングでは、元に戻せる設定を残し、一度に変更するのは1つの層だけにします。まずredir-hostで通常の名前解決を確認し、次にfake-ipをテストしてから、fallbackやDNSの出力ルールを追加します。すべての機能を同時に有効にするより、問題の切り分けが簡単です。

手順1:YAMLが読み込まれているか確認する

  • 同じ階層に置くdns:は1つだけにしてください。キーが重複するとエラーになる場合があるほか、先に書いた設定が後の設定で上書きされることもあります。
  • インデントにはスペースを使い、Tabは使わないでください。tun:とdns:は同じ階層のキーです。TUN全体をDNSの配下にインデントしないでください。
  • サブスクリプションの更新でローカルの変更が上書きされることがあります。長期的に使う設定はクライアントが対応する上書き機能に保存し、更新後に最終的な生成設定を確認してください。

手順2:ローカルの1053番ポートへ直接問い合わせる

digが使えるmacOSまたはLinux環境では、次の2つのコマンドを実行してUDPとTCPをそれぞれテストできます。ツールがインストールされていない場合は、OSのパッケージ管理機能で導入するか、DNSポートを指定できる別の問い合わせツールを使ってください。

dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp

redir-hostモードでは実際の名前解決結果が返ります。fake-ipモードでは、フィルター対象外のドメインに対して、通常は設定されたアドレスプール内のマッピングアドレスが返ります。2つのコマンドがどちらもタイムアウトする場合は、すぐにプロキシルールを変更せず、1053番ポートの待ち受け、設定の読み込み、ローカルファイアウォールを確認してください。SERVFAILが返る場合は、ログで初期の名前解決、上流への接続、証明書検証の問題を調べます。

手順3:OSからの問い合わせがコアに届いているか確認する

Windowsではipconfig /flushdnsを実行してOSのDNSキャッシュを消去します。systemd-resolvedを使うLinuxではresolvectl flush-cachesを実行してください。その後、テスト用ブラウザーをいったん終了してから再起動し、アプリ独自のキャッシュによる影響を減らします。1053番ポートへの直接問い合わせは成功するのに通常のアプリで接続できない場合は、TUNのルーティングとアプリ独自のDNS設定を重点的に確認してください。

手順4:DNSの成功と接続の成功を切り分ける

クライアントの接続ログで、宛先ドメイン、適用されたルール、出力先、エラーログを確認します。DNSからアドレスが返ったことが示すのは、名前解決が完了したということだけです。ノードに接続できない、ルールが誤った出力先を選ぶ、宛先ポートがブロックされているといった原因でも、Webページは開けません。fake-ipアドレスからドメインを復元できても、選択されたプロキシノードが使えるとは限りません。

システムプロキシ、ポート、TUN環境を引き続き確認する場合はトラブル対処を参照してください。サブスクリプションの初回取り込みやモード切り替えの手順は設定ガイドで確認できます。DNS設定は現在のネットワーク経路に合わせて行い、上流DNSをむやみに増やさないことが大切です。

Clashをダウンロード インストーラーとシステム要件