トラブル対応 読了時間:約10分

システムプロキシを設定しても通信できない?ブラウザーとターミナルの切り分け

ブラウザー拡張機能によるプロキシ設定の上書きと、ターミナルがシステムプロキシを参照しない問題は、よくある原因です。確認手順、環境変数の設定方法、代替策となるTUNモードを解説します。

まず切り分け:カーネルに届いていないのか、ルールでDIRECTになっているのか

「システムプロキシ」は、OSにプロキシのアドレスとポートを登録する設定です。デバイス上のすべての通信をClashに転送する機能ではありません。この設定を使うかどうかは、アプリが利用するネットワーク機能によって異なります。ブラウザー拡張機能やアプリ独自のプロキシ設定、ターミナルの環境変数によって、実際の通信経路が変わることもあります。

よくある勘違いとして、リクエストはすでにmihomoカーネルに届いているものの、ルールによってDIRECTに振り分けられているケースがあります。この場合、接続元のIPアドレスが変わらないのはルールの結果であり、システムプロキシが機能していないわけではありません。まずクライアントの「接続」画面を開き、対象ドメインで絞り込んで、適用ルール、プロキシグループ、最終的な出力先を確認してください。

確認できた状況まず確認する項目次に試すこと
接続画面に対象のリクエストが表示されないアプリがプロキシを使用しているかブラウザー設定の確認、またはプロキシを明示的に指定
リクエストは表示されるが、最終出力先がDIRECTルールの優先順位とプロキシグループの選択そのドメインが本来DIRECT接続の対象か確認
プロキシグループには届くが、接続がタイムアウトするノード、接続先サイト、ネットワークの疎通状況接続できることが分かっている別のノードで比較
プロキシを明示すると成功するが、通常のアクセスは失敗するシステムプロキシからの接続経路ブラウザーとターミナルを分けて対処

手順1:プロキシを明示してローカルの待受ポートを確認

この段階では、ルールやサブスクリプション、DNSを変更しないでください。同じ接続先にプロキシを明示してリクエストを送り、カーネルがリクエストを受け付けるかを切り分けます。Windows PowerShellではcurl.exeを使い、Windows PowerShell 5.1のcurlエイリアスによる引数の解釈違いを避けます。macOSとLinuxではcurlを使ってください。

# Windows PowerShell
curl.exe -v --connect-timeout 10 --max-time 20 --noproxy "" --proxy http://127.0.0.1:7890 https://example.com/ -o NUL

# macOS / Linux
curl -v --connect-timeout 10 --max-time 20 --noproxy "" --proxy http://127.0.0.1:7890 https://example.com/ -o /dev/null

--noproxy ""を指定すると、このテストに限りプロキシの除外リストが空になり、既存のNO_PROXYによる誤判定を防げます。詳細出力で127.0.0.1:7890への接続を確認し、HTTPSリクエストのCONNECTトンネルが確立されるかも確認してください。同時に、クライアントの「接続」または「ログ」に該当する記録があるかを確認します。

  • すぐに「接続が拒否されました」と表示される:カーネルが起動しているか、ポート番号に誤りがないか、待受アドレスにIPv4ループバックアドレスが含まれているかを確認してください。
  • ローカルポートには接続できるが、CONNECTの後に失敗する:ノード、ルール、TLS、接続先サイトの稼働状況を確認してください。システムプロキシのオン・オフを繰り返す必要はありません。
  • HTTP 407が返される:ローカルプロキシの認証設定を確認してください。パスワードを含むコマンド全体を公開ログに貼り付けないでください。
  • 接続先サイトからHTTPレスポンスが返される:今回のリクエストはローカルのプロキシ経由で送信されています。リモートノードを経由したかどうかは、クライアントの出力先記録で確認してください。

WindowsではGet-NetTCPConnection -State Listen -LocalPort 7890、macOSではlsof -nP -iTCP:7890 -sTCP:LISTENを実行すると、待受状態を確認できます。別のプログラムがポートを使用している場合は、まずプロセスを特定してから、競合するプログラムを終了するかクライアントのポートを変更してください。

ブラウザーの切り分け:システム設定、拡張機能、独自設定

