あるあるの症状:ブラウザは通るのにターミナルだけ直結・タイムアウト

Clash や Mihomo 互換クライアントを Windows で起動し、Edge や Chrome では海外サイトが開ける。あるいは TUN モードで画面右下の接続表示も「問題なさそう」に見える。それでも PowerShellコマンド プロンプト(CMD)Git Bash から git clonecurl を実行すると、途中で止まる・タイムアウトする・国内のミラーにだけ届く、といった差が出ることがあります。これは「プロキシが効いていない」のではなく、GUI が使う経路と、コンソールが使う経路がデフォルトでは一致しないことが多い、という理解が近いです。

Windows の「インターネット オプション」や「プロキシ」設定がブラウザに効いているからといって、そのまますべてのコンソール プロセスへ転送されるわけではありません。ターミナルでの取得は、多くの場合環境変数http_proxyHTTP_PROXY ほか)か、ツール単体の設定(Git の http.proxy など)を見ます。本章では、その前提から Clash の mixed-port と向き合わせる手順に入ります。

💡
本稿の対象と棲み分け 「WSL2 内の Linux からホスト側の Clash へ」を扱った別稿(WSL2)とは焦点が異なります。ここではネイティブな Windows のターミナルのみを対象とし、コンテナ側の環境変数はDocker 向けの記事へ譲ります。

なぜターミナルだけ Clash とすれ違うのか

第一に、多くのアプリが参照するユーザー/システムのプロキシ設定は、コンソールの子プロセスに自動で伝播しない場合があります。net use や開発ツールによってはインポートされますが、git.exe や標準ビルドの curl.exe が「いつ環境変数を読むか」は POSIX 準拠の期待どおりとは限らず、環境によって差が出ます。

第二に、Clash が TUN自動ルートでトラフィックを掴んでいる構成でも、アプリケーションが独自に名前解決して直 IP へぶつかったり、証明書ピン留めがある API と衝突したりすると、画面上はブラウザだけがうまくいって CLI が残る――というパターンが起こりえます。その場合でも、本稿が扱う HTTPS_PROXY 明示は切り分けと安定化の土台になります。TUN とルールの深掘りはTUN ガイドを併読ください。

第三に、localhost と記載されているプロキシ待受が、実際にはループバックだけに拘束されている構成だと、「プロキシ URL は合っているように見えるのに繋がらない」状態になりやすく、Allow LAN とファイアウォール許可を後ほどセットで確認します。

Clash:mixed-port の番号と HTTP としての張り方

設定 YAML またはクライアントの画面上で示される mixed-port(よくある例は 7890)は、同一ポートで HTTP と SOCKS の両方言を話せる入口です。この記事でもっとも単純に動かしやすいのは HTTP CONNECT として張る書き方で、環境変数には次のような形になります。http://127.0.0.1:7890 とするか、まれに http://localhost:7890 とするかで挙動差が出る場合は IPv4 に固定すると安定することがあります。ポート競合や誰が 7890 を掴んでいるかが気になるときは7890 と netstat の稿が近い論点です。

クライアント側でLAN からの接続を許可(Allow LAN に相当する設定/allow-lan)がオフになっていると、まれにループバック以外からの名前解決結果と噛み合わず気持ち悪い挙動になることがあります。まずローカルのターミナルだけを対象とする場合でも、仕様確認のひとときにオンにしておいてから 127.0.0.1 で試す運用でも構いません。セキュリティ方針上オフにしたいときは、その旨を頭に置いてポートとバインドを確認してください。

環境変数:HTTP_PROXY、HTTPS_PROXY、小文字との揃え方

多くの CLI は 大文字の HTTP_PROXYHTTPS_PROXY を参照し、POSIX 由来の小文字http_proxyhttps_proxy も併読します。両方セットしておけば環境による取りこぼしを減らせます。また ALL_PROXY は「全部ここ」としたいときの便法ですが、社内サイトを直結させるならむしろ NO_PROXY とセットで設計することが重要です。代表例:

set HTTP_PROXY=http://127.0.0.1:7890
set HTTPS_PROXY=http://127.0.0.1:7890
set ALL_PROXY=http://127.0.0.1:7890
set http_proxy=http://127.0.0.1:7890
set https_proxy=http://127.0.0.1:7890
set NO_PROXY=localhost,127.0.0.1,::1
set no_proxy=localhost,127.0.0.1,::1

ポート番号はご自身の mixed-port に置き換えてください。socks5h://127.0.0.1:7890 のような指定を試すときは、そのクライアントが当該スキームを受けられるか確認します。大抵の mixed は HTTP と SOCKS が同居するので、HTTPS クローンだけを済ませるなら最初は http:// で構いません。

PowerShell での設定(現在のセッションと永続化)

現在のウィンドウにだけ適用したいときは、次のように $env: プレフィックスで環境変数を書き換えられます。; で連結して一行でも構いません。

$proxy = "http://127.0.0.1:7890"
$env:HTTP_PROXY = $proxy
$env:HTTPS_PROXY = $proxy
$env:ALL_PROXY = $proxy
$env:http_proxy = $proxy
$env:https_proxy = $proxy
$env:NO_PROXY = "localhost,127.0.0.1,::1"
$env:no_proxy = $env:NO_PROXY

