なぜ Windows では通るのに WSL2 だけ詰まるのか
WSL2 は軽量 VM に近い独自の Linux ネットワーク名前空間を持ちます。シェルから見た 127.0.0.1 はその Linux 側のループバックであり、Windows 上で 127.0.0.1:7890 に待っている Clash とは別物です。ブラウザが Windows の「システムプロキシ」や TUN に乗っているときでも、WSL 内の curl/apt/git はデフォルトでそこに乗らず、多くは環境変数かツール固有の設定だけを見ます。
したがって「Windows の Clash は動いているはず」という前提のまま WSL で http://127.0.0.1:7890 を指定しても、多くの場合接続拒否かタイムアウトになります。正しくは、WSL から到達できる Windows ホスト側の IP アドレス(多くは仮想スイッチ上のアドレス)と、Clash が実際に LISTEN しているポートを組み合わせます。
Windows ホスト IP の取り方(resolv.conf と既定ルート)
代表的な方法は次の二系統です。どちらも「WSL がパケットを Windows に送るときの次ホップ」を読み取っています。
/etc/resolv.confのnameserver:WSL が自動生成する場合、最初の nameserver が Windows ホストを指していることが多いです(環境や WSL バージョンで変わり得るため、値はその場で確認してください)。- 既定ルートのゲートウェイ:
ip route show defaultの出力にあるviaのアドレスが、しばしば同じホスト IP と一致します。
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-lan・bind-address
WSL から Windows の Clash へ入る接続は、Windows から見ると「ループバックではなく別インターフェース越し」です。そのため、Clash の待受が 127.0.0.1 のみだと、ホスト IP へ向けても届かないことがあります。実務では次のいずれかが必要になります。
allow-lan: true(GUI では「LAN からの接続を許可」系)と、bind-address: '*'もしくは0.0.0.0相当の待受。- クライアントが「待受アドレス」を細かく選べる場合は、WSL の仮想スイッチ側に届くアドレスへのバインド。
mixed-port: 7890
allow-lan: true
bind-address: '*'
bind-address を広げると同一 LAN の他端末からも届き得るため、開発用マシンと不可信ネットワークを分け、必要なら Windows Defender ファイアウォールでポートを絞ります。LAN 共有全般は LAN 共有とファイアウォール の観点とも通じます。
allow-lan を戻し、待受をローカルのみに戻すのが安全です。
WSL 内の環境変数(HTTP/SOCKS・NO_PROXY)
ホスト IP を WIN_HOST に入れたうえで、代表的な export は次のとおりです。socks5h:// は名前解決をプロキシ側に寄せる指定です(split DNS や社内ゾーンと衝突する場合は HTTP 側に寄せ、NO_PROXY を厚くする方が安定することがあります)。
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」を切り替えられるようにしておくと運用が楽です。
apt・Git・DNS(fake-ip とのすれ違い)
APT は Acquire::http::Proxy など /etc/apt/apt.conf.d/ 下の設定を読みます。環境変数だけでは拾わないケースがあるため、長期利用では snippet を置く方法が確実です。
# /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/";
Git は git 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 が落ちる
- すぐ接続拒否:ポート違い、Clash 未起動、
bind-addressがループバックのみ、ファイアウォール、別プロセスがポート占有。 - タイムアウト:
WIN_HOSTの取り違え、IPv6 経路、上流ノード到達性。ログで TCP 確立の有無を先に見る。 - TLS/証明書エラー:プロキシループ、MITM と衝突、SNI が意図せず変わるケース。TLS とログ の整理に戻る。
- ルールに乗らない:環境変数は効いているがポリシーが DIRECT のまま、など。ルール分流 の順序と接続ログのドメイン表示を照合。
まとめと関連記事
WSL2 では 127.0.0.1 が Windows の Clash を指さないのが正常挙動です。ホスト IP(/etc/resolv.conf や既定ルート)と mixed-port を揃え、Clash が WSL からの接続を受け付ける待受(allow-lan と bind-address)になっているかを確認します。そのうえで HTTP_PROXY/HTTPS_PROXY/ALL_PROXY と NO_PROXY、必要なら apt と Git の個別設定、DNS と fake-ip の整合、ファイアウォールまでを一列に並べると、Windows だけ「快適なのに Linux シェルだけ詰まる」状態から抜けやすくなります。
汎用の環境変数テンプレと Docker 向けの書き分けは Docker/CLI と mixed-port、Windows 11 での初回セットは Clash Verge Rev、Linux 単体で TUN を載せる話は Ubuntu+TUN を参照してください。
→ Clash を無料ダウンロードし、待受ポートと LAN 許可、接続ログを同じ画面から扱えるクライアントで、WSL からの疎通を確認してください。