まずログがどの処理で出たものか確認する
Clash、Clash Meta、mihomoのログはよく似ていますが、同じ画面にクライアントログ、コアのログ、設定更新の記録が混在することがあります。問題を切り分ける前に、エラーを出したのがどのコンポーネントか確認しましょう。クライアントはサブスクリプションの取得、設定の保存、コアの起動を担当し、コアはDNS、ルール判定、プロキシ接続、TUNトラフィックの処理を担います。サブスクリプションの取得に失敗している場合、プロキシルールを変更しても解決しません。コア自体が起動していなければ、ノードの遅延テストも有効な結果になりません。
3種類の記録で確認するポイント
- クライアントの記録:サブスクリプションURLへのリクエスト、設定ファイルの保存、コアプロセスの起動、システムプロキシの切り替えなどが含まれます。HTTP 401、403、404や設定の書き込み失敗が出たら、まずサブスクリプションとファイル権限を確認します。
- コア起動時の記録:設定の読み込み、DNSモジュール、待受ポート、ルールセット、TUN初期化の状態が表示されます。ここでのエラーは、コアの停止や特定機能の利用不能につながることがあります。
- 接続記録:TCP、UDP、送信元アドレス、対象ドメイン、適用されたルール、最終的なポリシーグループが含まれます。ウェブページが開けない、アプリがプロキシを経由しない、ノードがタイムアウトするといった場合は、主にこの記録を確認します。
クライアントによってメニュー名は多少異なります。通常は「設定」→「ログ」、または「コア」→「ログ」からリアルタイムの記録を開けます。デスクトップクライアントによっては「ホーム」→「ログ」に入口があります。mihomoのGUIクライアントでは、「設定」→「パラメータ設定」からログレベルを変更できる場合もあります。問題を再現するときはログ画面を開いたまま古い記録を消去し、失敗する操作を1回だけ実行してください。こうして得たログが最も読みやすいサンプルです。
レベル、接続方向、ルール結果を読み取る
一般的なログレベルには debug、info、warning、errorがあります。infoは正常な接続も記録するため、表示されても障害とは限りません。warningは操作の失敗、フォールバック、一時的な異常を示しますが、通常はコアが動作し続けています。errorは優先して確認すべきレベルです。ルールを調べるときだけ一時的に debugを使い、終わったら infoに戻して、DNSや接続の詳細が大量に記録され続けるのを防ぎます。
[INFO] [TCP] 127.0.0.1:53142 --> example.com:443
match DomainSuffix(example.com) using Proxy[HK-01]
[WARNING] [TCP] dial Proxy (match DomainSuffix/example.com)
127.0.0.1:53142 --> example.com:443 error: i/o timeout
1行目は、ローカルプロセスが一時ポート 53142からTCP接続を開始し、接続先が example.com:443であることを示しています。続いて DOMAIN-SUFFIXルールに一致し、Proxyというポリシーグループに渡されています。角括弧内の HK-01は、そのグループが実際に選択したノードです。2つ目の部分は、接続がプロキシ経路に入ったものの、規定時間内に完了しなかったことを示します。したがって、まず「ルールに一致していない」可能性を除外し、ノード、上流ネットワーク、対象サイトへ注意を向けられます。
ログはこの順番で分解する
- プロトコルがTCPかUDPかを確認します。HTTPSのウェブ通信は多くがTCP 443を使いますが、QUIC経由でUDP 443を使う場合もあります。
- 送信元アドレスを確認します。
127.0.0.1は通常、システムプロキシまたはローカルアプリを示します。TUNが通信を引き受けている場合は、仮想ネットワークアダプターのアドレスが表示されることがあります。 - 接続先がドメインかIPアドレスかを確認します。IPアドレスだけの場合、一部のドメインルールは判定に利用できません。
matchの後に表示されるルールの種類と内容を確認します。usingの後に表示されるポリシーグループと実際のノードを確認し、接続が最終的にどこへ向かったかを判断します。- 最後に
errorの内容を読み、接続タイムアウト、拒否、名前解決失敗、認証失敗のどれかを区別します。
dial tcp timeout:規定時間内に接続を確立できない
dial tcpは、コアがTCP接続を確立中であることを示します。後続の i/o timeout、connect: operation timed out、context deadline exceededはいずれも「待機時間が上限を超えた」ことを示しますが、タイムアウトした場所は同じとは限りません。プロキシサーバーへの接続に失敗した場合もあれば、プロキシサーバーから対象サイトへの接続に失敗した場合もあります。エラーの前にあるノード名、対象アドレス、連続して失敗している範囲を合わせて判断します。
1つのノードだけタイムアウトする場合
同じポリシーグループで HK-01が連続してタイムアウトする一方、SG-02では同じサイトを正常に開けるなら、問題はノードまたはノードの経路に絞られます。まずクライアントで遅延テストを1回実行し、その後に実際のウェブページで確認します。遅延テストのURLが200を返しても、テスト経路が到達可能だと分かるだけで、すべてのサイトにアクセスできるとは限りません。5秒を超えるタイムアウトが3回連続する場合は、800ミリ秒のタイムアウトが1回だけ起きた場合より、接続が不安定である可能性が高いと判断できます。
すべてのノードが同時にタイムアウトする場合
- 現在のネットワークから、サブスクリプションサイト以外の一般的なウェブページへ直接アクセスできるか確認し、ローカルのネットワーク断を除外します。
- システム時刻が正確か確認します。数分のずれでも、TLSハンドシェイクやタイムスタンプ付き認証プロトコルに影響することがあります。
- ノードサーバーのアドレスを名前解決できるか確認します。ログに
lookupやDNS request failedも同時に出ているなら、先にDNSを処理します。 - 経路が互いに上書きされないよう、システム上で動作している別のVPN、プロキシソフト、ネットワークフィルタリングツールを一時的に終了します。
- TUNを有効にしている場合は、まずシステムプロキシに切り替えて再テストします。システムプロキシでは使えるのにTUNでは使えない場合、仮想ネットワークアダプター、ルーティング、権限を重点的に確認します。
[WARNING] dial tcp 203.0.113.20:443: i/o timeout
[WARNING] dial tcp: lookup node.example.net: i/o timeout
この2行は同じ方法で処理してはいけません。1行目はすでにサーバーIPを取得しており、TCP接続の段階でタイムアウトしています。2行目はまだドメイン解決の段階にあります。前者はサーバーのポートとネットワーク経路を、後者はDNSサーバー、DNS経路、ローカルネットワークを確認します。
connection refused:接続先が明確に接続を拒否する
connection refusedはタイムアウトとは異なります。タイムアウトは有効な応答がなかなか返らない状態ですが、接続拒否は対象ホストが短時間で拒否結果を返したことを示します。よくある原因は、ポートでサービスが待ち受けていない、サービスが停止している、ポート番号が間違っている、またはローカルアプリが起動していないClashの待受ポートへ接続していることです。
dial tcp 127.0.0.1:7890: connect: connection refused
dial tcp 198.51.100.8:8443: connect: connection refused
1行目の接続先は 127.0.0.1:7890です。これはアプリがローカルのプロキシポートへ接続しようとしたものの、そのポートを待ち受けるプロセスがないことを示します。クライアントのコアが動作しているか確認し、アプリのプロキシアドレスがClashの設定と一致しているか確認してください。一般的な混合プロキシポートは 7890ですが、ユーザー設定では 7897、7899などに変更されている場合もあります。既定値だけで設定しないようにしましょう。
2行目は、リモートアドレスが接続を拒否したことを示します。ノードサーバーに対応する場合は、ノードのポート、プロトコル種別、サブスクリプションの更新時期を確認します。VMessノードのポートをTrojan設定に誤って入力したり、サーバーのポート変更後も古いサブスクリプションを使い続けたりすると、すぐに拒否されることがあります。この場合、ルールモードを何度切り替えても効果はありません。エラーはプロキシサーバーへの接続段階で発生しているためです。
DNS名前解決に失敗する場合:まずどこがリクエストを処理しているか確認する
DNSの問題は、ウェブページにサーバーが見つからないと表示されたり、ログに lookup、no such host、all DNS requests failed、could not resolve、上流DNSのタイムアウトなどが出たりする形で現れます。切り分けの要点は、DNSリクエストがOS、ClashのDNSモジュール、ブラウザー独自のセキュアDNSのどれを経由しているかを確認することです。3つが並行して動作していると、1つだけ変更しても実際のリクエストに影響しない場合があります。
コアのDNS設定を確認する
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
nameserver:
- 223.5.5.5
fallback:
- tls://1.1.1.1:853
この設定では、コアが 1053ポートでDNSを待ち受けます。リクエストが自動的にシステムの53番ポートへ現れるわけではありません。GUIクライアントは通常、TUNまたはDNSの引き受けを有効にしたときに必要なルートを追加します。設定をコピーしただけでシステムDNSをコアへ向けていない場合、アプリは以前のリゾルバーを使い続けることがあります。逆に、ポートが別のプログラムに占有されていると、起動ログに bind: address already in useが表示されます。
症状に応じて確認箇所を分ける
- すべてのドメインで失敗するが、IPアドレスへ直接アクセスすると応答がある:DNSの待受、上流DNS、ファイアウォールを優先して確認します。
- 中国国内のドメインは正常だが、特定のドメインだけ失敗する:nameserver-policy、fallback、ルールセットによってDNSリクエストが到達不能な経路へ送られていないか確認します。
- ブラウザーだけ失敗し、ほかのアプリは正常:ブラウザーのセキュアDNS設定とプロキシ拡張機能を確認し、システムDNSを迂回していないか確かめます。
- Fake-IPアドレスは表示されるが接続に失敗する:Fake-IPが予約アドレスを返すのは正常な処理です。予約アドレスを実際のサーバーと誤認せず、その後のドメイン復元、ルール一致、プロキシ接続を確認します。
- TUNを有効にしたときだけ失敗する:DNSハイジャック設定、デフォルトルート、仮想ネットワークアダプターの権限を確認し、DNSリクエストがコアへループしていないか確認します。
DNSを変更した後は、古いキャッシュを削除してからテストします。Windowsではネットワークへ再接続するか、ターミナルで ipconfig /flushdnsを実行します。macOSではネットワークインターフェースをいったん無効にしてから再び有効にします。ブラウザーが独自のDNSキャッシュや接続キャッシュを保持していることもあるため、ブラウザーを完全に終了してから再テストすると確実です。
ルールに一致しない:ログにerrorが出ないこともある
ルール設定の誤りでは、赤いエラーが表示されないことがよくあります。接続自体は成功していても、DIRECT、誤ったノード、最後の MATCHへ振り分けられると、ユーザーには「ルールが効かない」と感じられます。Clashとmihomoは設定の上から順番に確認し、最初に一致した時点で停止します。範囲の広いルールを前に置くと、後ろにある具体的なルールが隠れてしまいます。
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- DOMAIN,api.example.com,Proxy
- MATCH,Proxy
api.example.comへアクセスしたとき、1つ目の DOMAIN-SUFFIXがすでに一致しているため、2つ目の完全一致ドメインルールは実行されません。APIをプロキシ経由にしたい場合は、DOMAIN,api.example.com,Proxyをより上に移動します。ログに match DomainSuffix(example.com) using DIRECTと表示されるなら、ルールシステムは正常に動作しています。問題はルールの順序であり、コアが設定を無視しているわけではありません。
ログにIPアドレスしか表示されない場合の確認方法
対象が 142.250.0.1:443のようなIPアドレスで表示される場合、DOMAINや DOMAIN-SUFFIXルールで利用できるドメイン名がない可能性があります。アプリがIPアドレスへ直接接続している、DNSマッピングが接続と紐付いていない、通信がコアを完全には経由していない、といった原因が考えられます。IP-CIDR、GEOIP、最後の MATCHのどれに一致したか確認します。no-resolveを使うIPルールは、一致判定のために追加のドメイン解決を行いません。これは「このルールをスキップする」という意味ではありません。
ルールセットの読み込みに失敗する場合
リモートルールセットをダウンロードできないと、ログにHTTP 404、context deadline exceeded、provider update failedなどが表示されることがあります。まずルールセットのURLと更新時刻を確認し、次にダウンロードリクエストがどのポリシーを使っているか確認します。初回読み込みに失敗すると、そのルールセットに依存するルールが利用できなくなる場合があります。キャッシュが残っていれば、コアが古いバージョンを使い続けることもあります。失敗が起動時に発生したのか、定期更新時に発生したのかも記録してください。
サブスクリプション、設定、コア起動のエラー
ログにTCPやUDPの接続記録がまったくない場合は、まずコアが設定を正常に読み込めたか確認します。YAMLのインデントエラー、存在しないノードを参照するポリシーグループ、ポートの競合、設定項目の非互換などにより、通信を引き受ける前にコアが終了することがあります。
HTTPステータスコードから分かるサブスクリプションの問題
| ログの状態 | 主な意味 | 優先して確認する項目 |
|---|---|---|
| 401 Unauthorized | 有効な認証情報がリクエストに含まれていない | サブスクリプションのトークンが完全か、リンクが途中で切れていないか |
| 403 Forbidden | サーバーはリクエストを受信したが、コンテンツの提供を拒否した | サブスクリプションの状態、アクセス制限、リクエスト元 |
| 404 Not Found | サブスクリプションのパスが存在しない | リンクの有効期限が切れていないか、パスを誤ってコピーしていないか |
| 429 Too Many Requests | 短時間にリクエストが集中している | 自動更新を一時停止し、制限が解除されるまで待つ |
| 5xx | サブスクリプションサービス側の一時的な障害 | しばらく待って再試行し、現在使える設定は保持する |
YAMLと参照に関するエラー
yaml: line 42: did not find expected key
proxy group Proxy: proxy HK-01 not found
listen tcp 127.0.0.1:7890: bind: address already in use
did not find expected keyは通常、インデント、コロンの欠落、閉じられていない引用符に関係しています。YAMLではスペースでインデントし、タブを混在させないでください。proxy not foundは、ポリシーグループが存在しないノードまたは子ポリシーグループを参照していることを示します。名前のスペース、大文字・小文字、サブスクリプション更新後にノード名が変更されていないかを確認します。address already in useは、待受アドレスまたはポートがすでに使用されていることを示します。古いコアプロセスを終了するか、「設定」→「パラメータ設定」でmixed-portを変更してから再起動します。permission deniedがTUNの初期化段階で表示される場合、通常は仮想ネットワークアダプターの権限またはシステムサービスの状態に関係しています。システムプロキシが正常に使えるなら、まずシステムプロキシモードを維持し、TUNは別途対応します。
Clash Premium、Clash Meta、mihomoでは、対応する設定項目が完全に同じではありません。新しいmihomoで生成した設定を古いコアに読み込ませると、unknown fieldや解析失敗が発生することがあります。まずクライアントの「概要」または「コア」画面で実際のコア名とバージョンを確認し、そのコアが対応する項目と照合してください。クライアントの外側のバージョンだけを見て判断しないようにしましょう。
再現性のあるログ調査フロー
- 症状を記録:失敗した時刻、アプリ名、対象ドメイン、システムプロキシまたはTUNの有効・無効を記録します。
- コアの状態を確認:コアが動作しているか、mixed-portが待ち受けているか、起動ログに設定エラーがないか確認します。
- ログを消去:レベルをinfoに設定し、過去の記録を削除して、古いエラーに判断を惑わされないようにします。
- 1回だけ再現:失敗するページを1つ開く、サブスクリプションを1回更新する、またはノード接続を1回実行するなど、複数のアプリを同時に操作しないようにします。
- 対象を先に探す:ドメイン、IPアドレス、サブスクリプションのアドレスを検索し、その前後10~20行のコンテキストを確認します。
- 処理段階を分ける:サブスクリプションのHTTPエラーはサブスクリプション段階、YAMLとポートのエラーは起動段階、lookupはDNS、matchはルール、dialは接続の問題として分類します。
- 一度に1つだけ変えて試す:一度に変更するのは、ノード1つ、DNS上流1つ、または接続方式1つだけにします。変更するたびにログを再度消去します。
- ログレベルを戻す:問題が解決したらdebugからinfoに戻し、不要な記録を減らします。
例えば、あるサイトがTUNモードでは8秒後に失敗するのに、システムプロキシモードでは1.2秒で開くとします。ログではどちらも同じノードに一致しているものの、システムプロキシモードではTCP接続が完了し、TUNモードでは対象に対応する記録がありません。この場合、ノードとルールはほぼ除外できるため、TUNのルーティング、アプリが仮想ネットワークアダプターを経由しているか、DNSハイジャック、システム権限を重点的に確認します。このような比較テストは、10個のノードを次々に変更するより効果的です。
他人にログを共有する前に、時刻、エラーの種類、対象ポート、ルールの種類、ポリシーグループ名は残しつつ、サブスクリプションのトークン、認証項目、完全なノードアドレス、ローカルのユーザー名を削除または置き換えます。最後のerror行だけを切り取らないでください。少なくともエラーの前後にある起動情報または接続コンテキストを残さないと、タイムアウトがDNS、ノード、対象サイトのどこで起きたのか判断しにくくなります。