Chrome・Edge:まず拡張機能による上書きを確認

  1. クライアントで「システムプロキシ」を有効にし、サブスクリプションが有効で、現在のプロキシグループに利用可能なノードが選択されていることを確認します。
  2. Chromeでは「設定」→「システム」→「パソコンのプロキシ設定を開く」、Edgeでは「設定」→「システムとパフォーマンス」から、パソコンのプロキシ設定を開きます。画面上の表記はバージョンによって異なる場合があります。
  3. Windows 11では「設定」→「ネットワークとインターネット」→「プロキシ」、Windows 10でも「設定」→「ネットワークとインターネット」→「プロキシ」を開きます。手動プロキシのアドレスとポートがクライアントの設定と一致しているか確認してください。
  4. chrome://extensions/またはedge://extensions/を開き、プロキシを制御する拡張機能を一時的に無効にします。プロキシ設定を自動で切り替える拡張機能も対象です。
  5. ブラウザーを完全に終了してから再起動し、同じテスト先にアクセスして、クライアントの接続記録を確認してください。

シークレットウィンドウだけでは、十分な切り分けになりません。拡張機能はシークレットモードでも実行を許可でき、システムレベルの設定も引き続き有効だからです。より確実に比較するには、プロキシ拡張機能を設定していない新しいブラウザープロファイルを作成してください。「組織によって管理されています」と表示される場合は、chrome://policy/またはedge://policy/も確認します。管理対象のデバイスでは、管理者にポリシーの変更を依頼してください。

Firefox:プロキシ設定の参照先を明確にする

Firefoxで「設定」→「一般」→「ネットワーク設定」→「設定」を開きます。クライアントが設定したシステムプロキシを使うには、「システムのプロキシー設定を使用する」を選択してください。「手動でプロキシーを設定する」を使う場合は、HTTPプロキシのアドレスとポート、HTTPSプロキシの設定を自分で管理する必要があります。以前設定したSOCKSプロキシは、システムプロキシを有効にしても自動的には無効になりません。

macOSでは「システム設定」→「ネットワーク」→現在のネットワーク接続→「詳細」→「プロキシ」で、WebプロキシとセキュアWebプロキシを確認できます。Linuxデスクトップのプロキシ設定がアプリに反映されるかは、デスクトップ環境やアプリの実装によって異なります。デスクトップのスイッチだけで、すべてのブラウザーに設定が反映されたと判断しないでください。

ターミナルの切り分け:HTTP_PROXYとHTTPS_PROXYを設定

ターミナルのプログラムは、通常デスクトップのシステムプロキシを自動的には使用しません。curl、Git、パッケージマネージャーは、それぞれ独自の設定ファイルを参照する場合もあります。ブラウザーでは接続できてもターミナルで失敗する場合は、まず現在のターミナルセッションに環境変数を設定し、システム全体の環境設定を変更するのは後にしてください。

Windows 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 -v --connect-timeout 10 --max-time 20 https://example.com/ -o NUL

# テスト後に今回の設定を削除
Remove-Item Env:HTTP_PROXY, Env:HTTPS_PROXY, Env:NO_PROXY -ErrorAction SilentlyContinue

HTTPS_PROXYはHTTPS接続に使用するプロキシを指定する環境変数であり、ローカルプロキシのアドレスをhttps://にする必要があるという意味ではありません。一般的なHTTPポートや混合ポートにはhttp://127.0.0.1:7890を指定し、CONNECTでHTTPS接続を転送します。

macOS・Linux:環境変数の大文字・小文字に注意

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 -v --connect-timeout 10 --max-time 20 https://example.com/ -o /dev/null

# テスト後に今回の設定を削除
unset http_proxy https_proxy no_proxy

大文字と小文字を区別する環境では、curlがHTTPプロキシ用に受け付けるのは小文字のhttp_proxyだけです。他のプログラムでは参照ルールが異なる場合もあります。まず上記の最小構成で動作を確認し、対象ツールのドキュメントに従って大文字の環境変数も設定してください。既存のプロキシ環境変数がある場合は、元の値を控えてからテストし、終了後に戻してください。既存の設定をそのまま削除しないでください。

環境変数の変更が反映されるのは、現在のプロセスと、その後に起動する子プロセスだけです。すでに開いているIDEのターミナル、バックグラウンドタスク、システムサービスには自動で反映されません。設定を永続化する場合は、使用するシェルの起動ファイルに追加し、ターミナルを開き直して確認してください。プロキシを無効にしたときに使えなくなる固定アドレスを残さないよう注意してください。

アプリごとの設定:Git、SOCKS、隔離された環境

Git:残っているプロキシ設定を確認し、すぐに全体設定を上書きしない

GitのHTTP通信には、環境変数とGitの設定の両方が影響する場合があります。まず設定の参照元を確認し、古いポート、リモートプロキシのアドレス、URLごとの設定が残っていないか調べてください。出力に認証情報が含まれる可能性があるため、共有する前に必ず伏せてください。

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

# 今回のGitコマンドだけにプロキシを指定
git -c http.proxy=http://127.0.0.1:7890 ls-remote https://github.com/git/git.git HEAD

