こんなとき読む記事:症状の整理

Windows 11Windows 10 のホストで ClashClash Verge RevClash for Windows 系、Mihomo コアを使うクライアントなど)を起動し、Edge や Chrome では期待どおりプロキシ経由になっているのに、WSL2Ubuntu などのシェルで curlsudo apt updategit clone を叩くと国内回線のままに見えたり、逆に接続は張れるのに名前解決だけ妙だったりする──という組み合わせは、開発者コミュニティでも頻出の相談です。

本記事では、Clash WSL2 プロキシを「ホスト上のリスナーへ橋渡しする」観点で手順化します。ポイントは二つあります。第一に、WSL2 の Linux は別のネットワーク名前空間におり、Windows が書き込むシステムプロキシをシェルが自動では引き継がないこと。第二に、Linux 側から見た 127.0.0.1ゲスト自身のループバックであり、ホストで待ち受けている Clash のポートとは一致しないことです。関連トピックは ブログ一覧 からも辿れます。

ℹ️
用語:本記事の「代理ブリッジ」とは、WSL2 から Windows ホストの LAN 側 IPClash が開いているポート(多くの場合 mixed-port や HTTP 用ポート)へ明示的に向けてトラフィックを流す構成を指します。DNS 同期とは、Clash の Fake-IPsystemd-resolved と、WSL が参照する名前解決の経路が食い違わないよう揃える作業のイメージです。

なぜ WSL2 は「Windows の Clash」を勝手に使わないのか

ブラウザは、Windows が提示するプロキシ設定(あるいは拡張機能)に従いやすい一方、WSL2 内の bashzsh から起動する curl は、基本的に親シェルにエクスポートされた環境変数やツール独自の設定しか見ません。そのため「Edge は通るのに WSL の curl だけ直結」は、ミスというよりレイヤの取り違いとして起きやすいです。

さらに、Windows 側のドキュメントに「プロキシは 127.0.0.1:7890」と書いてあっても、WSL2 のシェルで同じ文字列をそのまま使うと、Linux ゲスト自身の 7890 番を指します。ホストの Clash に届けるには、ホストの IP アドレス(仮想スイッチ越しに届くアドレス)を挟む必要があります。Windows 11 のブラウザと UWP 周りの整理は Windows 11 システムプロキシの記事 と補完的に読むと、ホスト側の挙動イメージが揃いやすいです。

前提チェック:Clash が「ホストの LAN」から届くか

まず Clash の GUI または設定で、Allow LAN(LAN からの接続を許可)相当の項目がオンか、bind-address0.0.0.0 側に寄っているかを確認してください。127.0.0.1 のみにバインドしていると、WSL2 からはどれだけ正しい IP を推定しても接続拒否になりがちです。

次に、Windows Defender ファイアウォールが、Clash の実行ファイルや該当ポートへのプライベートネットワークからの着信をブロックしていないかを見ます。企業端末ではポリシーで塞がれていることもあるため、その場合は情報システムの手順に従ってください。ポート競合で起動できない症状は ポート占有の切り分け記事 が近いテーマです。

ステップ 1:WSL2 から Windows ホストの IP を取る

代表的な方法は二つあります。一つは、既定ゲートウェイとして見えているアドレスを読む方法です。多くの WSL2 環境では、仮想スイッチ側の Windows ホストがゲートウェイとして現れます。

ip route show | awk '/^default/ { print $3; exit }'

もう一つは、自動生成される /etc/resolv.conf に書かれている nameserver を参照する方法です。WSL が DNS フォワーディング用にホストを指している構成では、この値がそのままホスト側の内部アドレスになることが多いです。どちらも実際の数値は環境で変わるため、コピペしたら必ず手元で確認してください。

grep -m1 '^nameserver' /etc/resolv.conf | awk '{ print $2 }'

取得した IP を変数に入れておくと、以降の export が楽です。例として HOST_IP という名前を使います。

HOST_IP=$(ip route show | awk '/^default/ { print $3; exit }')
echo "$HOST_IP"

ステップ 2:curl でホストのポートに届くか試す

Clash の mixed-port または HTTP プロキシが 7890 だと仮定します(手元のポートに置き換えてください)。まずはプロキシを経由せず、ホスト IP のポートが開いているかを見ます。

curl -v --max-time 5 "http://${HOST_IP}:7890" || true

ここでタイムアウトや接続拒否が続く場合は、Allow LAN/バインドアドレス/ファイアウォールのどれかがまだ噛み合っていません。逆に、HTTP エラーやプロキシ特有の応答が返るなら、少なくともレイヤ 4 の到達はできています。次に、明示的にプロキシを指定して外向き HTTPS を試します。

curl -I --max-time 15 -x "http://${HOST_IP}:7890" https://www.google.com

