接続トラブルシューティング · Clash 技術ブログ

Mihomo:再読み込み後の Fake-IP 上書きと v1.19.33 の修正

Mihomo の設定を再読み込みすると、既存ドメインの Fake-IP が新しいドメインに使われる?実行中のコアと DNS の待ち受け先を確認し、同じアドレス範囲で前後を比較します。対応する正式な手段で v1.19.33 の修正を取り込み、マッピング、接続、元に戻す方法まで確かめます。

  • Mihomo
  • Fake-IP
  • v1.19.33
  • 設定の再読み込み
  • DNS マッピング
目次

設定を変えていないのに、再読み込み後にウェブ接続が意図しない先へ向かったり切れたりすると、まず DNS キャッシュを消したくなるかもしれません。Mihomo の Fake-IP モードでは、もう少し具体的に確認できます。既存ドメインのアドレスは再読み込み直後には保たれるのに、新しいドメインを問い合わせた後に変わっていないでしょうか。

再読み込み直後は同じなのに、なぜ後でアドレスが変わる?

公式リポジトリの #3281 には、v1.19.32 と alpha-9f053c4 を使った macOS での再現報告があります。同じ設定の再読み込みでマッピングは引き継がれますが、その後の新規ドメインへの割り当てがプールの先頭から始まり、既存のアドレスを使ってしまう場合があります。毎回の再読み込みですべての Fake-IP が直ちに変わる、という問題ではありません。

Fake-IP はコアがアプリに返す仮想アドレスで、コアはそのアドレスから元のドメインを特定する必要があります。ウェブ表示が止まった、または DNS の結果が二度の問い合わせで違ったというだけでは、この不具合と確定できません。報告にある AdGuard の遅延との実際の因果関係も、確認されていません。

似た現象を見分ける

観測した現象判断と次の確認
同じプロセスで同じ範囲の設定を再読み込みした後、新規の問い合わせが既存のマッピングを上書きするこの記事の手順でバージョンを確認し、前後の問い合わせを比較します。
プロセスの終了、キャッシュの消去、fake-ip-range の変更後にアドレスが変わる比較条件が変わっているため、それだけではこの不具合と判断できません。
実際の公開アドレスが返る、または問い合わせがコアの DNS に届いていない待ち受け先、問い合わせの種類、hosts、Fake-IP の除外ルールを先に確認します。

v1.19.33 では何が修正された?

v1.19.33 の正式リリース情報に #3283 の修正が記載されています。固定コミットの実装では、既存のマッピングをコピーした後、新旧のアドレスプールが同じ範囲の場合に限り、割り当て位置 offset と周回状態 cycle も引き継ぎます。これにより、引き継いだばかりのアドレスを先頭から再び割り当てることを防ぎます。

追加されたテストは、コピー後に新しいドメインへアドレスを割り当てても、既存ドメインのマッピングと逆引きの対応が保たれることを確認しています。アドレスが永久に変わらないという保証ではありません。プール容量による再利用、範囲の変更、プロセスの再起動などは、別に判断する必要があります。

profile.store-fake-ip は Fake-IP のマッピングを保存する設定です。有効にしただけで今回の割り当て状態の修正が取り込まれるわけではなく、この問題に有効と確認された回避策でもありません。比較のためにむやみに切り替えたり、キャッシュファイルを削除したりしないでください。

条件を変えずに実際の Fake-IP を確認するには?

まず、クライアントのコア情報か今回の起動ログで、実行中の Mihomo のバージョンを確認します。GUI クライアントとコアのバージョンは別です。別のフォルダーで mihomo -v を実行しても、クライアントがそのファイルを使っている証明にはなりません。

問い合わせは実際の dns.listen に送る必要があります。以下はローカルの 127.0.0.1:1053 を例にしています。確認した待ち受け先と一致する場合にだけ、そのまま使ってください。異なる場合はコマンドのサーバーアドレスとポートを置き換え、例に合わせて待ち受け設定を変更しないでください。

記録を残してから、設定を一度再読み込みする

  1. 元の設定と状態を残す

    現在の設定とクライアントデータを別の場所にバックアップし、コアのバージョン、アドレス範囲、除外ルール、永続化の設定を記録します。通信を中断してもよい時間を選び、比較中に設定が変わらないようサブスクリプションの自動更新を一時停止してください。

  2. 既存ドメインのアドレスを記録する

    下の A 問い合わせで、既存ドメイン example.com の Fake-IP を記録します。そのドメインに、このコアが実際に仮想アドレスを割り当てている必要があります。hosts や除外ルールが適用されて実際のアドレスが返る場合は、比較に適した別のドメインを選んでください。

  3. 既存の操作で同じ設定を再読み込みする

    クライアントやサービスが対応している設定の再読み込み操作を使い、プロセスと fake-ip-range を変えずに進めます。同時にアプリを終了したり、キャッシュを消したり、別の設定へ切り替えたりしないでください。操作によってコアの再読み込みが実際に行われたことも確認します。

  4. 新しいドメインを問い合わせてから、既存ドメインを再確認する

    そのコアがまだアドレスを割り当てていないドメインを問い合わせ、続けて既存ドメインを再度問い合わせます。アドレスと関連ログを比較してください。example.net は例です。以前に問い合わせていた場合は、自分で管理できる未問い合わせのドメインに置き換えます。

