まず時系列を追い、次にエラーのキーワードを見る

一度に再現するリクエストは1つに絞り、関係する最初のエラーを探します。「Webページが開かない」原因は、通信の取り込み、ドメイン解決、ルール選択、プロキシ接続、接続先の応答などさまざまです。最後に記録されたタイムアウトは、それ以前の障害の結果にすぎないこともあります。timeoutだけを検索してノードを切り替えると、原因と違う箇所を変更しかねません。

Clashは、コアとクライアントのエコシステムを指す総称です。旧Clashコア、Clash Meta(現mihomo)、各種デスクトップUIでは、ログ形式や利用できる項目が異なる場合があります。UIの「ログ」ページには通常、コアの実行ログが表示されます。クライアント自体のサービス登録、権限、更新に関するエラーは、アプリのログに別途保存されることがあります。コアが起動していない場合、接続ログが空でも不思議ではありません。

  1. 障害が発生した現地時刻(例:14:32:10)と、接続先のドメイン名、使用したアプリを記録します。
  2. 関係のないWebページ、ダウンローダー、常時通信するアプリを閉じ、バックグラウンドの通信を減らします。
  3. ログページを開いて、画面に表示されている既存の記録を消します。通常、消えるのは表示内容だけで、ディスク上のログは削除されません。
  4. 対象ページを1回だけ再読み込みし、その前後約10秒のログを残します。
  5. 「コアに届いているか → 名前解決 → ルール → アウトバウンド → アプリの応答」の順に確認します。

ログレベル:通常はinfo、再現時はdebug

まずクライアントの「ログ」ページで既存の記録を確認します。詳しい情報が必要な場合は、クライアント設定で「ログレベル」またはLog Levelを探します。コアの実行レベルを直接変更できるUIもあれば、フィルターで一部の行を非表示にするだけで、コアの出力量は変わらないUIもあります。切り替えたらリクエストを再実行し、新しいデバッグ情報が出るか確認します。

レベル用途確認するポイント
silentトラブルシューティングに不向きログ出力が抑制されるため、接続の有無を判断できません
error重大なエラーのみを記録起動失敗などのエラーが中心で、通常の接続状況を把握する情報が不足しがちです
warning異常の確認接続失敗、タイムアウト、関連する警告
info通常の確認接続先、ルールの一致、選択されたポリシーなどの一般的な情報
debug短時間の再現確認詳細な名前解決や内部処理の情報。内容はバージョンによって異なります

設定変更は実際に適用される設定に反映する

設定でログレベルを指定できるコアでは、次のトップレベル項目を使用できます。dns:やtun:の下にインデントしないでください。クライアントでサブスクリプションを管理している場合は、クライアントが提供するオーバーライドまたはマージ設定の仕組みを使いましょう。ダウンロードしたサブスクリプションファイルを直接編集すると、次回の更新で上書きされることがあります。

log-level: debug

保存後、クライアントの手順に従って設定を再読み込みし、実行レベルが本当に変わったか確認します。調査が終わったらinfoに戻してください。デバッグログにはアクセス先のドメイン名、LAN内のアドレス、プロキシサーバーの情報が含まれることがあります。長期間保存するとログが増えるだけでなく、共有時に情報が漏れるリスクも高まります。

接続ログ:接続先・ルール・アウトバウンドを切り分ける

14:32:10 INF [TCP] 127.0.0.1:53124 --> example.com:443
match DomainSuffix(example.com) using DIRECT

この例からは、少なくとも4つの手がかりを読み取れます。通信はTCP、ローカル側の送信元ポートは53124、接続先はexample.com:443、ドメインサフィックスルールに一致してDIRECTが選択されています。送信元ポートは通常、アプリに一時的に割り当てられるポートです。Clashのリスニングポートではないため、この値を見てmixed-portを変更する必要はありません。

  • 接続先:ドメイン名またはIPアドレスが、直前に行った操作に対応するか確認します。Webページは画像、スクリプト、ログイン用APIにも接続するため、トップページのドメインだけが接続先とは限りません。
  • ルール:最後に表示されたポリシーグループ名だけでなく、一致したルールの種類と内容を確認します。
  • アウトバウンド:DIRECTは直接接続、REJECTはポリシーによる拒否です。プロキシグループの場合、その後に実際に選択されたプロキシが表示されることがあります。
  • 結果:接続ログがあるということは、コアがその接続を処理したことを示します。TLSハンドシェイクやWebページの読み込み、アプリのリクエストが成功したことまでは意味しません。

