Clashのシステムプロキシを有効にしても通信できない原因と対処法|ブラウザー・ターミナル別に解説
ブラウザー拡張機能による上書き、システムプロキシの未設定、ターミナルがシステムプロキシを参照しないことが主な原因です。ブラウザーとコマンドラインに分けて確認手順と環境変数の設定方法を解説します。
まず「リクエストがコアに届いていない」のか「ルールでDIRECTが選ばれている」のかを切り分ける
まずクライアントの接続画面を開き、対象サイトにもう一度アクセスします。システムプロキシはOSが提供するプロキシ設定で、この設定を参照するアプリだけが利用します。クライアントのボタンが「有効」でも、ブラウザーやターミナル、バックグラウンドサービスが接続しているとは限りません。
まず、2つの役割を把握しましょう。GUIクライアントはシステム設定の切り替えと接続状況の表示を担当し、Clashまたはmihomoのコアはポートの待ち受け、ルールの照合、リクエストの転送を担当します。mihomoはClash Metaから名称が変更されたコアです。コアが正常に動作し、システムプロキシが正しく設定され、アプリがその設定を参照する、という3つの条件がそろって初めてリクエストがコアに届きます。
| 確認できた状況 | 優先して確認する項目 | 次に行うこと |
|---|---|---|
| ブラウザーでアクセスしても新しい接続が表示されない | システムプロキシ、拡張機能、ブラウザー独自の設定 | プロキシのアドレスとポートを確認し、拡張機能を一時的に無効にする |
| ブラウザーは使えるが、ターミナルに新しい接続が表示されない | コマンドラインツールがシステムプロキシを参照していない | curlでプロキシを明示してテストする |
| 接続は表示されるが、出口がDIRECTになっている | ルールによってDIRECTが選択されている | マッチしたルールとポリシーグループの経路を確認する |
| 接続は表示されるが、プロキシ経路がタイムアウトする | ノードの疎通状況またはリモートDNSの名前解決 | ログを確認し、システムプロキシの切り替えを繰り返さない |
対象ページを閉じて開き直すか、ターミナルから新しいリクエストを実行します。ブラウザーのキャッシュ、バックグラウンドの長時間接続、接続画面のフィルター設定が確認を妨げることがあります。新しい記録がないことだけで原因を断定することはできません。TUNモードを使っている場合は、まず現在の状態を記録してください。TUNは仮想ネットワークアダプターで通信を取り込む方式のため、テスト結果がシステムプロキシの有効性だけを示すとは限りません。
ローカルポートを確認する:7890は例です
まずクライアントに表示されているHTTPポートまたは混合ポートを確認し、次にシステム設定を確認します。混合ポートでは、同じポートでHTTPとSOCKSのプロキシ接続を受け付けられます。ここでは 127.0.0.1:7890 を例にしています。実際のポートが 7897 の場合は、以降のコマンドも同じ値に置き換えてください。
# mihomoの設定例。サブスクリプション設定全体ではありません
mixed-port: 7890
allow-lan: false
mode: rule
管理APIのポートをプロキシポートとして使わないでください。external-controller は制御用のインターフェースです。応答があってもHTTPプロキシの待ち受けポートの代わりにはなりません。また、ローカルのブラウザーを接続するために「LAN内接続を許可」を有効にする必要はありません。同じシステム内であれば、通常はループバックアドレスを使います。
ポートが実際に待ち受けているか確認する
Windows PowerShellで次のコマンドを実行します。待ち受けの記録があれば、そのポートが使用中だとは分かりますが、該当プロセスが現在使っているクライアントのコアかどうかも確認してください。
Get-NetTCPConnection -LocalPort 7890 -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess
# 直前の出力に表示されたプロセスIDを入力プロンプトに指定
Get-Process -Id (Read-Host "OwningProcessのプロセスIDを入力")
macOSでは lsof、Linuxでは ss を使います。出力がない場合は、ブラウザーの設定を変える前に、コアの起動ログ、実際のポート番号、起動エラーの有無を確認してください。
# macOS
lsof -nP -iTCP:7890 -sTCP:LISTEN
# Linux
ss -lntp 'sport = :7890'
ブラウザーのトラブル対処:システム設定を確認してから拡張機能を切り分ける
手順1:システムプロキシが設定されているか確認する
Windows 11では、「設定」→「ネットワークとインターネット」→「プロキシ」→「手動プロキシ セットアップ」→「編集」を開きます。手動プロキシを使う場合、アドレスはローカルのループバックアドレス、ポートはクライアントと同じ値にします。クライアントがPAC(プロキシ自動設定スクリプト)を使う場合は、「セットアップ スクリプトを使う」とスクリプトのアドレスを確認します。手動プロキシのスイッチも同時にオンにする必要はありません。
macOS 13以降では、「システム設定」→「ネットワーク」→現在のネットワークサービス→「詳細」→「プロキシ」を開きます。「Webプロキシ(HTTP)」と「セキュアWebプロキシ(HTTPS)」を確認してください。「セキュアWebプロキシ」という名称でも、ローカルポートにTLS接続が必要とは限りません。通常はローカルのHTTPプロキシポートに接続し、プロキシがHTTPSトンネルを確立します。
- システムプロキシを自動変更するほかのクライアントを終了し、設定が直後に上書きされないようにします。
- プロキシの例外リストを確認します。対象ドメインが除外対象に含まれていると、ブラウザーが直接接続する場合があります。
- Wi-Fi、有線ネットワーク、VPNを切り替えた後に設定をもう一度確認します。特にmacOSでは、現在のネットワークサービスが切り替わっていないか確認してください。
- 組織管理下のデバイスでは、まずポリシーによる制限を確認します。管理ポリシーで強制的に上書きされる項目を何度も変更しないでください。
手順2:ブラウザー独自のプロキシ設定を確認する
ChromeまたはEdgeの拡張機能管理画面で、プロキシ制御権限を持つ拡張機能を一時的に無効にし、新しい通常ウィンドウでテストします。プロキシ拡張機能がシステム設定を上書きすることがあります。拡張機能がシークレットモードでの実行を許可されている場合や、ブラウザーポリシーが適用されている場合もあるため、シークレットウィンドウだけを比較手段にするのは確実ではありません。
Firefoxでは、「設定」→「一般」→ページ下部の「ネットワーク設定」→「設定」を開きます。クライアントの切り替えに追従させる場合は「システムのプロキシー設定を利用する」を選びます。単独でテストする場合は、一時的に手動プロキシを選び、実際のアドレスを入力します。テスト後は元の設定に戻してください。クライアントを切り替えた際に古いポートが残るのを防げます。
特定のブラウザーだけで失敗する場合は、別のブラウザーから同じアドレスにアクセスして比較します。別のブラウザーでは接続画面に記録が表示されるなら、まず問題のブラウザーの拡張機能、プロファイル、組織のポリシーを確認してください。コアを再インストールする必要はありません。
ターミナルのトラブル対処:プロキシを明示したコマンドで比較する
まず環境変数に頼らず、curlにプロキシを明示します。多くのコマンドラインツールはデスクトップOSのシステムプロキシを自動では参照しません。ブラウザーが使えても、ターミナルも使えるとは限りません。次のコマンドはmacOSとLinuxの一般的なシェル向けです。テスト先には https://example.com/ を使います。
curl -q -v --connect-timeout 10 --max-time 30 \
--noproxy "" \
--proxy http://127.0.0.1:7890 \
https://example.com/ -o /dev/null
Windows PowerShellでは curl.exe を明示して実行します。Windows PowerShell 5.1では、curl が別のコマンドのエイリアスになっている場合があるためです。応答本文は NUL に破棄します。
curl.exe -q -v --connect-timeout 10 --max-time 30 --noproxy "" --proxy http://127.0.0.1:7890 https://example.com/ -o NUL
- ユーザー設定のcurl設定ファイルが今回のテストに影響しないよう、
-qは最初の引数に指定します。 --noproxy ""を指定すると、今回のリクエストではプロキシ除外リストが空になり、対象アドレスが例外設定でプロキシを迂回するのを防げます。--connect-timeout 10は接続時の待機時間を、--max-time 30は転送全体の制限時間を設定します。単位はいずれも秒です。- 詳細出力で、まず
127.0.0.1の実際のポートに接続していることを確認し、次にHTTPSのCONNECTトンネルと、その後の応答を確認します。
Connection refused が表示されたら、まずローカルの待ち受けアドレスとポートを確認します。407 Proxy Authentication Required の場合は、ローカルプロキシで認証が有効になっていないか確認してください。トンネル確立後にタイムアウトする場合は、ポリシーグループとノードを確認します。サイトから 403 が返っても、プロキシを経由していないとは限りません。接続先サイトによるアクセス制限の可能性があります。
ページが開くかどうかだけで判断しないでください。プロキシを明示したコマンドが成功し、クライアントの接続画面にも対応する接続先が表示されて初めて、アプリからコアまでの接続を確認できます。その後、ルールが想定した出口を選んでいるかを確認します。
ターミナルの環境変数を設定する:HTTPプロキシとSOCKSプロキシを区別する
macOS・Linux:まず現在のシェルだけに適用する
まず現在のターミナルで次の設定を行い、--proxy を付けないコマンドで動作を確認します。https_proxy はHTTPSサイトへのアクセスに使うプロキシを表します。変数の値に http:// を指定できるのは、ここで示しているのがローカルプロキシサービスの通信プロトコルだからです。
export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export no_proxy="localhost,127.0.0.1,::1"
curl -q -v --connect-timeout 10 --max-time 30 \
https://example.com/ -o /dev/null
動作を確認してから、~/.zshrc や ~/.bashrc など、使用中のシェルが実際に読み込むファイルへの追加を検討します。最初から全体設定に書き込まないでください。クライアントを終了した後も、ターミナルが閉じたポートに接続し続けることがあります。環境変数が影響するのは通常、現在のプロセスと、そこから起動した子プロセスです。すでに起動しているプログラムの設定は自動では変わりません。
ツールがSOCKSに対応している場合は、次のように一度だけ指定して実行できます。socks5h の h は、接続先ドメインの名前解決をプロキシ側で行うことを示します。socks5 では通常、接続先ドメインをローカルで先に名前解決します。SOCKSまたは混合接続を実際に受け付けているポートでのみ使用できます。
curl -q --proxy socks5h://127.0.0.1:7890 \
--noproxy "" --connect-timeout 10 --max-time 30 \
https://example.com/ -o /dev/null
Windows PowerShell:現在のプロセスの環境変数を設定する
PowerShellでは $env: を使い、シェルの export をそのまま使わないでください。次の設定は現在のPowerShellと、そこから起動した子プロセスに適用されます。すでに開いている別のターミナルには直ちに反映されません。
$env:http_proxy = "http://127.0.0.1:7890"
$env:https_proxy = "http://127.0.0.1:7890"
$env:no_proxy = "localhost,127.0.0.1,::1"
curl.exe -q -v --connect-timeout 10 --max-time 30 https://example.com/ -o NUL
最初の動作確認に setx を使わないでください。環境変数を永続化するコマンドで、変更を反映するには通常、新しいプロセスを起動する必要があります。現在のウィンドウに残った古い値と混同しやすくなります。変数名や優先順位の扱いはツールによって異なります。curlのHTTPプロキシには小文字の http_proxy を使い、すべてのツールが大文字の HTTP_PROXY を参照すると決めつけないでください。
古い環境変数とツール独自のプロキシ設定を確認する
プロキシを明示したコマンドは成功するのに通常のコマンドが失敗する場合は、ALL_PROXY、all_proxy、NO_PROXY、no_proxy に古いポートが設定されていないか、接続先ドメインが含まれていないか確認します。Gitなどのツールにも独自設定があります。次のコマンドは設定元を表示するだけで、ファイルは変更しません。
git config --show-origin --get-regexp '.*proxy.*'
出力がなくても、必ずしもエラーではありません。一致する設定が見つからなかったという意味です。以前の設定が見つかった場合は、どのファイルにあり、ほかの作業環境でまだ使われているか確認してから変更してください。ターミナルの出力を共有する際は、プロキシのアカウント名とパスワード、サブスクリプションURL、アクセストークンを含むアドレスを隠してください。
コアには届くがプロキシを経由しない:ルールとポリシーグループを確認する
まず接続の詳細で、マッチしたルールと最終的な出口を確認します。ルールモードでは設定順に照合され、DIRECT が選ばれた場合はコアが直接接続しています。システムプロキシの不具合ではありません。ポリシーグループに DIRECT が含まれることもあるため、グループ名だけでなく経路全体を確認してください。
- 同じ接続先でテストし、現在のモード、マッチしたルール、ポリシーグループの経路を記録します。
- 選択中のプロキシグループで、DIRECTではなく利用可能なノードが選ばれているか確認します。
- 必要に応じて一時的にグローバルモードに切り替え、グローバルのポリシーグループでプロキシノードを選択してから、同じリクエストを実行します。
- グローバルモードでは使えてルールモードではDIRECTになる場合は、ルールの順序を確認します。どちらもタイムアウトする場合は、ノードとログを確認してください。
- テスト後はルールモードに戻し、ほかのアプリの通信振り分けを長時間変えたままにしないでください。
「プロキシを経由すること」と「接続先にアクセスできること」は別の問題です。ノードの障害、接続先の制限、DNSの名前解決失敗は、リクエストがコアに届いた後に起こることがあります。ローカルポートへの接続拒否をドメインルールの追加で解決しようとしたり、マッチしたルールを確認せずにクライアントを再インストールしたりしないでください。
WSL・コンテナー・TUN:特殊な実行環境は最後に確認する
まず、コマンドが実際にどのOS上で実行されているか確認します。WSL、Dockerコンテナー、仮想マシン内の 127.0.0.1 がホストを指すとは限りません。WSL 2ではNATネットワークとミラーネットワークで挙動が異なり、Dockerのホストアドレスも実行環境によって変わります。ホストのブラウザーでは使えるのにコンテナーからは接続を拒否される場合は、ループバックアドレスをそのまま使うのではなく、まずネットワーク境界を確認してください。
ネットワーク境界を越えた接続が本当に必要な場合に限り、待ち受けアドレス、LAN内接続の許可、ファイアウォールのルールを検討します。プロキシの待ち受け範囲をほかのネットワークインターフェースに広げると、接続可能な範囲も広がります。信頼できる送信元に限定し、必要に応じて認証を設定してください。ターミナルの問題を調べるために、ポートをインターネットに公開しないでください。
プロキシ設定にもプロキシ環境変数にも対応していないアプリでは、TUNモードを検討します。TUNは通常、システム権限が必要で、ルーティングやDNSの制御にも関わります。ポート設定の誤りをすぐに直す機能ではありません。有効にする前に現在の状態を記録し、別のVPNや仮想ネットワークアダプターと同時に通信を取り込んで、原因の特定が難しくならないようにしてください。
確認後は設定を元に戻し、必要最小限の調査記録を残す
まず一時的な変更を元に戻し、普段の作業手順で動作を確認します。以前はプロキシ変数を設定していなかった場合は、次のコマンドで今回追加した変数を削除できます。元から値が設定されていた場合は削除せず、元の値に戻してください。
# macOS / Linux:この記事で一時設定した小文字の変数だけを削除
unset http_proxy https_proxy no_proxy
# PowerShell:この記事で一時設定したプロセス環境変数だけを削除
Remove-Item Env:http_proxy, Env:https_proxy, Env:no_proxy -ErrorAction SilentlyContinue
最後に、実際の待ち受けポート、プロキシを明示したcurlの結果、ブラウザーが使っているプロキシ設定元、接続詳細に表示されたルールと出口の4点を記録します。これらを確認すれば、問題がアプリ設定、ローカルの待ち受け、コアの転送のどこにあるかを絞り込めます。「プロキシを有効にしても使えない」という曖昧な記録だけで終わりません。