なぜ Windows では通るのに WSL2 だけ詰まるのか

WSL2 は軽量 VM に近い独自の Linux ネットワーク名前空間を持ちます。シェルから見た 127.0.0.1その Linux 側のループバックであり、Windows 上で 127.0.0.1:7890 に待っている Clash とは別物です。ブラウザが Windows の「システムプロキシ」や TUN に乗っているときでも、WSL 内の curlaptgit はデフォルトでそこに乗らず、多くは環境変数かツール固有の設定だけを見ます。

したがって「Windows の Clash は動いているはず」という前提のまま WSL で http://127.0.0.1:7890 を指定しても、多くの場合接続拒否かタイムアウトになります。正しくは、WSL から到達できる Windows ホスト側の IP アドレス(多くは仮想スイッチ上のアドレス)と、Clash が実際に LISTEN しているポートを組み合わせます。

用語:本稿の「ホスト」は Windows、「ゲスト」は WSL2 内の Linux を指します。mixed-port は HTTP プロキシと SOCKS5 を同一 TCP ポートで扱う典型的な構成です(クライアントの表記は「混合ポート」など)。

Windows ホスト IP の取り方(resolv.conf と既定ルート)

代表的な方法は次の二系統です。どちらも「WSL がパケットを Windows に送るときの次ホップ」を読み取っています。

WSL 内でホスト IP を変数に入れる例(bash)
export WIN_HOST="$(awk '/^nameserver/{print $2; exit}' /etc/resolv.conf)"
echo "$WIN_HOST"

別の切り口として grep -m1 nameserver /etc/resolv.conf | awk '{print $2}' でも同様です。取得した IP に対し、WSL から curl -v --connect-timeout 3 "http://${WIN_HOST}:7890" のように生の TCP 到達を先に確認すると、プロキシ設定以前の層切り分けがしやすくなります(7890 は実際の mixed-port に置き換え)。

/etc/resolv.conf を独自に固定したい場合は、Microsoft ドキュメントに沿って /etc/wsl.conf[network] generateResolvConf = false などの話になり、DNS 設計ごとセットで検討する必要があります。Clash 側で fake-ip や独自 DNS を使っている場合は、Clash Meta DNS の整理 と合わせて読むと、WSL から見た名前解決の期待値が揃いやすいです。

Clash 側:mixed-port・allow-lanbind-address

WSL から Windows の Clash へ入る接続は、Windows から見ると「ループバックではなく別インターフェース越し」です。そのため、Clash の待受が 127.0.0.1 のみだと、ホスト IP へ向けても届かないことがあります。実務では次のいずれかが必要になります。

Illustrative YAML(コア版に合わせて調整)
mixed-port: 7890
allow-lan: true
bind-address: '*'

bind-address を広げると同一 LAN の他端末からも届き得るため、開発用マシンと不可信ネットワークを分け、必要なら Windows Defender ファイアウォールでポートを絞ります。LAN 共有全般は LAN 共有とファイアウォール の観点とも通じます。

セキュリティ:プロキシ入站を LAN に開けるのは信頼できる環境に限定してください。不要なら検証後に allow-lan を戻し、待受をローカルのみに戻すのが安全です。

WSL 内の環境変数(HTTP/SOCKS・NO_PROXY

ホスト IP を WIN_HOST に入れたうえで、代表的な export は次のとおりです。socks5h://名前解決をプロキシ側に寄せる指定です(split DNS や社内ゾーンと衝突する場合は HTTP 側に寄せ、NO_PROXY を厚くする方が安定することがあります)。

Shell — WIN_HOST は上段の手順で設定済みとする
export HTTP_PROXY="http://${WIN_HOST}:7890"
export HTTPS_PROXY="http://${WIN_HOST}:7890"
export ALL_PROXY="socks5h://${WIN_HOST}:7890"
export http_proxy="$HTTP_PROXY" https_proxy="$HTTPS_PROXY" all_proxy="$ALL_PROXY"
export NO_PROXY="localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
export no_proxy="$NO_PROXY"

NO_PROXY は環境に合わせて編集してください。社内 Git やプライベートレジストリを誤ってプロキシに流すと遅延や証明書エラーだけが目立つことがあります。恒常化するなら ~/.bashrc~/.profile に関数化し、「プロキシ ON/OFF」を切り替えられるようにしておくと運用が楽です。

aptGitDNS(fake-ip とのすれ違い)

APTAcquire::http::Proxy など /etc/apt/apt.conf.d/ 下の設定を読みます。環境変数だけでは拾わないケースがあるため、長期利用では snippet を置く方法が確実です。

apt プロキシ設定の例(管理者権限で作成・IP は実測値に置換)
# /etc/apt/apt.conf.d/95proxy (例:172.22.240.1 は ip route / resolv.conf で得たホスト IP)
Acquire::http::Proxy  "http://172.22.240.1:7890/";
Acquire::https::Proxy "http://172.22.240.1:7890/";

Gitgit config --global http.proxy http://172.22.240.1:7890 のように、実測したホスト IP を直書きする手もあります(IP とポートは環境に合わせる)。SSH リモート([email protected]:)は HTTP プロキシと別経路のため、HTTPS リモートへ寄せるか ProxyCommand を別途設計してください。

DNS では次のようなすれ違いが起きがちです。Clash が fake-ip を返す一方で、WSL 側のスタブリゾルバがその IP を「本物のグローバルアドレス」と誤解し、curl が奇妙な挙動をする、などです。症状が名前解決周りに偏るときは、Clash の DNS モードと dns.fake-ip-range、および WSL が参照している nameserver をログとセットで確認します。層別の考え方は 接続ログの timeout/TLS 記事 とも補完関係です。

Windows ファイアウォールと IPv6 の落とし穴

Clash 側の設定が正しくても、受信を Windows ファイアウォールがブロックしていると WSL からは常に拒否されます。該当実行ファイル(またはサービス)に対するプライベートプロファイルの許可ルールを追加するのが一般的です。Hyper-V/WSL の仮想アダプタまわりは環境差が大きいので、「WSL サブネットからの TCP 7890 をこのプロセスに許可」といった形で範囲を絞れるとよいです。

また、ツールやリポジトリが IPv6 を優先し、プロキシや NO_PROXY の設計が IPv4 だけだと、期待した経路に乗らないことがあります。curl -4 で挙動差を見る、あるいは Clash 側のルールと整合させる、といった切り分けが有効です。

切り分け:接続拒否・名前は通るが TLS が落ちる

まとめと関連記事

WSL2 では 127.0.0.1 が Windows の Clash を指さないのが正常挙動です。ホスト IP/etc/resolv.conf や既定ルート)と mixed-port を揃え、Clash が WSL からの接続を受け付ける待受allow-lanbind-address)になっているかを確認します。そのうえで HTTP_PROXYHTTPS_PROXYALL_PROXYNO_PROXY、必要なら aptGit の個別設定、DNS と fake-ip の整合、ファイアウォールまでを一列に並べると、Windows だけ「快適なのに Linux シェルだけ詰まる」状態から抜けやすくなります。

汎用の環境変数テンプレと Docker 向けの書き分けは Docker/CLI と mixed-port、Windows 11 での初回セットは Clash Verge Rev、Linux 単体で TUN を載せる話は Ubuntu+TUN を参照してください。

Clash を無料ダウンロードし、待受ポートと LAN 許可、接続ログを同じ画面から扱えるクライアントで、WSL からの疎通を確認してください。