🌊

WSLのミラーモードを使おう!

2024/08/06に公開

はじめに

8/1から転職して、新しく開発環境をセットアップをしてました。
WSLを構築している人が全然いなくてハマりまくった内容を記載します。
ミラーモードに関しては検索しても最新の情報が上がってこないので、環境構築で困っている誰かのために書き残します。

結論

# .wslconfigに書く
[wsl2]
networkingMode=mirrored

ローカルでSSL通信するための名前解決に関しては、ミラーモードを使えば従来のポートフォワーディング設定もいらないし、docker desktopの連携も問題ない!!
ガンガン使おう!

あらすじ

ローカルでSSL通信するためにmkcertを使って設定をしていた。
基本的に周りはmacOSでの開発でWSL使って日々開発している人は少数であった。
今回、READMEに書いてある手順通りにセットアップしていると、ネットワーク周りで上手くいかず詰まっていた。
結論で書いた通り、networkingModeをmirroredにしたところすべてが解決した。

従来のNAT

defaultの networkingMode=NAT である。
https://learn.microsoft.com/ja-jp/windows/wsl/networking#default-networking-mode-nat

今までは普通にlocalhostで確認していたので設定はしていなかった。

今回はSSL通信をするために https://a.test:80000 のように書いて、WSLにアクセスする必要がある。

手順書にはLANからのアクセス方法が書いてあった。
https://learn.microsoft.com/ja-jp/windows/wsl/networking#accessing-a-wsl-2-distribution-from-your-local-area-network-lan

WindowsのPowerShellから

netsh interface portproxy add v4tov4 listenport=80000 listenaddress=0.0.0.0 connectport=80000 connectaddress=(wsl hostname -I)

上記のように書き、
C:\Windows\System32\drivers\etc\hosts

上記のファイルを管理者権限で下記のように追記するとできるとあった。

127.0.0.1 a.test

これで https://a.test:80000 でWindowsのブラウザからアクセスするとdocker desktopのnginxからWSLのサーバーたちにアクセスできるとあった。

合わせて、DNSトンネリングに関してもtrueにして設定するとあった。

[wsl2]
dnsTunneling=true

https://learn.microsoft.com/ja-jp/windows/wsl/networking#dns-tunneling

実際起きた不都合

名前が解決されない

まず、hostsに書いたドメインにアクセスしてもサーバーが見つからない。
ping a.testをすると127.0.0.1を指しているが、ブラウザでアクセスすると
err_connection_refusedだったりerr_connecion_resetになり謎が多かった。

そこで、hostsを下記のように追加

127.0.0.1 a.test
::1 a.test

ipv6のlocalhostを指定すると、繫がる!!やった!!完了だ!!

クライアントからバックエンドのapi通信ができない

追加で、バックエンド通信用のドメインを追記しました。

127.0.0.1 a.test
::1 a.test
127.0.0.1 b.test
::1 b.test

そしてポートフォワーディングも追加

netsh interface portproxy add v4tov4 listenport=80001 listenaddress=0.0.0.0 connectport=80001 connectaddress=(wsl hostname -I)

これで https://b.test:80001 に接続できる!!
と思いきや、err_connection_refused ...
特に、docker composeで立ち上げているサーバーから https://b.test を叩いている部分がrefusedで詰む。

検証したこと

IPv6が優先的に使われている?IPv4を優先すれば直るかな?

そもそもhostsに127.0.0.1 a.testって書いているのに接続できなくて::1 a.testだと接続できるので早々に思ったこと。
https://bizlog.tech/windows-ipv4-priority/
上記を参考にIPv4を優先にしてみた。

結果: 特に変わらず

IPv6をIPv4にポートフォワーディングすればいける?

netsh interface portproxy add v4tov4 listenport=80001 listenaddress=0.0.0.0 connectport=80001 connectaddress=(wsl hostname -I)

上記のように追加するので、

netsh interface portproxy add v6tov4 listenport=80001 listenaddress=::1 connectport=80001 connectaddress=(wsl hostname -I)

って書けばIPv6でリクエストしたのをIPv4に変換してWSLに通信するかな~?って思った。

結果: 特に変わらず

最終的に

https://learn.microsoft.com/ja-jp/windows/wsl/networking
上記を眺めてたときに見かけた記載

ミラー モードのネットワーク
Windows 11 22H2 以降を実行しているマシンでは、ミラー モードのネットワークを有効にするため> に、.wslconfig ファイルの [wsl2] の下に networkingMode=mirrored を設定できます。 これを> 有効にすると、新しいネットワーク機能を追加し、互換性を改善するために、Windows 上にあるネットワーク インターフェイスを Linux に "ミラーリング" することを目標とする、まったく新しいネットワーク アーキテクチャに WSL が変更されます。

このモードを有効にするための現在の利点を次に示します。

  • IPv6 サポート
  • localhost アドレス 127.0.0.1 を使用して Linux 内から Windows サーバーに接続する。 > > - IPv6 localhost アドレス ::1 はサポートされていません
  • VPN のネットワーク互換性の向上
  • マルチキャストのサポート
  • ローカル エリア ネットワーク (LAN) から WSL に直接接続する

この新しいモードは、NAT (ネットワーク アドレス変換) ベースのアーキテクチャの使用に関して見られるネットワークの問題に対処します。

上記から

まったく新しいネットワーク アーキテクチャに WSL が変更されます。

ローカル エリア ネットワーク (LAN) から WSL に直接接続する

この新しいモードは、NAT (ネットワーク アドレス変換) ベースのアーキテクチャの使用に関して見られるネットワークの問題に対処します。

このへんの記述で、なんかミラーモードが解決しそうな予感がした。

WSL ミラーモード で調べると

こんな感じで、QiitaZenn

では、まだミラーモードが動作不安で、特にDockerコンテナへのアクセスがうまくいかないという不都合があったようである。

https://qiita.com/shigeokamoto/items/fc9fa1a395f3fd72fafa

ただ上記、Qiita記事で言及があったが

Docker Desktopはこの不都合に対応をしたようです。
https://docs.docker.com/desktop/release-notes/#for-windows-18

Added support for WSL mirrored mode networking (requires WSL v2.0.4 and up).

懸念であるDocker連携は無事解決したようなので、ミラーモードを使ったほうがいいのかな?と思っています。

NATモードでの挙動が全然わからず、ミラーモードですべて解決したような形でした。

さいごに

DNSトンネリング設定はいつの間にかdefaultがtrueになっていました。
https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config#main-wsl-settings

ミラーモードに関しては試験的ラベルである[experimental]ではなく[wsl2]ラベルで設定するので正式リリースされているという認識です。

自分みたいなローカルでSSL通信をするためにホスト名の設定をしたときにWSLでネットワーク周りでうまくいかなかった人はミラーモードを試してみてください!

Discussion