まず明示的なプロキシ接続で問題の箇所を切り分ける

「システムプロキシ」を有効にしても、クライアントがプロキシアドレスをOSの設定に反映しようとするだけで、すべてのアプリがその設定を使うとは限りません。mihomoコアが動作しているか、アプリがローカルポートに接続しているか、ルールがプロキシノードを選択しているかは、それぞれ別の問題です。まずブラウザー設定を介さずに明示的なプロキシ接続をテストし、その後、ブラウザーとターミナルを個別に確認します。

以下では、ローカルの混合ポート 7890 を例に説明します。クライアントのポート設定、または現在有効な設定から実際の値を確認してください。このポート番号は例であり、すべてのClashクライアントの標準値ではありません。Windows PowerShellでは、古いバージョンで curl が別のコマンドとして解釈されるのを避けるため、curl.exe を使用します。

# macOS / Linux
curl --noproxy "" -x http://127.0.0.1:7890 -I --connect-timeout 10 --max-time 20 https://example.com

# Windows PowerShell
curl.exe --noproxy "" -x http://127.0.0.1:7890 -I --connect-timeout 10 --max-time 20 https://example.com
  • 接続が拒否される:まずコアの起動状態、待ち受けポート、ポートを使用しているプロセスを確認します。DNSの変更は後回しにしてください。
  • ローカルプロキシへの接続は成功するが、その後タイムアウトする:クライアントの接続ログ、適用されたルール、プロキシグループ、ノードを確認します。
  • サイトからHTTPレスポンスが返る:対象への明示的なプロキシリクエストは完了しています。ルールのDIRECTではなく、実際にプロキシ経由で通信したかも確認してください。

ポート、コアの起動状態、プロセスの使用状況を確認する

サブスクリプションのインポート成功と、ローカルプロキシの待ち受け成功は別です。クライアントの画面が正常に開いていても、設定エラーでコアが終了していたり、別のプロキシプログラムが先にポートを使用していたりすることがあります。まず現在の設定が有効か確認し、コアの起動ログで待ち受け状態を確認してください。

設定項目を確認する

# ローカル待ち受けの例。接続可能な完全な設定ではありません
mixed-port: 7890
allow-lan: false
mode: rule

mixed-port は、同じポートでHTTPとSOCKSのプロキシリクエストを受け付けます。ポートを分けて設定する場合、port はHTTPプロキシ、socks-port はSOCKSプロキシに対応します。値を取り違えないでください。上記の設定例にはノード、プロキシグループ、ルールが含まれていないため、サブスクリプションの代わりにはなりません。GUIクライアントでは上書き設定から実行用の設定が生成されることもあるため、最終的に有効な値を確認してください。

ポート7890を使用しているプロセスを確認する

# Windows PowerShell:待ち受けPIDを確認
Get-NetTCPConnection -LocalPort 7890 -State Listen |
  Select-Object LocalAddress, LocalPort, OwningProcess

# macOS:プロセス名とPIDを確認
lsof -nP -iTCP:7890 -sTCP:LISTEN

# Linux:待ち受けアドレスとプロセス情報を確認。一部の情報には権限が必要です
ss -lntp 'sport = :7890'

Windowsでは、確認したPIDを Get-Process -Id 1234 に指定できます。1234 は例です。待ち受けプロセスが古いクライアントのものなら、まずそのプログラムを通常の方法で終了してから、現在のコアを起動してください。用途を確認できないシステムプロセスを強制終了しないでください。待ち受けプロセスが見つからない場合は、ログで設定の解析エラー、ポートのバインド失敗、コアの終了理由を確認します。

ローカルへの接続に localhost を使っている場合、IPv6のループバックアドレス ::1 に解決されることがあります。一方、コアがIPv4だけで待ち受けていると接続できません。切り分けでは 127.0.0.1 を指定し、接続先と待ち受けアドレスを一致させてください。

ブラウザー側の確認:システム設定、拡張機能、PAC

明示的なプロキシ接続は成功するのにブラウザーで使えない場合は、ブラウザーがどのプロキシ設定を参照しているかを確認します。ブラウザーやデスクトップ環境、組織のポリシーによって動作は異なるため、クライアントのスイッチの色だけでは判断できません。

  1. Windows 11:「設定」→「ネットワークとインターネット」→「プロキシ」を開きます。「プロキシ サーバーを使う」のアドレスとポートを確認し、「セットアップ スクリプトを使う」が有効かどうかも記録します。
  2. macOS:「システム設定」→「ネットワーク」→現在のネットワークサービス→「詳細」→「プロキシ」を開きます。Webプロキシ、安全なWebプロキシ、自動プロキシ構成を確認してください。
  3. Chrome:アドレスバーに chrome://settings/system と入力してパソコンのプロキシ設定を開きます。続けて chrome://extensions を開き、プロキシを制御する拡張機能がないか確認します。
  4. Firefox:「設定」→「一般」→「ネットワーク設定」→「設定」を開きます。「システムのプロキシー設定を利用する」を選ぶか、コアの設定と一致するHTTP・HTTPSプロキシのアドレスを手動で入力してください。