再読み込み前の問い合わせ例:待ち受け先とドメインを置き換えて使用
nslookup -type=A -port=1053 example.com 127.0.0.1

同じ設定の再読み込みが終わったら、下の二つの問い合わせを順番に実行します。ツールがなければ、システムにある同等の DNS 問い合わせツールを使ってください。ブラウザーのキャッシュ結果で代用したり、公開 DNS サーバーから返った実際のアドレスをコアのマッピングとみなしたりしないでください。

再読み込み後の問い合わせ例:待ち受け先とドメインを置き換え、新規・既存の順に実行
nslookup -type=A -port=1053 example.net 127.0.0.1
nslookup -type=A -port=1053 example.com 127.0.0.1

新しい問い合わせを一度送って上書きが起きなかっただけでは、古いコアに影響がないとは言えません。プール内の既存の割り当てや問い合わせの順番でも結果は変わります。毎回のドメイン、アドレス、時刻を残してください。発生させるために本番利用中のドメインへ大量の問い合わせを送ったり、容量による通常の再利用を同じ不具合と誤認したりしないでください。

修正を実際に取り込むには、どう更新する?

まず、アプリやサービスがコアだけの更新に対応しているか確認します。対応していれば、そこで認められた正式な入手先から修正を含むバージョンを選び、元のファイルと設定を保管してください。対応していなければ、メンテナーが修正の組み込みを明示した正式なクライアントパッケージを選ぶか、その公開を待ちます。アプリ内部のファイルを独断で上書きしないでください。

v1.19.33 の正式な記録でこの修正の収録を確認できます。ただし、クライアントを更新したばかりというだけで、コアも更新されたとは判断できません。更新後の起動ログやコア情報を確認し、対象のバージョンが実際に動作していることを確かめます。

更新後は新しいプロセスで比較し直す

  1. 元に戻せる状態を保管する

    別の場所に保存したバックアップ、元のバージョン、その設定を対応付け、復元方法を確認してから更新します。唯一のバックアップを上書きしたり、唯一のデータフォルダーに別バージョンから直接書き込んだりしないでください。

  2. 新しいプロセスの実際のバージョンを確かめる

    メンテナーの手順に従って更新後のコアを起動し、実行中のバージョン、実際に読み込まれた設定、DNS の待ち受け先を確認します。

  3. 新しいプロセス内で前後の問い合わせをやり直す

    更新時には通常プロセスが再起動するため、新旧プロセスで同じアドレスになる必要はありません。まず既存ドメインのマッピングを作り直し、その新しいプロセスを維持したまま同じ設定を再読み込みして、新しいドメイン、既存ドメインの順に問い合わせます。

一度の成功で判断せず、何を確認すればよい?

マッピングと実際の接続を両方確認する

  • GUI クライアントだけでなく、実際に動作するコアのバージョンを記録した。
  • 前後とも同じ dns.listen に A 問い合わせを送り、対象ドメインは hosts や Fake-IP の除外ルールに該当していない。
  • 同じ新しいプロセスとアドレス範囲で再読み込み前後を比較し、キャッシュ消去、プロセス終了、途中の設定変更を行っていない。
  • 適量の新規ドメイン問い合わせ後も、引き継いだ既存ドメインのマッピングが早期に上書きされていない。そのドメインを使うウェブサイトやアプリへの新しいリクエストも確かめた。
  • 元の自動更新設定へ戻してから再度観察し、失敗した場合はバージョン、設定の差分、機密情報を隠した問い合わせ記録を保管する。

マッピングが保たれるのに接続できない場合は、実際のルーティング、上流の名前解決、アプリの接続記録を引き続き調べます。DNS や AdGuard の問題がすべて今回の修正で解決するとは考えないでください。この記事は公式リポジトリの報告、修正、回帰テストに基づくもので、あなたのクライアント環境での実機再現を代行したものではありません。

更新後も問題がある場合、どう戻して記録を残す?

新バージョンで別の互換性問題が生じた場合は、元々対応していた更新手段を使って保管済みのコアまたはクライアントへ戻し、そのバージョンに対応する独立したバックアップを復元します。問題のある操作を止めてから切り替え、二つのバージョンが同じデータフォルダーへ同時に書き込まないようにしてください。

旧バージョンへ戻すと今回の不具合が再び現れる可能性があり、最終的な修正にはなりません。設定と元の自動更新設定を復元したら、実行中のバージョン、DNS の待ち受け先、実際の接続を確認し直します。原因が分からない違いを隠すために、唯一のキャッシュを消したり、サブスクリプションを削除したりしないでください。

メンテナーへは、コアの完全なバージョン、OS、再読み込みの方法、実際のアドレス範囲、永続化の設定、順序の分かる前後の問い合わせ結果を伝えます。サブスクリプションの認証情報、secret、非公開ドメイン、個人情報は取り除いてください。元の issue の状態だけでは、利用中のパッケージに修正が含まれるかは判断できません。

参考資料