関連するログがまったくない場合

まずログがフィルターで非表示になっていないか確認し、次に通信の入口を調べます。システムプロキシが適用されるのは、その設定に従うアプリだけです。アプリ内にプロキシアドレスを個別設定している場合は、現在のリスニングアドレスとポート(例:127.0.0.1:7890)を確認してください。すべてのクライアントが7890を使うとは限りません。TUNモードでは、仮想NIC、ルーティングの取り込み、必要な権限が有効かも確認します。

ブラウザーが既存の接続を再利用すると、ページを再読み込みしても新しい接続ログが出ないことがあります。ブラウザーを完全に終了してから起動し直すか、新しいテストプロセスからリクエストすると、切り分けやすいログを取得できます。通常のプロキシテストではログが残るのに、対象のアプリだけ記録されない場合は、そのアプリの通信をどう取り込んでいるかを優先して確認します。

dial失敗:接続拒否・タイムアウト・経路なしを見分ける

dialは接続の確立を試みる処理を指します。エラーに表示されるアドレスは、最終的な接続先のほか、プロキシサーバーやDNS上流のこともあります。まずエラー全体を読み、「どこへの接続」かを特定してから、Webサイト、ノード、ローカルネットワークのどれを調べるか判断します。

dial tcp 127.0.0.1:7890: connect: connection refused
dial tcp 192.0.2.10:443: i/o timeout
dial tcp [2001:db8::10]:443: connect: network is unreachable

上記の192.0.2.10と2001:db8::10はドキュメント用の例示アドレスで、テスト可能なノードではありません。3種類のエラーはそれぞれ、「接続先による拒否」「制限時間内に完了しない」「利用可能なネットワーク経路がない」を示し、対処方法も異なります。

connection refused:アドレスと待ち受け状態を確認

拒否されたアドレスが127.0.0.1:7890なら、プロキシコアが起動していない、ポートが変更された、アプリが古い設定を使っているといった原因が考えられます。WindowsではPowerShell、macOSとLinuxではターミナルからTCPの待ち受け状態を確認できます。以下のコマンドは確認のみを行い、プロセスを終了しません。

# Windows PowerShell
Get-NetTCPConnection -LocalPort 7890 -State Listen

# macOS / Linux(lsofのインストールが必要)
lsof -nP -iTCP:7890 -sTCP:LISTEN

待ち受けがない場合は、クライアントに戻って実行状態を確認します。待ち受けがある場合は、プロセスが想定したコアか確認してください。接続先のプロキシサーバーが拒否する場合は、サブスクリプションのサーバーポートとサービスの状態を調べます。ローカルのmixed-portを変更しても、リモート側の拒否は解消しません。

i/o timeout:どの区間でタイムアウトしたか確認

タイムアウトしたからといって、ノードが恒久的に使えないとは限りません。パケットロス、ファイアウォールによる破棄、プロキシサーバーへの到達不能、接続先の応答遅延などが考えられます。接続先を変えず、同じポリシーグループ内の別のプロキシに切り替えて、エラーのアドレスと発生時刻を比べます。すべてのプロキシで失敗する場合は、ローカルネットワークとプロキシサーバーの名前解決を確認します。DNS、TUN、ルールを同時に変更するのは避けてください。

network is unreachable:ルーティングとアドレスファミリーを確認

エラーのアドレスが角括弧で囲まれている場合、通常はIPv6です。利用可能なIPv6ルートがない、VPNのルートと競合している、TUNによる通信取り込みに問題がある、といった原因で到達不能になることがあります。まずシステム自体から同じアドレスファミリーに接続できるか確認し、その後ルートの変更を調べます。IPv6のエラーが1件あるだけでは、リクエスト全体の失敗とは判断できません。後続でIPv4が再試行されている可能性もあるため、前後のログをあわせて確認してください。

DNS解決のタイムアウト:上流の障害と接続障害を見分ける

lookup example.com: i/o timeout
exchange failed: context deadline exceeded
lookup example.com: no such host