2つ目のコマンドはGitのHTTPS接続経路を確認するだけで、全体設定には書き込みません。git@で始まるSSHリポジトリのアドレスは別の通信経路を使うため、http.proxyを設定してもHTTPプロキシ経由にはなりません。

SOCKS:ローカルでの名前解決とプロキシ側での名前解決

クライアントの待受がSOCKSのみの場合、HTTPポートとして使うことはできません。SOCKSポートが7891と確認できている場合は、次のコマンドを実行してください。混合ポートを使う場合は、実際の混合ポート番号に置き換えます。

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

curlのsocks5h://は接続先ドメインの名前解決をSOCKSプロキシ側で行い、socks5://では通常ローカルで名前解決します。この違いはローカルDNSの問題を切り分けるのに役立ちますが、すべてのアプリのDNS通信がプロキシ経由になったことを示すものではありません。

WSL、コンテナー、仮想マシンでは、ネットワークの境界にも注意が必要です。内部の127.0.0.1がホストを指すとは限りません。WSLではNATとミラーネットワークモードで動作が異なるため、実際のモードに応じてホストのアドレスを確認してください。ネットワークをまたいで待受ポートに接続する場合は、「LANからの接続を許可する」設定、待受アドレス、ファイアウォールの適用範囲を確認します。プロキシポートをインターネットに直接公開しないでください。

TUNモード:プロキシ設定を参照しないアプリへの対処

アプリがシステムプロキシを参照せず、プロキシを明示的に設定する機能もない場合は、mihomoクライアントのTUNモードを検討できます。TUNは仮想ネットワークインターフェースとルーティングを使ってIP通信を転送するため、HTTPシステムプロキシとは接続方式が異なります。ブラウザーにシステム設定を「より強制的に」参照させる機能ではありません。

  1. まず明示的なプロキシ指定で、ノード、サブスクリプション、ルールが利用できることを確認します。現在の設定を書き出し、元に戻せるようバックアップを残してください。
  2. クライアントの「設定」で「サービスモード」を開き、案内に従ってサービスをインストールまたは有効にします。クライアントによっては別の権限昇格方法を使うため、現在のバージョンの画面に従ってください。
  3. 「TUNモード」を有効にし、ログで仮想インターフェースとルートが正常に作成されたか確認します。auto-route、DNSの転送、インターフェースの検出に関する設定は、クライアントが生成する設定との整合性を保ってください。
  4. デフォルトルートの競合を避けるため、ほかのVPNや同種の仮想ネットワークアダプターによる通信制御をいったん停止し、その後ブラウザー、ターミナル、LAN内のデバイス、社内サイトへの接続を確認してください。
  5. ネットワークに接続できなくなった場合は、まずTUNを無効にし、元のシステムプロキシ設定に戻してください。問題が起きている状態で、DNS、ルート、ルールを同時に変更しないでください。

TUNが特定のアプリの通信を転送するかは、ルート、除外設定、ネットワークインターフェース、権限によって決まります。UDPやQUICなどの通信が正常に転送されるかどうかは、カーネルの設定とノードの対応状況にも左右されます。TUNを有効にしていても、ルールによってDIRECTが選ばれる場合があります。「TUNに入ったか」と「最終的にリモートノードを経由するか」は、別々に確認してください。

再テストの手順:一度に変更するのは一つだけ

切り分けが終わったら、同じ接続先、同じノード、同じルールモードで比較してください。特定のページが開くかどうかや、一度だけ確認した出口IPだけで判断しないでください。キャッシュ、除外リスト、接続先ドメインのルールによって結果が変わる場合があります。

  • ローカル接続:127.0.0.1:7890を明示してリクエストを送り、クライアントに記録されるか確認します。
  • ブラウザー:プロキシ拡張機能を無効にして参照元を確認した後、接続記録にリクエストが表示されるか確認します。
  • ターミナル:現在のセッションに環境変数を設定し、対象のツールから同じリクエストを正常に送信できるか確認します。
  • 出力先:リクエストに適用されたルールと、プロキシグループで最終的に選択されたノードを確認します。
  • 設定の復元:クライアントを終了した後にターミナルのプロキシ環境変数を削除する必要があるか、TUNを無効にした後に社内ネットワークとDNSが復旧するか確認します。

問題を報告する際は、OSのバージョン、クライアントとカーネルのバージョン、実際の待受ポート、失敗したコマンド、発生時刻、該当するログを記録してください。サブスクリプションのURL、認証情報、機密性の高いドメイン名は削除してください。ルールやDNSを詳しく確認するにはトラブルシューティングガイドを、システムプロキシ、プロキシグループ、TUNの違いは用語集を参照してください。

Clashをダウンロード