なぜ WSL2 では「localhost の Clash」がそのまま使えないのか

WSL2 は軽量 VM に近いネットワーク境界を持ち、Linux ゲストと Windows ホストは別のネットワーク名前空間にいます。そのため、Windows 側で 127.0.0.1:7890 のように Clash が待ち受けていても、WSL2 の bash から同じアドレスを叩くとLinux 自身のループバックを指し、ホストの Clash には届きません。ここを理解せずに環境変数だけ真似すると「プロキシを設定したのに繋がらない」状態が長く続きがちです。

一方で、Microsoft 側の実装によりWindows ホストへ向かう専用の到達点は用意されており、多くの環境では /etc/resolv.conf に書かれた nameserver の IP(例:10.255.255.254172.x.x.1)がその役割を果たします。あるいは ip route show default の default via で得られるゲートウェイがホスト側を指す、という見方もできます。ディストリビューションや WSL の世代で値は変わるため、毎回コマンドで確認する癖を付けるのが安全です。

💡
本稿の前提 Windows 上で Clash/Mihomo 互換のクライアントが起動済みで、HTTP または SOCKS、あるいは mixed-port が有効であること。ネイティブ Ubuntu にコアだけ入れて運用する話題はLinux 向けの別稿と棲み分けています。

Clash 側のポート:mixed-port と従来の port/socks-port

設定ファイルでは、古いスタイルとして port(HTTP)と socks-port(SOCKS5)が並ぶ構成と、mixed-port で両プロトコルを同一ポートに束ねる構成が併存します。WSL2 から向ける URI は、実際にリッスンしている方に合わせます。例えば mixed-port が 7890 なら、HTTP プロキシとして http://HOST:7890、あるいはツールが SOCKS を選べるなら socks5h://HOST:7890 のように書きます(ホスト名部分は後述の HOST を実 IP や変数に置き換え)。

Git や curl、多くの CLI は ALL_PROXY または HTTPS_PROXY を解釈しますが、スキーム省略の HOST:PORT だけでは挙動が実装依存になることがあります。可能なら http:// または socks5h:// を明示し、DNS をプロキシ側で解決するか(socks5h)ローカルで解決するか(http:// と名前解決の組み合わせ)を意識すると、企業フィルタや split DNS の環境でも切り分けがしやすくなります。

Windows ホストの IP を確実に取る

定番は grep nameserver /etc/resolv.conf | awk '{print $2}' のように nameserver 行を抜き出す方法です。WSL2 の新しいネットワークモード(mirrored 等)では挙動が変わることがあるため、取得した IP に対して curl -v --connect-timeout 3 http://そのIP:PORT で疎通を確認してから環境変数に反映するとよいです。また、一時的に cat /etc/resolv.conf 全体を眺め、コメントで案内されている公式の取得手段があればそれに従うのが確実です。

シェルに定数を残すなら、export WIN_HOST=$(grep -m1 '^nameserver' /etc/resolv.conf | awk '{print $2}') のように変数化し、プロキシ URL を http://${WIN_HOST}:7890 と組み立てるとメンテナンスしやすいです。セッションをまたぐなら ~/.bashrc~/.zshrc に同様の行を置きますが、VPN や仮想アダプタの有無で nameserver が変わることもあるため、接続トラブル時はまず IP の取り直しを疑ってください。

allow-lan:WSL から届くパケットを Clash が受け取る

Windows の Clash が「ループバックのみ」で待っていると、ホスト IP 経由で来た WSL の SYN も拒否されます。クライアントの設定で Allow LAN 相当(設定キーは実装で allow-lan: true や UI トグル)を有効にし、バインドアドレスが 0.0.0.0 側に広がっているかを確認します。これはLAN 共有の記事で触れているトピックと根っこは同じで、いわゆる「同一マシン内の別インタフェースからの到達」を許可する話です。

Windows Defender ファイアウォールがブロックしているケースもあります。初回接続時に許可ダイアログが出たらプライベートプロファイルで許可する、あるいは一時的にルールを追加して疎通を確認してから絞り込む、といった順が現実的です。セキュリティと利便性のトレードオフは環境ポリシー次第なので、社用端末では IT ガイドラインに従ってください。

bash/zsh での環境変数:ALL_PROXY と小文字互換

多くのツールは http_proxyhttps_proxyall_proxy の小文字形も参照します。対話シェルで試すときの例を示します(ポートは自分の mixed-port に合わせて変更)。

export WIN_HOST=$(grep -m1 '^nameserver' /etc/resolv.conf | awk '{print $2}')
export HTTP_PROXY="http://${WIN_HOST}:7890"
export HTTPS_PROXY="http://${WIN_HOST}:7890"
export ALL_PROXY="http://${WIN_HOST}:7890"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
export NO_PROXY="localhost,127.0.0.1,::1"
export no_proxy="$NO_PROXY"

