WSL2 から Windows 上の Clash へトラフィックを通す:ミラー型ネットワークとポート転送で段階的に直す
Windows のブラウザでは Clash 越しに普通に開けるのに、WSL2 の Ubuntu ターミナルでは curl がタイムアウトし、apt update が遅い・失敗する、Docker の pull だけ詰まる——という切り分けは開発環境で非常によく出ます。原因の多くは「WSL2 とホストのネットワーク境界」と「127.0.0.1 が指す先の取り違え」にあります。本記事では、ミラー型ネットワーク(mirrored)の活用、従来どおりのホスト IP 経由、mixed ポートの LAN 公開、プロキシ環境変数、最後の手段としての Windows のポート転送(portproxy)まで、変数を一つずつ減らしながら揃える手順をまとめます。
なぜ「Windows だけ繋がる」のか
WSL2 の各ディストリビューションは、ざっくり言えば軽量 VM の背後にいる別の Linux ネットワーク名前空間です。したがって、WSL2 内の 127.0.0.1 は「その Linux 自身」のループバックであって、Windows ホスト上で Clash が待ち受けている 127.0.0.1とは一致しません。ブラウザは Windows 側で動いているのでシステムプロキシや TUN に乗りやすい一方、WSL2 のシェルは別マシンに近い感覚でホストのローカルポートを見に行く必要があります。
さらに、Clash の HTTP / SOCKS(多くの構成では mixed-port にまとまっている)が 127.0.0.1 のみにバインドされていると、WSL2 からはそもそも到達できません。Allow LAN(名称はクライアントによりますが「LAN からの接続を許可」系)を有効にし、実際に 0.0.0.0 側で待ち受けているかを確認するのが定石です。ここは 「LAN 越しの mixed-port」で掘り下げています。
先に決める二択
ミラー型ネットワークが使える Windows なら、localhost の相互到達やマルチキャスト周りが素直になりがちです。使えない・挙動が変なら、ホストの実 IP(デフォルトゲートウェイ)にプロキシを向ける古典ルートに落ち着かせます。
Windows 側:Clash の待受けを WSL2 から見える形に
まずホストで Clash が動いている前提を崩さないことが先決です。購読・モード・TUN の有無は 「Clash for Windows の完全設定」に沿って整えてください。WSL2 連携でよく詰まるのは次の二点です。
- mixed-port(または HTTP / SOCKS 各ポート)が LAN から届くか:ループバック限定のままだと WSL2 からは届きません。
- ファイアウォール:初回起動時にブロックされていないか。テスト中だけ一時的に許可ルールを足すこともありますが、運用では必要最小限に留めてください。
疎通確認は、WSL2 側から curl -I でプロキシ経由のヘッダ取得が取れるかを見るのが早いです。まだプロキシを設定していない段階なら、ホスト IP とポートが開いているかを nc や curl の接続エラー種別で切り分けます。
ミラー型ネットワーク(mirrored)で localhost を揃える
Windows 11 の新しめのビルドでは、WSL の networkingMode=mirrored(ミラー型)が選べます。ユーザーディレクトリの .wslconfig に次のようなブロックを書き、wsl --shutdown 後に WSL2 を再起動します(管理者権限のコマンドプロンプトや PowerShellで実行)。
# %UserProfile%\.wslconfig — illustrative; adjust to your Windows/WSL version
[wsl2]
networkingMode=mirrored
ミラー型が有効だと、WSL2 から Windows の localhost 上のサービスへアクセスしやすくなるケースが増えます。実際の挙動は Windows と WSL のバージョン組み合わせに依存するため、「有効化したら 127.0.0.1:ポート で繋がった/繋がらない」をその場で確認してください。繋がるなら、プロキシ URL は http://127.0.0.1:7890 のようにシンプルに書けることが多く、運用が楽です。
バージョンと互換性
ミラー型は「常に万能」ではありません。企業ポリシー、別製品の仮想スイッチ、古いカーネル更新の遅れと組み合わさると、期待どおりに動かないこともあります。そのときは次節のホスト IP 方式へ移行してください。
ホスト IP を取る:従来の WSL2 NAT 構成でも通す
ミラー型を使わない、または使えない場合、WSL2 から Windows へは「デフォルトルートのゲートウェイ」がホストを指すことが多いです。例として次のコマンドで確認します(環境により出力は異なります)。
ip route show | grep default
# example gateway might look like: default via 172.x.x.1 dev eth0
このゲートウェイ IP(例では 172.x.x.1)を WINDOWS_HOST のように環境変数へ入れ、プロキシを http://WINDOWS_HOST:7890 形式で参照するのが定番です。古い記事では /etc/resolv.conf の nameserver 行をホスト IP とみなす手法もありましたが、systemd-resolved や WSL の世代で中身が変わりやすいため、ルートテーブル側を優先して確認するほうが安全です。
DNS だけおかしい場合は、Clash 側の fake-ip と期待の食い違いも疑います。「接続中なのに繋がらない?DNS と fake-ip」と併読してください。
プロキシ環境変数:apt、curl、git、コンテナビルド
多くの CLI は http_proxy / https_proxy / all_proxy(小文字)と、大文字版の両方を読みます。no_proxy には社内レジストリやローカルホストを入れ、不要なトラフィックだけ直結させます。
# Example — replace host and port with yours
export HOST_IP=$(ip route | awk '/default/ {print $3; exit}')
export http_proxy="http://${HOST_IP}:7890"
export https_proxy="http://${HOST_IP}:7890"
export all_proxy="socks5://${HOST_IP}:7891"
export no_proxy="localhost,127.0.0.1,::1"
~/.bashrc や ~/.profile に書く前に、一度手元シェルでエクスポートして curl -I https://example.com が通るか試してください。apt は /etc/apt/apt.conf.d/ に Acquire::http::Proxy 等を置く方法もありますが、環境変数で十分な場合が多いです。
Docker はデーモンが別プロセスのため、シェルの環境変数だけでは pull に効かないことがあります。/etc/docker/daemon.json の proxies ブロックや、BuildKit 利用時のビルド引数など、レイヤーごとに設定場所が変わります。Docker 専題は 「Clash Meta と Docker Compose」の考え方と噛み合わせてください。
最後の手段:Windows で portproxy する
どうしても WSL2 からホストのプロキシポートに届かないが、Windows ローカルでは 127.0.0.1:7890 が生きている——というとき、管理者権限で netsh interface portproxy を使い、WSL のサブネット側から見えるインターフェイスへ転送する手法があります。環境固有の IP 範囲とインターフェイス名が絡むため、コピペ運用より自分の ipconfig / ip addr に合わせて一行ずつ検証するのが安全です。
# Run in elevated cmd or PowerShell — illustrative only
# netsh interface portproxy add v4tov4 listenaddress=WSL_SUBNET_GATE listenport=7890 connectaddress=127.0.0.1 connectport=7890
portproxy は管理者の保守と再起動後の持続性に注意してください。ミラー型やホスト IP 直指定で済むなら、そちらのほうがシンプルです。
症状早見表
| 症状 | まず疑うところ |
|---|---|
WSL の curl 127.0.0.1:7890 が即拒否 |
127 がホストを指していない/ミラー型未使用。ホスト IP か mirrored を検討。 |
| ホスト IP は通るが認証まわりで失敗 | プロキシの認証要否、Clash のログ、ルールでローカルがループしていないか。 |
| ブラウザは速いが apt だけ遅い | apt 用のプロキシ設定不足、IPv6 経路、DNS の取り違え。 |
| Docker pull だけ失敗 | デーモン側プロキシ未設定、または docker0 経路とホスト IP の組み合わせ。 |
チェックリスト
- Windows で Clash が動き、mixed 等のポートが LAN から到達可能か確認する。
- ミラー型を試せるなら
.wslconfigを設定し、wsl --shutdown後に挙動を再確認する。 - ミラー型なしならデフォルトゲートウェイからホスト IP を取り、環境変数でプロキシを張る。
curl・git・aptを個別に試し、Docker だけ別設定が要るか切り分ける。- それでも届かないときだけ portproxy やファイアウォール詳細を検討する。
まとめ
WSL2 と Clash の組み合わせは、「ホストでは動くのに Linux だけ動かない」という境界の問題として捉えると切り分けが速くなります。ミラー型で localhost を揃えられる環境なら設定が簡潔になり、そうでなければホスト IP と環境変数の古典パターンが堅実です。