このとき Clash の接続ログに該当フローが出るかを見ると、WSL2 からホスト経由で出口ノードに乗っているかが判断しやすいです。

ステップ 3:シェルに http_proxy 系を載せる

検証が通ったら、同じセッションで環境変数を揃えます。大文字・小文字の両方を揃えるのは、ツールによって参照名が異なるためです。

export http_proxy="http://${HOST_IP}:7890"
export https_proxy="http://${HOST_IP}:7890"
export HTTP_PROXY="$http_proxy"
export HTTPS_PROXY="$https_proxy"
export all_proxy="socks5://${HOST_IP}:7891"
export ALL_PROXY="$all_proxy"

7891 側の SOCKS は例です。SOCKS を公開していない構成なら、HTTP だけに絞って問題ありません。恒久的に使う場合は ~/.bashrc~/.zshrc に追記しますが、常時プロキシは社内イントラやローカル開発サーバへの接続まで巻き込むことがあるため、用途別に source する小さなスクリプトへ分ける運用も現実的です。

ヒント:WSL を再起動すると HOST_IP が変わることがあります。起動のたびにゲートウェイを取り直すワンライナーを .profile に置くか、systemd ユーザユニットでエクスポートする方法もあります。Ubuntu 22.04 以降で WSL の systemd を有効にするには /etc/wsl.conf[boot]systemd=true が必要になる点に注意してください。

ステップ 4:apt がプロキシを読むようにする

sudo を付けると環境変数が引き継がれないことがあります。sudo -E で保持するか、/etc/apt/apt.conf.dAcquire::http::Proxy を書く方法があります。後者はファイル権限に注意し、組織ポリシーに反しないか確認してください。

sudo tee /etc/apt/apt.conf.d/95proxy <<'EOF'
Acquire::http::Proxy "http://YOUR_HOST_IP:7890/";
Acquire::https::Proxy "http://YOUR_HOST_IP:7890/";
EOF

プレースホルダは実際の IP に置き換えてください。apt update 後に Clash ログへリポジトリのホスト名が流れるかを見ると、期待どおりプロキシ経由になっているかが分かります。

ステップ 5:git の HTTPS と SSH

HTTPS URL での git clone は、上記の http_proxy をエクスポートしたシェルから実行すれば多くの場合プロキシを通ります。一方で、git config --global http.proxy に古い値が残っているとそちらが優先されることがあるため、不要なら削除してください。

SSH[email protected]:)は HTTPS プロキシの外側です。~/.ssh/configProxyCommand を組む必要があり、本記事の環境変数だけでは完結しません。まずは HTTPS 越しの取得で経路を固めるのが手早いです。

ステップ 6:DNS を Clash のモードと揃える

プロキシは通っているのに、特定ドメインだけ名前解決が妙になる場合は、Clash 側の DNS 設定と WSL が使うリゾルバの組み合わせを疑います。Fake-IP を有効にしていると、ブラウザや一部アプリとは挙動差が出やすいです。設定の考え方と検証の型は Fake-IP と DNS の解説記事 にまとめています。

WSL2 では /etc/wsl.conf[network]generateResolvConf を切り替える運用例もありますが、誤ると名前解決が全滅するため、変更前にバックアップとロールバック手順を用意してください。IPv6 の経路が別立てになっているケースもあるので、切り分けのときは curl -4curl -6 を意識すると早いです。

ステップ 7:環境変数でも取りこぼすときは TUN を検討

一部のツールは独自の DNS 解決やプロキシ非対応のソケットを使い、HTTP プロキシ環境変数では取りこぼします。その場合は、Windows 側で TUN モードを有効にし、より下位のレイヤでトラフィックを取り込む選択肢があります。概要と注意点は TUN モード解説記事 を参照してください。WSL2 と TUN の組み合わせはビルドやミラードネットワーク設定の影響を受けやすいため、変更は小さなステップで進めるのが安全です。

まとめ:ホスト IP と環境変数が「WSL2 では必須の橋」

WSL2 が Clash を通らないように見える典型は、127.0.0.1 の取り違えと、システムプロキシをシェルが読まないことの二重奏です。まずホスト IP を実測し、Allow LAN とファイアウォールでポートが開いていることを curl で確認し、http_proxyhttps_proxy を載せたうえで aptgit を再検証する流れが再現性が高いです。名前解決が気になる段階では、Fake-IP や resolv.conf の生成ルールを別軸で揃えます。

クライアントの導入や更新は、画面の表記と手元のポートが一致しやすいよう、公式の配布物から揃えておくのがおすすめです。Windows 向けの入手先は ダウンロードページ から選べます。安定したビルドでログの見方に慣れておくと、本記事の手順とも噛み合わせやすくなります。

無料で Clash をダウンロードし、快適な接続体験を試す