Clashのシステムプロキシが効かないときの対処法:ブラウザーは使えるのにターミナルで失敗する場合
システムプロキシ、ブラウザー独自設定、ターミナルの環境変数、ローカル待受ポートを順番に確認します。
まずブラウザーのプロキシ経路を確認する
「ブラウザーではアクセスできるのに、ターミナルでは失敗する」からといって、Clashのシステムプロキシが無効だとは限りません。ブラウザーとコマンドラインツールでは、まったく異なるネットワーク経路を使うことがあります。ブラウザーはOSのプロキシ設定を読み取る場合もあれば、拡張機能、独自のプロキシ設定、内蔵のセキュアDNSを使う場合もあります。一方、ターミナルのプログラムはシステムプロキシを無視して、接続先へ直接アクセスすることがあります。
最初に行うべきことは、ノードを何度も切り替えることではなく、ブラウザーの通信がどこからClashに入っているかを確認することです。ブラウザーのプロキシ拡張機能と独自のプロキシ設定を一時的に無効にし、Clashのシステムプロキシだけを有効にして、テストページへ再度アクセスします。拡張機能を無効にした途端にブラウザーも接続できなくなるなら、以前の通信はシステムプロキシではなく拡張機能経由だった可能性が高いでしょう。
次にClashクライアントの接続履歴を確認します。これまで開いたことのないドメインへアクセスし、接続一覧に該当ドメイン、接続先、適用されたルール、ポリシーグループが表示されるかを確認してください。ブラウザーではアクセスに成功しているのにClashに新しい接続が表示されない場合、そのリクエストは現在動作しているClashのインスタンスに入っていません。よくある原因は、ブラウザーが別のプロキシを使っている、独立したVPNが有効になっている、複数のプロキシクライアントが同時に動作している、またはブラウザーが終了していない古い接続を再利用していることです。
ブラウザーとターミナルで、同じドメインとプロトコルをテストしているかも確認しましょう。通常のウェブページ、HTTPS APIへのリクエスト、Gitリポジトリへの接続、パッケージのダウンロードでは、異なるドメイン、ポート、ルールが使われることがあります。あるウェブページにアクセスできても、Git、パッケージマネージャー、リモートAPIの接続先まで同じルールで正しく処理されるとは限りません。
Clashのローカル待受ポートとプロトコルを確認する
ターミナルからClash経由で通信するには、まず待受中のローカルプロキシポートへ接続できなければなりません。クライアントによって初期値は異なり、設定をインポートした際に上書きされることもあります。そのため、ポートが必ず7890だと決めつけないでください。クライアントのポート設定、実行ログ、または現在有効な設定から実際の値を確認します。
一般的な設定には、HTTPポート、SOCKSポート、mixed-portがあります。mixed-portは同じポートでHTTPとSOCKSのプロキシ接続を受け付けられるため、ブラウザー、curl、その他のツールを同時に使う場合に便利です。以下は構造の例にすぎないため、実際の確認ではクライアントに表示される有効な設定を基準にしてください。
mixed-port: 7890
socks-port: 7891
allow-lan: false
mode: rule
設定にポート番号が記載されていても、プロセスが実際に待ち受けているとは限りません。別のプログラムがポートを使用している場合や、設定の読み込みに失敗してClashのコアが起動していない場合があります。Windowsでは netstat またはPowerShell、macOSとLinuxでは lsof または ss を使って待受状態を確認できます。
netstat -ano | findstr 7890
lsof -nP -iTCP:7890 -sTCP:LISTEN
ss -lntp | grep 7890
待受結果が何も表示されない場合は、ターミナルの設定を変更し続けるのではなく、まずClashクライアントに戻ってコアの動作状態とログを確認します。ポートが別のプロセスに使用されている場合は、競合しているプログラムを終了するかClashのポートを変更し、ターミナル側のプロキシアドレスも合わせて更新してください。
待受を確認できたら、curlでプロキシを明示的に指定します。この方法ならシステムプロキシと環境変数を経由せず、「ターミナルからローカルポートまで」と「Clashから接続先まで」の2つの経路が機能しているかをすばやく確認できます。
curl -I -x http://127.0.0.1:7890 https://example.com
curl -I --proxy socks5h://127.0.0.1:7891 https://example.com
1つ目のコマンドはHTTPプロキシ、2つ目はSOCKS5プロキシとしてテストします。socks5h の h は、接続先ドメインの名前解決をプロキシ側で行うことを示します。ローカルDNSの問題とプロキシ接続の問題を切り分けるのに役立ちます。プロキシを明示すると成功する場合、Clashのポートとノードはおおむね正常で、問題はシステムプロキシの読み取り方か、ターミナルの環境変数にあることが多いでしょう。
「connection refused」と表示された場合は、まずポートとコアの状態を確認します。長時間タイムアウトする場合は、ファイアウォール、ノードへの接続性、ルールを確認してください。プロキシ認証エラーが返る場合は、使用しているクライアントがローカルポートに認証情報を設定しているか確認します。ログ上でリクエストがClashに入り、DIRECTルールで処理されている場合は、ルールの順序と最終的に選択されたポリシーグループも確認が必要です。
ターミナルプログラムにプロキシ環境変数を設定する
多くのコマンドラインツールはデスクトップのシステムプロキシ設定を自動的に読み取らず、http_proxy、https_proxy、all_proxy などの環境変数を参照します。変数名で大文字・小文字の扱いが異なるほか、対応範囲もプログラムによって異なります。互換性の問題を減らすには、小文字と大文字の両方を設定する方法がありますが、同じセッション内に競合するアドレスを残さないようにしてください。
macOSとLinuxで一時的に設定する
BashやZshなどのShellでは、現在のターミナルセッションだけにプロキシ変数をエクスポートできます。
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
curl -I https://example.com
https_proxy はHTTPS接続時に使うプロキシを示す変数であり、値を必ず https:// で始める必要があるという意味ではありません。ローカルのClashポートは通常HTTPプロキシを提供するため、アドレスは http://127.0.0.1:7890 と記述することが一般的です。SOCKSを統一して使う場合は、次のように設定します。
export all_proxy=socks5h://127.0.0.1:7891
export ALL_PROXY=socks5h://127.0.0.1:7891
WindowsのCMDとPowerShellで一時的に設定する
CMDでは set を使って、現在のウィンドウに環境変数を設定します。
set http_proxy=http://127.0.0.1:7890
set https_proxy=http://127.0.0.1:7890
curl.exe -I https://example.com
PowerShellでは、現在のプロセスの Env スコープに書き込みます。
$Env:http_proxy = "http://127.0.0.1:7890"
$Env:https_proxy = "http://127.0.0.1:7890"
curl.exe -I https://example.com
PowerShellでは、テストに curl.exe を明示的に使用してください。旧バージョンの環境ではコマンドエイリアスによって結果が分かりにくくなることがあります。Invoke-WebRequest では、プロキシを直接指定することもできます。
Invoke-WebRequest -Uri "https://example.com" -Proxy "http://127.0.0.1:7890"
残存設定と除外リストを確認する
変数を変更する前に現在の値を出力し、古いポート、無効なホスト名、別のプロキシソフトのアドレスが残っていないか確認します。macOSとLinuxでは env | grep -i proxy、PowerShellでは Get-ChildItem Env: | Where-Object Name -Match 'proxy' を実行できます。
no_proxy または NO_PROXY は、プロキシを経由しないアドレスを指定するための変数です。接続先ドメインが意図せず除外リストに入っていると、プログラムは直接接続します。一般的に localhost、127.0.0.1、LAN内のサービスは除外して問題ありませんが、広すぎるサフィックス指定では外部ドメインまで除外される可能性があります。
システムプロキシ、ツール設定、プラットフォームの違いに対処する
システムプロキシは、すべてのプログラムが従う単一の転送レイヤーではありません。OSが提供するプロキシ関連パラメータの集合に近く、設定を読み取るか、いつ読み取るか、どのプロトコルに対応するかはアプリケーションごとに決まります。ブラウザーは通常システム設定を読み取りますが、Git、npm、Pythonのパッケージマネージャー、コンテナプロセス、一部のJavaプログラムは独自の設定を使うことがよくあります。
WindowsのシステムプロキシとWinHTTP
Windowsのデスクトップアプリはユーザー単位のシステムプロキシを読み取ることが多い一方、一部のシステムコンポーネントやサービスはWinHTTPの設定を使います。両者は完全に同じではありません。そのため、ブラウザーは使えるのにサービスアカウントで実行されるツールが失敗するケースは珍しくありません。次のコマンドでWinHTTPの現在の状態を確認できます。
netsh winhttp show proxy
用途を確認せずにユーザープロキシをWinHTTPへ直接インポートしないでください。依存するシステムコンポーネントに影響する可能性があります。まずは対象のコマンドからClashへ明示的に接続して問題の範囲を確認し、そのうえでツール独自の設定を使うか、システムレベルの設定を調整するか判断するのが安全です。
Gitとパッケージマネージャーの独自プロキシ
GitではHTTPとHTTPSのプロキシを個別に保存できます。環境変数が正しいのにGitだけ失敗する場合は、古い設定が残っていないか確認してください。
git config --global --get http.proxy
git config --global --get https.proxy
現在のClashのHTTPポートを使う場合は、次のように設定します。
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
Gitの独自プロキシが不要になった場合は、値を空文字列にするのではなく、該当する設定項目を削除してください。npm、pnpm、pip、Maven、Gradleにもそれぞれ異なる設定元があります。確認時にはツールの設定ファイル、環境変数、IDEの設定を同時に調べ、同じリクエストが複数の設定で上書きされないようにします。
プロキシプロトコルとポートを一致させる
SOCKSポートをHTTPプロキシとして使ったり、HTTPポートをSOCKSアドレスとして指定したりすると、ハンドシェイクに失敗します。Clashクライアントでポートの種類を確認し、ツールには対応するURLスキームを指定してください。HTTPプロキシは通常 http://127.0.0.1:ポート、SOCKS5は socks5:// または socks5h:// と記述します。
127.0.0.1 と localhost の名前解決の違いにも注意してください。環境によっては localhost がIPv6アドレス ::1 に優先解決されますが、ClashがIPv4だけで待ち受けていることがあります。切り分けの段階では 127.0.0.1 を直接指定すると、この要因を減らせます。
TUNモード、DNS、分離環境を確認する
TUNモードは仮想ネットワークインターフェースを通じて、より多くの通信を引き受けます。通常、各ターミナルプログラムがシステムプロキシに個別対応している必要はありません。ただし、TUNを有効にすればすべてのコマンドが自動的に成功するわけではありません。仮想インターフェースの作成権限、ルートの追加、DNSの引き受け、プロセスのバイパスルール、他のVPNソフトなどが結果に影響します。
通常のシステムプロキシではcurlでポートを明示すると動作するのに、TUNを有効にすると直接のリクエストが失敗する場合は、Clashのログに該当接続が表示されるか確認します。記録がまったくない場合は、ルートがTUNに入っていない可能性があります。接続はあるものの名前解決に失敗する場合はDNS設定を確認し、接続が誤ったポリシーグループへ振り分けられている場合は、ルールの適用結果を見直してください。
Clash Meta(Mihomoとも呼ばれます)は、より高度なTUN、DNS、ルール機能に対応しています。ただし、グラフィカルクライアントで関連項目が表示されるか、どの実行権限を使うかはクライアントの実装によって異なります。YAMLを変更する前に、起動時にクライアントが設定を再生成するか確認し、手動変更が上書きされないようにしてください。
WSL、Docker、仮想マシン、リモート開発コンテナでは特別な対応が必要です。これらの環境から見た 127.0.0.1 は通常、自身を指し、ホストマシンを指しません。ホスト側のClashが正常に待ち受けていても、コンテナ内から 127.0.0.1:7890 へアクセスすると拒否されることがあります。この場合は仮想ネットワーク上のホストアドレスを使い、ClashがLAN接続を許可していること、待受アドレスが対象インターフェースをカバーしていることを確認し、ホストのファイアウォールも確認してください。
SSHでリモートサーバーへログインした後、ターミナルのコマンドはリモートホスト上で実行されます。リモートホストの 127.0.0.1 もローカルPCを指しません。リモートのコマンドから手元のClashを使うには、明示的なSSHポートフォワーディングを構成するか、リモート環境から到達できるプロキシを設定する必要があります。手元の環境変数をそのままコピーしても動作しません。
手順に沿ってClashのターミナルプロキシを特定する
効果的な切り分けは、システムプロキシ、ルール、DNS、ノードを同時に変更するのではなく、層ごとに検証することです。各手順で確認する項目を1つに絞り、テスト結果を記録します。
- コアの動作を確認:Clashクライアントの状態と起動ログを確認し、現在の設定が正常に読み込まれていることを確認します。
- ポートの待受を確認:有効な設定からHTTP、SOCKS、mixed-portを確認し、システムコマンドで該当ポートが待ち受け状態になっていることを確認します。
- プロキシを明示的に指定:
curl -xまたは--proxyを使ってローカルポートへ直接接続し、システムプロキシの読み取り問題を切り分けます。 - 接続履歴を確認:リクエストがClashに入り、適用されたルール、ポリシーグループ、ノード、エラー情報を確認します。
- ターミナルの変数を確認:proxy関連の変数をすべて出力し、古いアドレスや競合する値を削除して、現在のセッションに正しいポートを設定します。
- ツール独自の設定を確認:Git、パッケージマネージャー、IDE、ランタイムに別のプロキシ設定が保存されていないか確認します。
- 実行環境の境界を確認:コマンドがホストマシン、WSL、コンテナ、仮想マシン、リモートサーバーのどこで実行されているかを判断し、そこでのローカルアドレスが実際に何を指すか確認します。
- 最後にTUNとDNSを確認:基本的なポートテストが成功してから、仮想インターフェース、ルーティング、名前解決を調べます。
プロキシを明示したテストと環境変数を使ったテストの両方が成功しているのに、特定のツールだけが失敗する場合、原因はほぼそのツール自体にあります。その場合はツールの詳細ログを有効にし、接続先ドメイン、読み込まれたプロキシ設定、TLSエラーを確認してください。Clashのノードを変更し続ける必要はありません。
プロキシを明示したテストがすべて失敗する場合は、Clash側に戻ってポート、設定、ノードを確認します。複数の接続先ドメインを個別にテストし、接続履歴でルールの適用結果を比較するとよいでしょう。一部のドメインだけが失敗する場合は、ルール、DNS、接続先サービスを重点的に確認します。すべてのドメインで接続を確立できない場合は、ローカルの待受、コアのログ、プロキシノードを優先して確認してください。
切り分けが終わったら、不要な一時変数と重複した設定を削除し、明確なプロキシ経路を1つだけ残します。システムプロキシはデスクトップアプリ、環境変数はターミナルセッション、ツール独自の設定は固定要件のあるプログラム、TUNはより多くの通信を引き受けたい環境に適しています。現在の環境に合う層を主要な入口として選ぶことで、ポート変更や設定競合によるトラブルを減らせます。