これらの例は、クエリのタイムアウト、DNS通信の期限超過、名前が見つからない問題などを示している可能性があります。実際のログには、上流アドレス、クエリタイプ、低レベルの接続エラーが記録されることもあります。no such hostはタイムアウトとは異なります。まずドメイン名の入力を確認し、次に応答元とフィルター設定を調べます。

  1. どこで名前解決しているか確認:システムDNS、アプリ独自のDoH、mihomo内蔵DNSのどれが使われているかを確認します。ブラウザーのセキュアDNS設定や、TUNによるDNS hijackによって、実際の経路が変わることがあります。
  2. 上流に到達できるか確認:従来型DNSでは通常UDP/TCP 53、DoTでは通常TCP 853、DoHでは通常HTTPS 443を使います。ポートに接続できても、トランスポート層で到達可能というだけで、DNSクエリの成功が保証されるわけではありません。
  3. 2種類のドメインを区別:接続先Webサイトのドメイン名と、プロキシサーバーのドメイン名は、どちらも名前解決が必要な場合があります。プロキシサーバーの名前解決に失敗すると、その後のプロキシ接続も失敗します。
  4. 依存関係を確認:プロキシ経由でしかアクセスできないDNS上流が、まだ名前解決されていないプロキシサーバーに依存していると、起動時の依存関係の問題が発生することがあります。

システムの名前解決結果は比較用

nslookup example.com

このコマンドでは、システム標準の名前解決経路による結果を確認できますが、mihomo内蔵DNSが正常だと証明できるわけではありません。TUNやDNS hijackが有効な場合、コアが処理を引き受けることもあります。同じ経路が使われているか判断するには、現在の設定とログに記録された上流情報を照らし合わせる必要があります。「システムで名前解決できるからClashのDNSも問題ない」とは言い切れません。

mihomoのproxy-server-nameserverはプロキシサーバーのドメイン名解決に、default-nameserverはDNSサーバー自体のドメイン名解決に関係します。具体的な動作と対応項目は、使用中のコアのドキュメントで確認してください。旧Clashの設定ではこれらの項目が使えない場合があるため、新しいコア向けの例をそのまま全コピーしないでください。respect-rulesなどを設定している場合は、DNSリクエストが自身に依存するプロキシ経路へルールで送られていないかも確認します。

ルール未一致:モード・順序・接続先の種類を確認

「ルール未一致」が明確なエラーとして記録されるとは限りません。よくあるのは、ログにフォールバックのMatchが表示されるケースや、想定と異なるアウトバウンドが選ばれるケースです。まずクライアントがルールモードになっているか確認します。グローバルモードとDIRECTモードでは、通常のルールモードのように接続ごとにアウトバウンドを選択しません。

# 設定例:サブスクリプション全体ではありません
rules:
  - DOMAIN-SUFFIX,example.com,DIRECT
  - MATCH,DIRECT

ルールは上から順に評価され、最初に一致したルールで結果が決まります。上の例では、具体的なドメインルールをフォールバックより前に置いています。MATCHを先頭に置くと、後続の通常ルールで接続を処理できません。この例では組み込みの宛先DIRECTのみを使っています。独自のポリシーグループ名に置き換える場合は、完全な設定のproxy-groupsでそのグループを定義してください。

  • ドメイン名が一致していない:DOMAINは指定したドメイン名に一致し、DOMAIN-SUFFIXはサフィックスと該当するサブドメインに一致します。Webページのリダイレクト後に使われるログイン用ドメインが、元のルール範囲に含まれていないことがあります。
  • IPアドレスしか取得できていない:アプリがIPアドレスへ直接接続している場合や、ドメイン名の情報が保持されていない場合、ドメインルールで判定できないことがあります。通信のスニッフィングでドメイン名を復元できるかは、プロトコル、設定、コアの対応状況によって異なり、すべての接続で復元できるとは限りません。
  • ルールセットが読み込まれていない:起動時や設定の再読み込み時に、プロバイダーのダウンロードや解析でエラーが出ていないか確認します。ルールセットの形式とbehaviorは一致させる必要があります。サブスクリプションをダウンロードできても、すべてのルールセットが読み込まれたとは限りません。
  • オーバーライドがマージされていない:現在どの設定が有効か確認します。別の設定ファイルを編集したり、マージ階層を間違えたりすると、ルールが実行中の設定に反映されないことがあります。
  • ポリシーグループ内の選択が異なる:想定したルールに一致していても、グループ内の手動選択、自動テストの結果、ネストしたグループの参照先が変わっていると、意図しないプロキシが使われることがあります。

