まず"システムプロキシ"を2本の経路に分けて考える
"システムプロキシ"という言葉から統一スイッチのようなものを想像しがちだが、実際にOSレベルのプロキシ設定が効くのはシステムプロキシ設定に従うアプリだけであり、その"従う"仕組みは完全に独立した2本の経路に分かれている。
- ブラウザ側の経路:主要なブラウザ(Chrome、Edge、Firefox など)は Windows/macOS 上でデフォルトでシステムのプロキシ設定項目を読み込む。この経路はOSのネットワーク設定パネルによって制御される。
- ターミナル/コマンドライン側の経路:ターミナルの
curlやgit、パッケージマネージャーなどはOSの設定パネルを見ておらず、http_proxy、https_proxyといった環境変数を参照する。システムプロキシのスイッチはこれらには一切影響しない。
これこそ"Clashを起動してるのに効かない"という声が多い理由――そもそも適用範囲がターミナルをカバーしておらず、問題はターミナル側の経路が未設定であるだけというケースが少なくない。逆にターミナルは使えるのにブラウザだけ直結になっている場合は、システムプロキシ設定項目自体が正しく書き込まれていないか、例外リストに引っかかっているケースが多い。
Clash系クライアントが起動して行っているのは基本的に2つだけ――ローカルにプロキシポート(HTTP/SOCKS/混合ポート)を開くことと、ルールに従って各ノードに振り分けることだ。システム内の他のプログラムがこのポートに通信を送るかどうかはシステムプロキシ設定や環境変数が正しく構成されているかにかかっており、これはOS側の役割であって Clash コア本体の役割ではない。
手順1:Clashが実際にポートを監視しているか確認する
システムプロキシ設定や環境変数を疑う前に、まずポート自体が通っているかを確認しておく。これだけで"見せかけの無効"は半分は消える。
- クライアントの接続/ポート設定画面を開き、現在のHTTPポート(デフォルトでよくあるのは7890)と混合ポートが有効かどうかをメモする。
- コマンドラインで直接そのポートをテストし、システムプロキシのスイッチを経由せずに監視の有無だけを確かめる。
HTTPレスポンスヘッダーが取得できれば(301/302でも構わない)ポート自体は問題なく、原因はシステムプロキシ側が接続していないこと。逆に接続拒否が出る場合はクライアントが起動していないかポートが変更されているので、まずこちらを解決してから次に進む。curl -x http://127.0.0.1:7890 https://www.google.com -I - Windows では
netstat -ano | findstr 7890、macOS/Linux ではlsof -i :7890を使い、そのポートを占有しているのが本当に Clash であって別のプログラムに奪われていないかを確認する。
| ポート種別 | よくあるデフォルト値 | 主な用途 |
|---|---|---|
| HTTPポート | 7890 | ブラウザのシステムプロキシ、大半のターミナルツール |
| SOCKSポート | 7891 | SOCKS5を要求する一部のクライアント |
| 混合ポート(mixed-port) | 設定により異なる | 同一ポートでHTTPとSOCKSの両方を受け付ける |
| コントロールパネルポート | 9090 | RESTful API用、プロキシ転送とは無関係 |
ブラウザ側:システムプロキシがなぜ反映されないのか
ブラウザ側の経路がうまくいかない原因は主に3か所。順番に確認する。
- システムプロキシのスイッチが実際にはONになっていない――クライアントの"システムプロキシに設定"は連動スイッチであり、バージョンによっては再起動後に前回の状態が自動で復元されないことがある。記憶で判断せず、現在の状態を手動で確認する。
- ブラウザ自身が独自のプロキシ設定を持っている――多くのブラウザはデフォルトでシステムに追従するが、以前に"手動でプロキシを設定"していたり、プロキシ管理系の拡張機能を入れていた場合、ブラウザは自身の設定を優先してシステム側の設定を無視する。この場合はブラウザのプロキシモードを"システムプロキシに従う"に戻すか、該当の拡張機能を無効化する。
- 企業・教育機関のネットワークにおけるグループポリシーによる上書き――一部の業務用PCではグループポリシーがネットワーク設定を一括管理しており、システムプロキシ項目にチェックが入っていても実際の通信はポリシー層に上書きされてしまう。こうした環境では TUN モードに切り替えてシステムプロキシ設定そのものを回避することを推奨する(詳細は本文末尾)。
ブラウザのシークレット/プライベートウィンドウは独自にネットワーク設定のキャッシュを持つことがあり、通常ウィンドウで効いていてもシークレットウィンドウには同期されないケースがある。"一部のウィンドウだけ効かない"場合は、まずシークレットウィンドウを開き直してから判断する。
ターミナル側:環境変数とシェル設定
ターミナルはシステムプロキシのパネルを見ておらず、環境変数を参照する。よく使われるのは http_proxy、https_proxy、all_proxy(小文字が標準で、大文字表記はツールによって対応状況が異なる)。動作確認だけなら現在のターミナルセッションでその場でエクスポートすればよい。
export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export all_proxy="socks5://127.0.0.1:7891"
この書き方は現在開いているターミナルウィンドウにしか効かず、ウィンドウを閉じると消える。ターミナルを開くたびに自動で反映させたい場合は、これらの行をシェルの起動設定ファイルに書き込む――bashユーザーは ~/.bashrc か ~/.bash_profile、zshユーザー(macOSのデフォルトシェル)は ~/.zshrc に書き込み、書き終えたら source ~/.zshrc を実行すれば現在のウィンドウにも即座に反映され、ターミナルを再起動する必要はない。
よくある落とし穴は3つある。
- 設定ファイルを間違えている――macOSのデフォルトシェルはすでに zsh に切り替わっているのに、古いチュートリアルをそのまま参考にして
.bashrcを編集してしまい、新しいターミナルでは全く読み込まれないというケース。まずecho $SHELLで現在使っているシェルを確認する。 - ポート番号が実際の設定と一致していない――クライアント側でポートを変更したり、設定ファイルを再インストールした際に、環境変数に書いたポート番号を更新し忘れているケース。この問題はターミナルだけで発生し、ブラウザはシステムプロキシ設定に追従しているため正常に動くことが多い。両者の挙動が異なるときはまずポート番号を照らし合わせる。
- 一部のツールは自身の設定項目を単独で読み込む――たとえば Git は
git config --global http.proxy内で個別に設定されたプロキシアドレスを優先的に読み込むため、環境変数が正しくてもGitは自身の設定項目に従って動作する。追加で以下を実行する必要がある。git config --global http.proxy http://127.0.0.1:7890 git config --global https.proxy http://127.0.0.1:7890
環境変数を設定した後は、curl -v https://ipinfo.io/ip の出力IPがノードの所在地域のIPに変わっているかどうかで検証すること。コマンドがエラーを返さないことだけを見てはいけない――エラーが出ないことは代理経由になっているとは限らず、直結のままアクセスできているだけの場合もある。
PACの残骸とプロキシ例外リスト
以前にPACファイル方式のプロキシツール(自動設定スクリプトモード)を使っていた場合、Clashに切り替えたりアンインストールした後も古いPACアドレスがシステムに残っていることがあり、システムプロキシパネルに表示されるのが手動指定のIP+ポートではなく"設定スクリプトを使用する"のままになっていることがある。この残骸は手動プロキシより優先度が高くなる場合が多く、システムプロキシをONにしても直結のままだったり動作がおかしくなる原因になる。確認方法は以下の通り。
- Windows:「設定 → ネットワークとインターネット → プロキシ」を開き、「セットアップ スクリプトを使う」が有効になっていないか確認する。有効な場合はまずオフにしてから、「手動でプロキシをセットアップする」を個別にオンにする。
- macOS:「システム設定 → ネットワーク → 対象ネットワークサービスの詳細 → プロキシ」で、「自動プロキシ構成」に古いPACアドレスが入力されていないか確認する。同時に「Webプロキシ(HTTP)」と「セキュアWebプロキシ(HTTPS)」の2項目にそれぞれ Clash のポートが正しく入力されているかも確認する。
もう一つ見落としがちなのがプロキシ例外リスト(no_proxy / bypass list)だ。システムプロキシ設定には通常「これらのアドレスにはプロキシサーバーを使用しない」という項目があり、デフォルトで localhost や 127.* などのローカルアドレスが含まれているのは正常だが、一部のインストーラーや古い設定がここに広範なワイルドカードルールを大量に追加してしまい、正常なサイトまで例外リストに入ってしまってアクセス時に丸ごと直結になってしまうケースがある。この例外欄に想定外のドメインパターンが書き込まれていないか重点的に確認する。ターミナル側で対応する環境変数は no_proxy で、これも同様に個別に確認する価値がある。
echo $no_proxy
no_proxy に * や過度に広いワイルドカード(トップレベルドメイン全体など)が書かれていると、ターミナルのプロキシ設定が実質無効化され、すべてのリクエストが例外と判定されて直結になってしまう。こういう書き方が見つかった場合は一度クリアして、必要最小限のローカルアドレスだけを書き直すことを推奨する。
確認手順チェックリストと最終手段
ここまでの内容を、そのまま上から順にチェックできる一覧表にまとめた。"システムプロキシがONなのに効かない"に遭遇したら上から順に確認していく。
curl -xで直接ポートをテストし、Clash本体が監視していてポート番号が正しいことを確認する。- クライアントの「システムプロキシに設定」スイッチが実際にONになっているかを確認する。
- ブラウザが個別に手動プロキシを設定されていないか、プロキシ管理系拡張機能が入っていないかを確認し、まとめて「システムに従う」に戻す。
- システムプロキシパネルに古いPACスクリプトのアドレスが残っていないか確認し、クリアしてから手動でIPとポートを指定する。
- システムプロキシの例外リストとターミナルの
no_proxy変数を確認し、広すぎるワイルドカードルールを整理する。 - ターミナルの環境変数は現在使用しているシェル(bash/zsh)に合わせて対応する設定ファイルに書き込み、ポート番号をクライアントの実際の設定と一致させる。
- Gitなど独自のプロキシ設定項目を持つツールを個別に確認し、期限切れの古いアドレスを読み込んでいないかチェックする。
一通り確認しても一部のアプリだけがどうしてもシステムプロキシ設定や環境変数を認識しない――これは珍しくない話で、独立プロセスとして動く一部のプログラムはシステムプロキシパネルもシェルの環境変数も一切チェックせず、自身に組み込まれた直結ロジックしか使わない。こうした"言うことを聞かない"アプリに遭遇した場合、手間が少ないのは TUNモード に切り替えることだ。クライアントがシステムのネットワーク層に仮想ネットワークカードを作成し、すべての通信をネットワーク層で一括して処理する。個々のアプリがシステムプロキシ設定に"協力"するかどうかに依存しなくなり、ブラウザ、ターミナル、その他の独立プロセスの通信もまとめて処理される。TUNモードは適用範囲がより徹底している一方、DNS処理やネットワークカードの権限要求も高く、設定にはシステムプロキシより一段階多い権限の許可が必要になる。具体的な有効化手順はプラットフォーム別の解説ページで確認できる。