なぜブラウザは通るのにターミナルだけ直結しやすいのか

macOS では、Clash 系クライアントが「システムプロキシを設定」する機能を持っていることが多く、Safari や Chrome などはその設定を参照して通信をプロキシへ流します。一方、ターミナルで動く curlgitnpm は、基本的に自分のプロセス環境に http_proxyhttps_proxy などが無ければ、システムの代理設定を自動では読みません(ツールやバージョンによって例外はありますが、再現性を取るなら環境変数で明示するのが安全です)。

また、SSH 越しの [email protected]: 形式は HTTPS プロキシの対象外です。HTTPS での clonefetch と、SSH の鍵認証は別経路なので、「プロキシを入れたのに Git だけ変わらない」場合はまず URL 形式を疑う価値があります。

初めてクライアント側のポートや購読を整える場合は、Clash Verge Rev の入門ガイドで待ち受けポートを確認してから本稿の変数に置き換えると迷いが減ります。

ステップ 0:Clash の HTTP/混在ポートを確認する

環境変数に書く URL は、実際に Clash が待ち受けているポートと一致している必要があります。多くのプリセットでは HTTP プロキシ127.0.0.1:7890SOCKS5127.0.0.1:7891 のように並んでいます。mixed-port(混在ポート)を有効にしている構成では、ひとつのポートで HTTP と SOCKS の両方を受け付けることもあり、その場合はダッシュボードや設定 YAML の mixed-port の値をそのまま使います。

ここで言う「実測」とは、ドキュメントの例を写すのではなく、今動いているプロファイルの数値を見て export 文に反映することです。ポートがずれていると、環境変数を入れても接続拒否やタイムアウトのままです。

コンテナや別マシンから同じ Mac の Clash に向ける話題は Docker Desktop と macOS Clash の記事host.docker.internal 側を扱っています。本稿はホスト上の Terminal.app/iTerm2に限定します。

ステップ 1:シェルに HTTP(S) プロキシを一括で渡す

まずは現在のシェルだけ有効な設定として、次のように export します(ポート 7890 はご利用環境に合わせて差し替えてください)。大文字・小文字の両方を揃えておくと、互換性のばらつきに強くなります。

export HTTP_PROXY="http://127.0.0.1:7890"
export HTTPS_PROXY="http://127.0.0.1:7890"
export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"

HTTPS トラフィックを HTTP プロキシに載せるのは一般的な「CONNECT トンネル」の形です。Clash 側がそのポートで HTTP プロキシとして応答していれば、curl https://... はこの HTTPS_PROXY を参照します。

ツールによっては ALL_PROXY だけを見る場合があります。SOCKS を直接指定する例は次のとおりです(ポートは SOCKS 側、多くの場合 7891)。

export ALL_PROXY="socks5://127.0.0.1:7891"
export all_proxy="socks5://127.0.0.1:7891"

混在ポートが 7890 で HTTP と SOCKS の両方を受け付けているなら、ALL_PROXY=socks5://127.0.0.1:7890 のように同じ番号に寄せるパターンもあります。どちらを選ぶかは、その端末で詰まっているコマンドが libcurl ベースか、Go 製 CLI かなどで挙動が変わるため、後述の検証で確かめます。

ステップ 2:NO_PROXY でローカルだけ外す

プロキシを常時有効にすると、社内の Git サーバーやローカルの localhost まで経由してしまい、逆に遅くなることがあります。NO_PROXY(および no_proxy)に除外リストを書いておくと運用が楽です。

export NO_PROXY="localhost,127.0.0.1,::1,*.local"
export no_proxy="localhost,127.0.0.1,::1,*.local"

チームでドメインのホワイトリストを共有し、必要な社内サフィックスをカンマ区切りで足していくのがおすすめです。広げすぎると本当にプロキシが要るホストまで直結して失敗します。狭すぎると開発用のローカル API がプロキシに吸われます。バランスはプロジェクトごとに調整してください。

ステップ 3:~/.zshrc または ~/.bash_profile に固定する

ターミナルを開くたびに設定したい場合は、上記の export 群を ~/.zshrc(デフォルトシェルが zsh の macOS)か、Bash を使うなら ~/.bash_profile に追記します。追記後は source ~/.zshrc で読み直すか、新しいタブを開いて反映を確認します。

「常時オンにしたくない」場合は、関数でオンオフを切り替える方法もあります。例えば proxy_onproxy_off のシェル関数にまとめ、必要なセッションだけ有効化する運用も実務ではよく見ます。セキュリティポリシー上、平文の環境変数に資格情報を載せないことは、企業利用では必須級の注意事項です。