重複する設定を整理してからPACを確認する

プロキシ切り替え拡張機能がシステム設定を上書きしていることがあります。関連する拡張機能を一時的に無効にし、ブラウザーを完全に終了してから再起動し、クライアントの接続一覧を確認してください。拡張機能がプライベートウィンドウでの実行を許可されている場合、シークレットモードでも影響を除外できないことがあります。

PACはリクエストURLに応じてプロキシ経由か直接接続かを決めるスクリプトで、「すべての通信をプロキシ経由にする」スイッチではありません。たとえばスクリプトが DIRECT を返すと、ブラウザーはローカルプロキシに接続しません。設定を変更する前に元の状態を記録し、切り分け中は制御方法を一つだけ残して、自動スクリプト、手動プロキシ、拡張機能のルールが重ならないようにします。組織のポリシーで管理されている端末では、管理者に相談してください。組織から配布された設定を削除しないでください。

Windowsでは、PowerShellで次のコマンドを実行すると、現在のユーザーに適用されている一部のプロキシ設定を確認できます。設定元を特定するための情報であり、すべてのブラウザーが最終的にこの設定を使うとは限りません:

Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' |
  Select-Object ProxyEnable, ProxyServer, AutoConfigURL

netsh winhttp show proxy で表示されるのはWinHTTPのプロキシ設定です。この結果だけで、Chromeが使うシステムプロキシの有効・無効は判断できません。両者を混同すると、「コマンドでは直接接続と表示されるのに、ブラウザーは実際にはプロキシを使っている」と誤認することがあります。

ターミナル側の確認:プロキシ環境変数を明示的に設定する

多くのコマンドラインツールは、デスクトップのシステムプロキシを自動では参照しません。ブラウザーでサイトにアクセスできても、ターミナルのcurl、Git、パッケージマネージャーが失敗することはあります。まず一時的な環境変数で試し、すぐに全体設定を変更しないでください。動作を確認してから、シェルの起動ファイルに追加するか判断します。

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

# 古い設定が残っていないか確認
env | grep -iE '^(http|https|all|no)_proxy='

https_proxy という変数名は、接続先URLのプロトコルを表すもので、変数値を https:// で始める必要はありません。ローカルのHTTPプロキシに接続する場合は http://127.0.0.1:7890 を指定します。HTTPSリクエストはCONNECTでトンネルを確立します。プロトコルをHTTPSに変えると、ローカルポートが対応していないTLSプロキシを要求することになり、かえって接続できなくなる場合があります。

curlはセキュリティ上の理由から、HTTPプロキシの変数として大文字の HTTP_PROXY を使いません。小文字で設定するのが確実です。ほかのプログラムでは大文字・小文字の扱いが異なる場合があります。大文字の変数や all_proxy がすでに設定されていないかも確認し、古いポートが使われ続けないようにしてください。

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 -I --connect-timeout 10 --max-time 20 https://example.com
Get-ChildItem Env: | Where-Object Name -Match 'proxy'

この設定が適用されるのは、現在のPowerShellと、そこから後で起動した子プロセスです。すでに起動しているエディターや別のターミナルには自動で反映されません。Windows Terminalで先に開いていた別のタブにも、設定が反映済みとは限りません。WSL、コンテナー、リモートSSHセッションはそれぞれ独立した環境です。その中の 127.0.0.1 がホスト側のプロキシを指すとは限りません。この問題を解決するために、プロキシをすべてのネットワークインターフェースで待ち受けさせないでください。

一時設定を元に戻す

# macOS / Linux
unset http_proxy https_proxy all_proxy no_proxy
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY

# Windows PowerShell
Remove-Item Env:http_proxy, Env:https_proxy, Env:all_proxy, Env:no_proxy -ErrorAction SilentlyContinue

会社のプロキシを使っていた場合は、単に設定を消すのではなく、記録しておいた元の値に戻してください。現在のシェルを閉じれば、今回の一時的な変更も破棄されます。~/.zshrc、~/.bashrc、PowerShellのプロファイルに追加した設定は、別途編集が必要です。

特定のツールだけ失敗する場合:アプリ固有の設定を確認

