macOSでClashのシステムプロキシが効かないときの対処法|ブラウザとターミナルを別々に確認

SafariやChromeはシステムプロキシを使う一方、ターミナルは通常そのままでは使いません。ネットワーク設定のプロキシ項目と、shellのhttp_proxy環境変数を分けて確認します。

システムプロキシ・ターミナルのプロキシ・TUNを区別する

Clashクライアントに「システムプロキシが有効」と表示されるのは、クライアントがmacOSのプロキシ設定を書き換えようとしていることを示します。すべてのアプリの通信が制御されているという意味ではありません。Safariは通常システムプロキシを使い、Chromeもデフォルトではシステムプロキシを参照しますが、拡張機能や起動オプション、組織のポリシーによって動作が変わることがあります。ターミナルのコマンドはそれぞれ独自のプロキシ設定を使うため、ブラウザでWebページが開けるかどうかだけでは判断できません。

GUIクライアントは設定のインポート、ルールグループの切り替え、システム設定の管理を担当し、コアはプロキシポートの待ち受け、ルール判定、リクエストの転送を担当します。クライアントの画面が動作中でも、設定エラーによってコアが正常に起動していない場合があります。「プロキシ設定が書き込まれたこと」と「ローカルポートが実際に使えること」は分けて確認しましょう。

接続方式主な確認箇所適用範囲
システムプロキシmacOSで現在使っているネットワークサービスのプロキシ項目アプリ側がこれらの設定に従う必要があります
ターミナルで明示するプロキシコマンドの引数、環境変数、ツールの設定通常は指定したプロセスとその子プロセスだけに適用されます
TUNモード仮想ネットワークインターフェース、ルーティング、DNS、権限クライアントとコアの対応が必要な別の接続経路です

コアの動作とローカルの待ち受けポートを確認する

サブスクリプションファイルだけでなく、実行中の設定を確認する

まずクライアントで、現在の設定が読み込まれているか、HTTP・SOCKS・混合ポートの実際の番号はいくつかを確認します。画面の項目名や設定の上書き方法はクライアントによって異なるため、共通のメニュー手順を当てはめることはできません。サブスクリプションに記載されたポートがクライアント設定で上書きされることもあるため、実行中の設定と起動ログを優先して確認してください。

混合ポートに対応するコアでは、同じポートでHTTPとSOCKSの両方のリクエストを受け付けられます。以下は設定項目の一部を示す例です。ノードやルールグループを含む完全なサブスクリプションではなく、トラブル対処のために元ファイルを上書きする必要もありません。

mixed-port: 7890
allow-lan: false
mode: rule

allow-lan: falseでも、ローカルから127.0.0.1を利用できます。このMacだけを確認する場合、システムプロキシを有効にするためにLANアクセスを許可する必要はありません。TCPの待ち受け状態は、次のコマンドで確認できます。

lsof -nP -iTCP:7890 -sTCP:LISTEN
  • 待ち受けの記録がある場合:プロセスが想定したクライアントまたはそのコアのものかを確認し、待ち受けアドレスでローカルのループバック接続が許可されているか確認します。
  • 記録がない場合:ポート番号の間違い、コアの起動失敗、設定ログの解析エラーを確認します。必要に応じて、管理者権限でプロセスが表示されるか再確認してください。
  • ほかのプログラムがポートを使用中の場合:まず競合を解消し、クライアントの待ち受けポートとシステムプロキシのポートを両方変更します。片方だけを変更しないでください。

システム設定を介さず、プロキシの接続先を直接テストする

curl -I -v --connect-timeout 10 --max-time 20 \
  --noproxy "" \
  --proxy http://127.0.0.1:7890 \
  https://example.com/

このコマンドはHTTPプロキシを明示してHTTPSのURLにアクセスします。--noproxy ""は、現在のプロキシ除外リストの影響を避けるための指定です。example.comは接続テスト用のドメインなので、問題が起きている実際のサイトでも再テストしてください。応答ステータスコードは必ずしも200である必要はありません。ローカル接続の失敗、プロキシトンネルの失敗、TLSエラー、接続先からのHTTP応答を切り分けることが重要です。