確認時は対象ドメイン用の一時ルールを1つだけ追加し、関連する広範囲のルールより前に配置して、再読み込み後に新しい接続を作成します。ルール名とアウトバウンドが想定どおりであることを確認してから、実際のアクセス問題が解決したか判断してください。ルールの書き方やmixed-portについては設定の応用もご覧ください。

時系列で原因を特定:再現時に変更するのは1項目だけ

以下はトラブルシューティング記録の例であり、実際の速度測定結果ではありません。14:32:10にページを再読み込みし、同時刻に想定したポリシーグループに一致、14:32:15にプロキシサーバーへの接続タイムアウトが発生したとします。まずプロキシサーバーまでの経路を確認します。14:32:10の時点ですでにそのドメイン名の解決に失敗していた場合は、名前解決がより早い段階の障害です。

確認できたこと次に行うこと今は避けること
接続先のログがないログのフィルター、システムプロキシ、アプリ内プロキシ、TUNによる通信取り込みを確認ノードをまとめて切り替える
プロキシサーバーのドメイン名を解決できない名前解決の上流と起動時の依存関係を確認接続先Webサイトのルールだけを変更する
フォールバックまたは誤ったルールに一致ルールモード、ルールの順序、ドメイン名、実行中の設定を確認遅延の数値だけでルールが正しいと判断する
想定したアウトバウンドへの接続が拒否またはタイムアウト接続先アドレスとポートを確認し、別のプロキシで比較ネットワーク設定をすべて同時にリセットする
接続は確立したがアプリは失敗するTLS、HTTPステータス、アプリのログを確認すべての失敗をDNSの問題とみなす

プロキシを明示したリクエストで入口を確認

現在のmixed-portが実際に7890の場合は、次のリクエストでHTTPプロキシの入口を確認できます。Windowsではcurl.exeを使うと、PowerShell環境によって異なるコマンドエイリアスの影響を避けられます。macOSとLinuxでは通常curlを使います。

# Windows
curl.exe -I --proxy http://127.0.0.1:7890 --connect-timeout 5 --max-time 15 https://example.com/

# macOS / Linux
curl -I --proxy http://127.0.0.1:7890 --connect-timeout 5 --max-time 15 https://example.com/

ここでは5秒が接続確立までのタイムアウト、15秒がリクエスト全体のタイムアウトです。このcurlテストだけに適用され、コア全体のタイムアウト設定は変更しません。-Iはレスポンスヘッダーをリクエストします。接続先から403や405が返っても、ただちにプロキシ障害とは判断せず、接続が確立したか、どこからレスポンスが返ったかを確認してください。このテストではローカルのHTTPプロキシ入口を明示的に使うため、他のアプリでTUNが正常に機能しているかは単独では確認できません。

ログに接続処理の記録があるのに、ブラウザーで証明書やログインのエラーが出る場合は、ブラウザーの開発者ツールでネットワーク状態とアプリのエラーを確認します。Clashの実行ログは完全なHTTPキャプチャではないため、通常、アプリのAPIレスポンスをすべて確認することはできません。コアのログで通信経路を特定し、アプリのログでより上位の原因を補います。

トラブルシューティング用ログの共有:前後の情報を残し、機密項目を隠す

メンテナーに送る情報は、量よりも再現性が重要です。同じリクエスト前後約10秒のログ、現在のモード、OSのバージョン、クライアントのバージョン、コアのバージョンを残し、システムプロキシやTUNを有効にしているかも記載します。クライアントとmihomoコアのバージョンはそれぞれ記録し、一方で他方を代用しないでください。

  • 操作と想定結果を明記します。例:「対象ページを開くと指定したドメインルールに一致する想定だが、実際にはMATCHになった」。
  • エラーの全体、ルールの種類、アドレスファミリー、ポートを残します。情報が欠けると、リモート側とローカル側の障害を区別しにくくなります。
  • サブスクリプションURL、認証情報、コントロールAPIのキー、アクセストークンを削除します。
  • プロキシサーバー名、ユーザー名、LAN内アドレスは、一貫した仮名に置き換えます。同じ対象には常に同じ仮名を使ってください。
  • 直近の設定変更と、変更前後で同じリクエストを行った結果を添えます。赤いエラー行を1行だけ切り取るのは避けてください。