WSLパッケージの2.0.0にていくつか機能追加が行われました。ここではネットワークに加えられたミラーモードのみにフォーカスします。
[2024.9.22] Docker 27.3.0 に WSL用の特別ルールが入りました。これによりWindowsホストからの127.0.0.1へのアクセスはコンテナでポートマップしたサービスへアクセスできるようになりました。
https://github.com/moby/moby/releases/tag/v27.3.0
ということで、ミラーモードは万能です(個人の感想)。安心してご利用ください。
[2023.10.25] ミラーモードはじめいくつかの新機能はWindows11 22H2通常版に機能開放されました。最新のWindowsUpdate適用の上、ストア版WSLをアップデートすることにより以下のオプションが.wslconfigで使えるようになります。
[wsl2]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
WSLストア版のアップデートは
wsl --update; wsl --update --pre-release
旧来のWSLネットワーク
WSL1ネットワーク
WSL1はシステムコールエミュレーションで実現されるLinux互換機能です。独自のネットワークスタックでなくWindowsそのものでした。この為、設定などに制限があるものの通信を行う分には違和感のないものでした。ただ、現在の主流は仮想マシン上でLinuxカーネルを動作させるWSL2へ移行しています。
NATモード
WSL2は仮想ネットワークからNATを介してWindows外と通信する仕組みが基本です。NATが挟まるので外部との接点はWindowsが受け持ち、直接はLinuxが見えません。またIPv6も利用できませんでした※。更に、仮想ネットワークがプライベートアドレスを利用するので外部の プライベートアドレスとの競合、特にVPN接続時に顕著な問題として課題に上がっていました。
※いずれも工夫をすれば解決できますが、基本的には制約・不満が多い状態です。
ブリッジモード
こうした中で提供された?のがブリッジモードですが、未だに公式には認められていない裏技的な扱いにとどまっています。ブリッジモードはネットワークアダプタを仮想化してWindowsと共有、つまり直接LANに接続しているような使用感があります。
至って自然なモードなのですが、いくつか制限があります。
- Windows11pro以上のSKUが必要
- 独立性が強すぎる(Windowsが接続したVPNを使えない等)
- 予め仮想スイッチを作成しておく必要がある
- そもそものHyper-Vのバグにぶつかることがある
Linux機をもう一台用意しようというような人ならともかく、Windowsユーザーが気軽にLinux環境を手に入れる には少々ハードルが上がってしまいます。
本題のミラーモード
そして、先日提供されたのがミラーモードです。こちらは試験的とはいえ正式な提供です。
公式の案内では以下のような機能が提供されるとあります。
- IPv6サポート
- WSLの127.0.0.1へアクセスすることで、Windowsで稼働するサービスへ接続可能
- Windows外から直接WSLへアクセス可能
- VPNとの互換性向上
- マルチキャストのサポート
いままで、ネットワークの扱いにあった不満を一気に解消しようとする意欲的なものです。
実際の動きはこれまどとどう違うのかというと、、、
.wsconfigに記述するだけで有効になります。
[experimental]
networkingMode=mirrored
IPアドレスはWindowsと共通のものが使われます。NATでも独立した接続でもなくWindowsが使用するアドレスそのものでWSL1の使用感に近いものです。
WindowsでVPN接続を行うとLinuxでもVPN経由のアクセスが可能になります。
使用するIPアドレスや経路情報がWindowsと共通なのでVPNやLAN内のプライベートアドレスとの競合が発生することもありません。
ブリッジモード同様に外部からのアクセスも可能なうえWindowsのファイヤーウオールが適用されるので安全対策も手軽でしょう。
更に実測でブリッジモードよりも若干高速というオマケ付きです。
このようにNATモード、ブリッジモードの良いとこ取りしたような機能です。
実験的故?の課題
試験提供ということもあり現状では不具合もあります。
- ポートが競合する
- WindowsからLinux上のDockerコンテナへアクセスできないことがある
ミラーモードではlocalhost(127.0.0.1)を介してLinuxからWindowsで稼働するサービスへ接続できます。このため?(Windowsサービスにアクセスできるようになったのは副次的?)Windowsで既にlistenしているポートを使おうとするとエラー扱いとなります。除外ポートを指定するオプションもありますが、主にDocker Desktopを使っている方々からの改善要求が上がっています。
通常は競合しないように気を付ければ良いだけなのですが、Docker DesktopはWindows側に通信を中継するプロセスを起動する(=LinuxとWindows双方でListenする)ので有無を言わせず競合してしまいます。
Docker Desktopではなく、LinuxにDockerパッケージをインストールしている場合は別の問題でWindowsからコンテナへアクセスでき ないことがあります。これはコンテナまで到達する通信がいままでとは変わってしまっていることが原因のようです。Dockerの設定を変更することで回避できないことも無いのですが、修正が望まれる部分です。
構造的な違い
DockerコンテナがWindowsと通信できないことから少し深堀してみると、旧来 lo(=local loopback)デバイスを介してWindowsとやり取りしていたものがloopback0というデバイスを使うようになっています。さらに、このデバイスはHyper-Vネットワークドライバを使っているので構造としてはeht0, loopback0はHyper-V仮想スイッチに接続されている。つまり、ドライバとハイパーバイザー(?仮想ネットワーク内の何か?)が頑張ってつじつまを合わせているという構造のようです。
また、一部トラフィックの発信元アドレスを変換するような定義がnftablesに入っているようです。これはWindowsとIPアドレスを共有す るという無茶な仕様を満たすために必要ということだと思いますが、こうした(こういう対応が必要な)部分が微妙な不具合として露呈する可能性があると思います。
今後に期待。不満が無ければ一般利用可
このようにまだいくつかの改善が必要ですが、今まで課題とされていたものの多くが解消されるので大いに期待できるものです。また、試験的とはいえ機能の基本的な部分はこなれている気がします。WSL自体が未完成の状態で提供されているモノなので試してみて自身の用途に不満が無ければ利用してかまわないでしょう。