127.0.0.1:7890に接続できない場合は、まずローカルの待ち受けを修復します。ローカルプロキシへの接続後にタイムアウトする場合は、クライアントの接続ログ、ルールの適用状況、ノードのログを確認します。プロキシを明示すればアクセスできるのにブラウザでは失敗する場合に、macOSのプロキシ設定が書き込まれている経路を確認しましょう。

ブラウザで効かない場合:現在のネットワークサービスのプロキシ項目を確認する

使用中のWi-FiまたはEthernetサービスを確認する

「システム設定」画面を採用しているmacOSでは、「システム設定」→「ネットワーク」→使用中のネットワークサービス→「詳細」→「プロキシ」の順に開きます。Wi-Fiの場合は「システム設定」→「Wi-Fi」→接続中のネットワークの「詳細」からも開けます。旧バージョンのシステム環境設定では、通常「ネットワーク」→対象サービス→「詳細」→「プロキシ」にあります。実際の画面表示に従ってください。

「Webプロキシ(HTTP)」と「セキュアWebプロキシ(HTTPS)」を確認します。サーバーは127.0.0.1、ポートはクライアントのHTTPポートまたは混合ポートと一致している必要があります。HTTPSプロキシの設定はHTTPSサイトへのリクエストに使うもので、ローカルプロキシのアドレスをhttps://127.0.0.1にするという意味ではありません。

macOSのプロキシ設定はネットワークサービスごとに保存されます。Wi-FiからUSB Ethernetに切り替えた場合、以前のサービスの設定が正しくても、新しいサービスの設定が正しいとは限りません。まずサービスを一覧表示し、現在使っているサービスを確認します。

networksetup -listallnetworkservices
networksetup -getwebproxy "Wi-Fi"
networksetup -getsecurewebproxy "Wi-Fi"
networksetup -getproxybypassdomains "Wi-Fi"
networksetup -getautoproxyurl "Wi-Fi"
networksetup -getproxyautodiscovery "Wi-Fi"

サービス名がWi-Fiでない場合は、最初のコマンドで表示された実際の名前に置き換え、引用符は残してください。以下は想定される項目の例であり、このMacでの検出結果ではありません。HTTPとHTTPSの両方を個別に確認します。

Enabled: Yes
Server: 127.0.0.1
Port: 7890
Authenticated Proxy Enabled: 0

PAC、プロキシ除外リスト、ブラウザ側の設定を確認する

  • 自動プロキシ設定:PACスクリプトは、接続先に応じてプロキシ経由か直接接続かを指定できます。元の設定を記録したうえで、一時的に検証対象のプロキシ方式だけを残し、PACによる振り分けを手動プロキシの不具合と誤認しないようにします。
  • プロキシ除外リスト:localhost、127.0.0.1、*.localはローカルアクセスでよく使われます。対象ドメインや範囲の広すぎるワイルドカードが誤って追加されていないか確認してください。ローカル用の除外項目をすべて消す必要はありません。
  • ブラウザ拡張機能:Chromeのプロキシ切り替え拡張機能を一時停止して再テストします。組織管理下のデバイスではポリシーも確認し、管理対象の設定をそのまま上書きしないでください。
  • 複数のクライアント:複数のプロキシツールが同時にシステム設定を書き換えないようにします。設定が以前のポートに何度も戻る場合は、どのプロセスがまだ設定を管理しているか確認してください。

変更後にWebページへ再度アクセスします。必要に応じてブラウザを完全に終了してから開き直してください。キャッシュで結果が歪まないよう、以前に読み込んでいないページを選ぶのがおすすめです。同時にクライアントの接続ログも確認します。新しい接続がまったく記録されない場合は、アプリがプロキシに接続していない可能性があります。接続は記録されているものの、ルールによってDIRECTに振り分けられている場合は、ルール選択の問題です。