ユーザープロファイルへの永続化には [Environment]::SetEnvironmentVariable や設定アプリでのユーザー環境変数登録があります。setx で CMD 由来の永続値を書く方法も広く流通していますが、新しく開いたターミナルから有効になる点と、値の長さ制限への注意があります。開発用と普段の生活用で分けたい場合は、この記事だけのときだけ起動する専用 PowerShell プロファイルに関数としてまとめると安全です。

CMD と Git Bash

CMD は前掲の set VAR=value で同一セッションにだけ反映されます。setx を使えばユーザー環境に残せますが、既存ウィンドウは閉じるまで古い環境が残りますので、自動化では「セットしたあと新しいウィンドルを開いて検証」を習慣にしてください。

Git Bash(MinGW 系)は、Unix 様式のexport が使えるため、POSIX に近い手順になります。http_proxyHTTPS_PROXY の両系統を両方セットしておくと、クロスプラットフォームのスクリプトを置くときにも事故が減ります。Git が入っているパスとは独立して環境変数は見えるので、まずcurl -I https://example.com など単純な HTTPS で疎通確認してから git に進むと切り分けが速いです。

Git プロキシ:環境変数と git config の優先順位

Git for Windows は通常、環境変数を尊重しつつ、明示的な git config http.proxy が優先される場面があります。検証するときには次の順が安全です:git config --global --unset http.proxyhttps.proxy をいったん外して環境変数だけで試し、問題なければ永続値として設定に焼く。あるいは逆に環境変数より Git だけ固定したいときはコンフィグに明示する運用でも構いません。

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

[email protected]:... 形式の SSH クローンはこの設定とは別レイヤーです。GIT_SSH_COMMAND 経由でのラッパや、SSH の ProxyCommand、あるいは HTTPS に切り替える、といった設計になります。この稿では前述の環境変数と HTTP(S) のプロキシに絞って説明しました。

開発者ツールチェーン一式の構成例についてはCursor と GitHub の稿も参考にできます。

curl について:curl.exe と PowerShell のエイリアス

PowerShell において curl は歴史的に Invoke-WebRequest のエイリアスになっている環境があります。実体のcurl バイナリを叩きたいときは明示的にcurl.exeと打つか、フルパスを確認すると混乱が減ります。接続ログを詳しく見るには curl -v が有効です。プロキシを環境変数で渡すか、一時的に -x http://127.0.0.1:7890 のように明示するかは好みですが、まず環境変数がそのシェルに見えているかを Get-ChildItem Env:HTTP* などで確認してから試すと早いです。

NO_PROXY と社内向けサイト

イントラネットの GitLab や npm 私有レジストリへはプロキシを通さないほうが速いことが多く、コンマ区切りでホスト名や IP を NO_PROXY に列挙します。PowerShell と CMD で値の引き継ぎ規則が微妙に異なるため、セットしたセッションで実際に curlgit の両方を叩いて確認してください。環境による取りこぼしが疑われるときは、そのセッション専用のラッパ スクリプトに絞って export すると切り分けがしやすくなります。

タイムアウトと接続拒否の切り分け

接続タイムアウトが続くときは、(1) Clash が起動済みであること、(2) ポートが mixed と一致すること、(3) そもそもそのプロセスが環境変数を読んでいること、を再確認してください。接続が拒否されている場合は、別プロセスがポートを掴んでいないかや、Listen が 127.0.0.1 以外を要求していないか、Windows Defender Firewall の許可リストにコンソールの実行ファイルが載っていないかを疑います。クライアント側のログに SYN が着ていなければ、まずローカルの待受側に問題があると決めつけられます。

名前解決でコケている場合

HTTPS で TLS まで進まず名前解決で止まるときは DNS の問題である可能性があります。Clash が提供する名前解決(fake-ip と redir-host)の読みかたは複雑なので、ひとまず「プロキスの URL とポートは張れているか」を本文の順で確認し、必要なら Windows でのクライアント設定と DNS を合わせ直すのが第二段になります。

まとめ

Windows でブラウザは快適でもターミナルだけ遅い場合、根本原因はほぼコンソールにプロキシ情報が伝わっていないか、伝わっているがGit 側の設定や別ポートと矛盾しているかのどちらかに集約されます。環境変数を大文字・小文字両方で揃え、HTTPS_PROXY を明示し、必要なら NO_PROXY で内向きを除外する――この三本柱を一度通せば再現実験は短時間で済みます。また、Subsystem との棲み分けとして WSL のみを触る場合はリンク先の WSL 稿へ回すと視点が整理できます。

クライアントの入手経路や各 OS 向けの入口はダウンロードページで案内しています。GitHub でソースコードを参照する場合も、実行ファイルそのものは配布元を取り間違えやすいため、サイト側で整理したリンクから入る運用が安全です。構成が読めてきたら、→ Clash を無料ダウンロードし、環境変数経由でもう一度 git と curl を試すところから進めてみてください。