ステップ 4:curl で到達性を確認する

設定が効いているかは、まず curl のヘッダ取得が手軽です。プロキシを経由すると、Clash のログに該当ドメインが現れるはずです。

curl -I https://www.google.com
curl -I https://registry.npmjs.org

-v を付けると接続先にプロキシが使われているかの手がかりが増えます。タイムアウトが続くときは、ポート番号、Clash のルールでそのドメインが期待するポリシーに乗っているか、DNS(fake-ip など)の影響を順に見ます。詳しい切り分けは トラブルシューティングガイドも参照してください。

なお curl は環境変数に加え --proxy オプションでも指定できます。変数が効いていない疑いがあるときは、curl --proxy http://127.0.0.1:7890 https://example.com のように一発試験すると、Clash 本体側の問題かシェル設定かを分離しやすくなります。

ステップ 5:git の HTTPS プロキシ(と SSH の切り分け)

Git は libcurl を使うため、HTTP_PROXYHTTPS_PROXY をエクスポートしていれば多くの場合 https:// リモートに対して効きます。併せて Git 独自の設定で上書きすることもできます。

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

後から無効にするときは git config --global --unset http.proxy などで削除します。リポジトリ単位でだけプロキシを使いたい場合は --global を外し、そのリポジトリ内で設定してください。

SSH URL のリモートはこの設定の対象外です。SSH をプロキシ越しにしたい場合は ~/.ssh/configProxyCommand など別の仕組みが必要になり、HTTPS 版の手順とは問題が分かれます。まずは「HTTPS なら通るか」を環境変数で確認し、SSH に切り替えるかどうかを決めると手戻りが減ります。

ステップ 6:npm.npmrc でレジストリ取得を安定させる

npm は環境変数を尊重する一方、npm config set proxy で永続化する運用もよく行われます。

npm config set proxy  http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890

設定値は npm config list で確認できます。モノレポや CI では .npmrc をリポジトリに置かない方がよい場合もあるため、個人マシンではユーザ直下の ~/.npmrc に限定する方法もあります。

npx や一部のパッケージは追加で HTTP_PROXY を読むことがあり、環境変数と npm config の両方が揃っているとつまずきにくいです。企業プロキシの認証が必要な環境では、資格情報を平文で書かず、承認された方法(OS のキーチェーン連携など)に従ってください。

補足:127.0.0.1 で足りないとき(LAN 待ち受け)

通常、同じ Mac 上のターミナルから 127.0.0.1 の Clash へ向かう分には追加設定は不要なことが多いです。一方、仮想化や特殊なネットワーク名前空間からホストのプロキシへ届ける場合は、Clash 側で Allow LAN を有効にし、待ち受けを LAN インターフェース側でも開く必要が出ます。考え方は LAN プロキシを有効化する手順と同じ系統です。コンテナからホストへ届ける具体例は前述の Docker 向け記事とセットで読むと整理しやすいです。

よくある落とし穴

HTTPS_PROXY だけ未設定

HTTP だけ通って HTTPS だけ失敗するパターンです。HTTPS_PROXY と小文字の https_proxy をセットで入れてください。

混在ポートと HTTP 専用ポートの取り違え

http://127.0.0.1:... を SOCKS ポートに向けたり、逆に SOCKS URL を HTTP ポートに向けたりすると接続できません。設定画面の実数値で揃えます。

Git が SSH のまま

環境変数をどれだけ整えても [email protected] は別経路です。HTTPS リモートに切り替えるか、SSH 用のプロキシ設定を別途用意します。

NO_PROXY の漏れ/過剰

意図しないホストがリストに入ると「プロキシを付けたのに直結で詰まる」逆パターンが起きます。チームでリストをレビューすると安全です。

まとめ

macOS で Clash を使っていても、ターミナルの CLI はシステム代理を自動継承しないことがある、というのが本題の核心です。HTTPS_PROXYALL_PROXYNO_PROXY をシェルに明示し、curl で到達性を確認したうえで gitnpm を試す——この順番なら、どこで詰まっているかを短時間で切り分けられます。ポート番号はプリセットの例ではなく、実行中の Clash 設定に合わせるのが実測のコツです。

GUI でルールやログを扱いやすいクライアントにしておくと、環境変数側は一度決めれば長く使い回せます。同種ツールと比較しても、ルールの見通しとコアの安定性のバランスでは Clash 系のスタックが扱いやすい部類に入ります。→ Clash を無料ダウンロードし、ターミナルとブラウザの両方で快適な経路設計をそろえる