ブラウザは使えるのにターミナルで失敗する場合:shellのプロキシ変数を設定する

ターミナルから起動したcurl、Git、パッケージマネージャーがmacOSのシステムプロキシに従うとは限りません。環境変数を参照するツールもあれば、独自の設定を参照するツールや、システムネットワークAPIを使うツールもあります。まず1つのコマンドだけで一時的にテストし、その後shell全体を設定するか判断してください。

まず1つのコマンドだけにプロキシを指定する

http_proxy=http://127.0.0.1:7890 \
https_proxy=http://127.0.0.1:7890 \
curl -I --connect-timeout 10 --max-time 20 https://example.com/

ここでのhttps_proxyもhttp://を使用します。これはローカルのHTTPプロキシ接続先を表すためです。HTTPSサイトへアクセスする際、通常ツールはHTTP CONNECTでトンネルを確立します。接続先がHTTPSだからといって、変数の値をTLSプロキシのアドレスに変更しないでください。

現在のターミナルセッションに環境変数を設定する

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"

env | grep -iE '^(http|https|all|no)_proxy='
curl -I --connect-timeout 10 --max-time 20 https://example.com/

これらの環境変数は、現在のshellと、そこから起動する子プロセスにだけ適用されます。すでに開いている別のターミナルや、Dockから起動したすべてのGUIアプリの設定が自動的に変わるわけではありません。変数名の大文字・小文字への対応はツールによって異なります。たとえばcurlのHTTPプロキシ変数は小文字のhttp_proxyを使うため、大文字のHTTP_PROXYだけを設定しないでください。

SOCKSの接続先を使う場合は、次のコマンドで個別にテストできます。ポートが実際にSOCKSに対応している場合に限って使ってください。この例の混合ポートはどちらのリクエストにも対応しています。socks5hを指定すると、接続先のホスト名解決をプロキシ側に任せられるため、ローカルのDNS解決とプロキシ経由の問題を切り分けやすくなります。

curl -I --noproxy "" \
  --proxy socks5h://127.0.0.1:7890 \
  --connect-timeout 10 --max-time 20 \
  https://example.com/

環境変数を永続化する前に、古い設定を確認する

一時的なテストに成功したら、対話型zshでは必要なexport行を~/.zshrcに追加し、新しいターミナルを開くかsource ~/.zshrcを実行します。ほかのshellでは、それぞれに対応する起動ファイルを使ってください。クライアントを終了しても、環境変数はローカルポートを参照したままです。トラブル対処を簡単にするには、常時有効にするより必要なときだけ設定する方法がおすすめです。

# 現在のshellで一般的なプロキシ変数を解除する
unset http_proxy https_proxy all_proxy no_proxy
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY

環境変数を起動ファイルに追加した場合は、該当行を削除するかコメントアウトしないと、新しいターミナルで再び読み込まれます。all_proxyが古いポートを参照していないか、no_proxyに接続先ドメインが含まれていないか確認してください。プログラムによって優先順位や照合方法が異なるため、複数のプロキシ変数を重ねて設定するのは避けましょう。

Gitまたはパッケージマネージャーだけ失敗する場合:ツール固有の設定を確認する

同じターミナルでcurlは成功するのにGitが失敗する場合は、システムプロキシを何度も切り替えるのではなく、Gitの設定元を確認します。古いグローバルプロキシ、リポジトリ単位のプロキシ、URLごとのプロキシ設定によって、Gitが別の経路を使っている可能性があります。

git config --show-origin --get-regexp '.*proxy.*'

# 今回のHTTPSリポジトリアクセスだけにプロキシを指定する
git -c http.proxy=http://127.0.0.1:7890 \
  ls-remote https://github.com/git/git.git HEAD