NO_PROXY に社内レジストリや直結したいドメインを足すかどうかは運用次第です。apt だけ直結させたい場合は、後述のように apt 側の設定を外す方が明確です。なお、環境変数を張りっぱなしにすると普段のブラウザ用シェルまで影響するため、別ターミナルで試すか、関数で on/off を切り替えると安全です。

apt をプロキシ経由にする(Acquire::http::Proxy)

apt は環境変数だけでは拾わないことがあるため、/etc/apt/apt.conf.d/95proxy のようなファイルで明示します。管理者権限が必要です。

Acquire::http::Proxy "http://10.255.255.254:7890/";
Acquire::https::Proxy "http://10.255.255.254:7890/";

上記の IP はあくまで例です。実際の WIN_HOST に置き換え、末尾のスラッシュの有無は組織内ミラーの URL 形式に合わせて調整してください。社内プロキシの上流にさらに Clash を置く二段構成では、apt が期待する認証ヘッダや例外リストが絡むため、その場合はミラー URL を国内直結にする方が安定することがあります。

git の http/https プロキシ

リポジトリ取得は次のようにグローバル設定できます。

git config --global http.proxy  "http://${WIN_HOST}:7890"
git config --global https.proxy "http://${WIN_HOST}:7890"

SSH([email protected]:...)はこの設定の対象外です。SSH を経路に含めたい場合は ~/.ssh/configProxyCommand で nc や connect 系を挟む、あるいは HTTPS クローンに切り替える、といった別設計になります。Windows 側の Clash で TUN を有効にし、かつ WSL のトラフィックまでホストで捕捉できている構成なら話は変わりますが、それはTUN モードの稿で扱うレイヤーです。本稿は明示プロキシとポート転送の理解に焦点を当てます。

curl での疎通確認と切り分け

環境変数を設定したあと、curl -I https://www.google.com などで応答コードを確認します。タイムアウトなら (1) WIN_HOST の誤り (2) Clash 未起動 (3) allow-lan 無効 (4) ポート番号の取り違え (5) ファイアウォール、の順が多いです。Clash のダッシュボードやログで接続が着ているかを見ると、WSL 側の問題か Windows 側の問題かがすぐ分かります。

IPv6 だけが有効な経路を試みているケースでは、プロキシ URL を IPv4 リテラルに固定すると安定することがあります。逆に企業網では IPv4 ブロック下で IPv6 直結が必要、という逆パターンもあり得ます。ここは実測がすべてです。

TUN 全捕捉と明示プロキシの棲み分け

Windows ホストで TUN を有効にすると、ホスト OS 上のアプリは楽になりますが、WSL2 のパケットまで自動でホストの TUN に吸い上げられるかは構成次第です。開発の現場では、まず明示プロキシで apt/git/curl を安定させ、必要なら TUN やミラード networking を検討する二段構えが扱いやすいです。Windows クライアントの初期設定の流れはClash Verge Rev の Windows 向けガイドも参照ください。

よくあるつまずき

Connection refused

ポートは合っているが接続拒否なら、Clash がループバック専用で待っている可能性が高いです。Allow LAN とバインドを確認し、実際に ss や Windows 側のリスニング一覧で 0.0.0.0:PORT になっているかを見ます。

タイムアウトばかり

WIN_HOST の取り違え、または会社のネットワークが透過プロキシを要求しているパターンです。別ネットワーク(テザリング等)で再現するかを試し、差分から原因を絞ります。

apt だけ失敗する

環境変数ではなく Acquire 設定が必要です。逆に、Acquire を直したのにまだ失敗する場合はリポジトリ URL が file スキームだったり、独自 CA を挟むミラーだったりするので、エラーメッセージ全文を読みます。

まとめと次の一歩

WSL2 から Windows の Clash を使うコツは、ループバックではなくホスト IP +正しいポートに向けること、そして LAN からの接続を Clash が受け入れる設定にある、と覚えておけば十分です。環境変数はシェルとツールの組み合わせごとに解釈が微妙に異なるため、ALL_PROXY を軸にしつつ apt だけは Acquire で明示する、git は http.proxy を別管理する、と役割を分けるとトラブル時の切り分けが速くなります。

Windows 側のクライアント選びや導入の入口は、当サイトのダウンロードページに整理してあります。オープンソースのソースコードや Issue を追う用途では各プロジェクトの GitHub も有用ですが、実行ファイルの第一入手先はサイト側の導線に寄せた方が、CPU アーキテクチャや更新チャネルの取り違えを減らせます。実際に WSL2 とホストの両方を触り比べると、仮想化された Linux とネイティブ Linux の差分が手に取るように分かるはずです。準備が整ったら、→ Clash を無料ダウンロードし、Windows 向けクライアントから試すところから進めてみてください。