環境変数を設定しても特定のツールだけ失敗する場合は、そのツール独自のプロキシ設定を確認してください。アプリ側の設定が環境変数より優先されることや、バックグラウンドサービスが現在のシェル環境を引き継いでいないことがあります。Gitを例に、まず設定元を調べてから変更を検討します:

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

# このコマンドだけにプロキシを指定し、全体設定には保存しない
git -c http.proxy=http://127.0.0.1:7890 ls-remote https://github.com/git/git.git HEAD

このコマンドでは公開リポジトリを使っています。プライベートリポジトリのテストで認証エラーが発生しても、すぐにプロキシの問題と判断しないでください。GitのHTTPS通信はHTTPプロキシを利用できますが、git@ で始まるSSH形式のリモートアドレスは別の経路で通信します。http.proxy を設定しても、同じプロキシを自動で経由するわけではありません。

npm、Pythonのパッケージ管理ツール、Javaアプリ、コンテナのビルドも、それぞれ設定ファイル、コマンド引数、サービス環境を参照する場合があります。まずcurlで基準となる接続を確認し、その後、個別のツールを調べてください。ネットワークの切り分けのためにTLS証明書の検証を無効にしないでください。証明書エラーが発生した場合は、システム時刻、信頼チェーン、組織ネットワークの証明書設定を確認します。

mihomoにリクエストが届いた後:ルールとノードを確認

クライアントの接続一覧に対象ドメインが表示されても、リクエストがコアに届いたことしか分かりません。想定したノードを使ったとは限りません。ルールは上から順に適用されるため、先にあるDIRECTルール、プロキシグループで選択中のDIRECT、最後のMATCHによって、通信経路が変わることがあります。

  • モードを確認:ルールモードが選択されているか確認します。比較のため一時的にグローバルモードへ切り替える場合は、グローバル側でプロキシノードが実際に選択されていることを確認し、テスト後に元のモードへ戻してください。
  • 適用ルールを確認:対象ドメイン、マッチしたルール、最終的なプロキシグループの経路を記録します。サブスクリプションで参照しているプロキシグループ名が、実際の定義と一致している必要があります。
  • ノードを確認:遅延テストに成功しても、その時点でテスト用URLに接続できたことしか分かりません。すべてのドメイン、ポート、プロトコルが使えるとは限りません。
  • エラーが発生した段階を確認:ローカル接続の失敗、ノードへの接続タイムアウト、DNS解決エラー、TLSハンドシェイクエラーは、それぞれ別に対処します。すべてを「プロキシが効かない」で片付けないでください。

接続元のIPアドレスを比較するには、同じIP確認サービスに対して直接接続とプロキシ経由のリクエストを実行し、接続ログと照合します。両方で同じIPが表示されても、システムプロキシが効いていないとは限りません。ルールによって確認先ドメインが直接接続になっていたり、TUNが直接接続に見えるリクエストを引き継いでいたりする可能性があります。テスト時はTUNの状態と選択中のポリシーを記録し、一度に複数の条件を変更しないでください。

# curlのアプリケーションレベルのプロキシを使わない。TUNが有効な場合はこのリクエストも引き継がれる可能性があります
curl --proxy "" --noproxy "*" --max-time 20 https://api.ipify.org

# ローカルのHTTPプロキシを明示的に使用
curl --noproxy "" -x http://127.0.0.1:7890 --max-time 20 https://api.ipify.org

TUNを使うべき場合と、システムプロキシを引き続き調整する場合

ブラウザーだけで問題が起きていて、明示的なプロキシ接続が成功しているなら、まずブラウザーの設定を修正してください。ターミナルツールがプロキシ環境変数に対応している場合は、ツールごとに設定するほうが原因を特定しやすいことがあります。TUNは、システムプロキシを参照しないアプリの通信を取り込みたい場合や、より多くのIP通信を対象にしたい場合に適しています。ただし、あらゆる問題の切り分けで最初に使う方法ではありません。

TUNモードは仮想ネットワークインターフェースとルーティングを使って通信を取り込み、通常は権限、DNS、ルートの設定も必要です。無効なノード、誤ったサブスクリプションやルールを修正するものではなく、ほかのVPNやセキュリティソフトのネットワークポリシーを回避できる保証もありません。同種の通信制御プログラムをいったん終了し、現在のルートとDNSの状態を記録したうえで、クライアントの手順に従って有効にしてください。

問題を報告する場合は、OSのバージョン、クライアントとmihomoコアのバージョン、実際の待ち受けポート、失敗したコマンド、エラーが発生した時間帯を記録してください。ログを共有する前に、サブスクリプションURL、アクセストークン、ノードの認証情報を削除してください。設定項目の詳細は設定ドキュメントを、基本的なインポートと通信の取り込み手順は使い方ガイドをご覧ください。