2つ目のコマンドは公開リポジトリへの接続テストで、グローバル設定は変更しません。出力にアカウント名、パスワード、個人用アドレスが含まれる場合は、ログを共有する前に伏せてください。グローバルのhttp.proxyが誤設定だと確認できた場合に限り、git config --global --unset http.proxyを実行します。リポジトリ単位やURLごとの設定は、それぞれ該当するスコープで変更してください。

  • HTTPS URLを使うGitリクエストと、git@ホスト:リポジトリ形式のSSHリクエストは、別々のプロトコル経路です。HTTPプロキシのテスト結果からSSHの動作を直接判断することはできません。
  • npmの個別設定は、npm config get proxyとnpm config get https-proxyで確認できます。変更する前に、元の値を記録してください。
  • sudoを使うと、環境変数が削除される場合があります。プロキシを引き継ぐために環境変数をすべて保持するのではなく、そのツールに必要な最小限の設定を確認してください。

リクエストがClashに届いている場合:ルール、DNS、TUNを確認する

接続ログに対象リクエストが表示されていれば、少なくともそのリクエストはコアに到達しています。この場合、「システムプロキシが効かない」という説明は適切でないことが多く、適用されたルール、現在選択されているルールグループ、最終的な接続先を確認する必要があります。ルールモードでは通常、設定順に照合されます。末尾のMATCHが処理するのは、それ以前のルールに一致しなかったリクエストだけです。ルールグループを選んでも、現在の選択先が必ずプロキシノードになるとは限りません。

  1. ルールの接続先:対象ドメインに適用されたルールと、最終的な接続先がノード、DIRECT、REJECTのどれかを確認します。直接接続ルールが設定されている場合、リクエストはコアを経由していても直結されることがあります。
  2. ノードと回線:同じ接続先に対し、利用可能な別のノードで再テストします。クライアント内の遅延テストはテスト先への結果にすぎず、対象サイトへの実際の接続を確認するものではありません。
  3. DNS:ローカルでの名前解決失敗、コアの上流DNSでの失敗、接続先への接続失敗を区別します。fake-ipを万能な解決策と考えないでください。DNSの制御やアプリとの互換性にも関係します。
  4. TUN:明示的なプロキシに従わないアプリの通信を制御する必要がある場合に限り、クライアントの対応状況、権限、ルーティング、DNSの設定を確認します。mihomoベースのクライアントでもTUNの設定項目は異なる場合があるため、別のクライアントの画面手順を流用しないでください。

再テストの手順と終了後の設定復元

調整後は、次の順番で確認します。ブラウザとターミナルの両方で成功すれば、それぞれの接続経路が正しく設定されています。特定のWebページが開けても、すべてのアプリがプロキシを使うとは限りません。

  1. lsofで実際のポートが待ち受け中か確認します。
  2. curl --proxyでプロキシを明示してテストし、ローカルの接続先とWebサイトの両方にアクセスできることを確認します。
  3. 現在のネットワークサービスのHTTP・HTTPS設定を確認してから、ブラウザで対象ページに再度アクセスします。
  4. ターミナルの環境変数とツール固有のプロキシ設定を確認し、同じターミナルでcurlと実際に使うコマンドをそれぞれテストします。
  5. クライアントを終了する前に、システムプロキシの管理をオフにします。終了後はネットワーク設定を確認し、待ち受けが停止したポートをプロキシが参照したままにならないようにしてください。

クライアントが異常終了した後、どのWebページにもアクセスできない場合は、現在のネットワークサービスの「プロキシ」画面を開き、残っているローカル手動プロキシの設定を記録してからオフにします。次にターミナルの環境変数を解除し、プロキシを使わずに接続できるかテストしてください。組織管理下のプロキシやPACは管理ルールに従って元に戻し、まとめて削除しないでください。引き続き原因を調べる場合は、実際のポート番号、サービス名、明示的なプロキシテストで失敗した段階、個人情報を伏せた接続ログをまとめると、「プロキシが反応しない」と伝えるだけより役立ちます。

ポートやルールの項目はYAMLマニュアル、設定のインポートやTUNの各OSでの操作は使い方ガイドを参照してください。トラブル対処では、アプリの接続経路、ローカルのコア、外部への接続先を段階ごとに切り分けることが重要です。

Clashをダウンロード