WSL2をIPv6ネットワークに接続する(前編)

## はじめに
:::note warn
2023.11.12追記
現在の最新WSLではブリッジモードやミラーモードというネットワークモードが追加されているのでIPv6を使いたい場合にはそちらをご利用ください。
この手法は旧来のネットワークモードやWindowsサンドボックスでの活用方法もありますが、基本的にはもはや必要のない方法です。
:::
WSL2は公式にはIPv6通信に対応していません。
Microsoftとしてもこのことは課題ととらえていてるのでいずれは解決されると思います。ただ、まてねーよと思っているのは筆者だけではないはず。多くの人がIPv6の世界へと踏み出したいと考えているはず。

そんなあなたに、一歩先にIPv6の世界へ踏み出せるお手伝いができれば。

本稿の構成は以下のような構成を考えています。

前編 *WSL2がIPv6通信できない理由* <-- イマココ
中編 [*現時点のWindows標準機能だけでRAを広告する*](https://qiita.com/shigeokamoto/items/9c5a631fe3099ed346c2)
後編 [*DHCPv6-PDでプレフィクス委譲を受ける*](https://qiita.com/shigeokamoto/items/a13f5fea5085f541a0b5)
番外 [*改良スクリプトをタスクスケジューラに登録する*](https://qiita.com/shigeokamoto/items/4e5538fcc80aba2dc4fe)


## WSL2がIPv6通信できない理由

では、WSL2がIPv6に対応できないのはどうしてでしょうか？

別途寄稿した「[WSL2のUbuntuに固定のIP(IPv6)アドレスを複数つけてみる](https://qiita.com/shigeokamoto/items/5766c025d3292acea1cb)」のようにWSL2インスタンスとWindowsホストは既にIPv6で通信できる状態にあります。

```:現状
イーサネット----------------+-----------------------
                           | ↓　
                    Windows  ×
                           | ↑
vEthernet (WSL)------------+-------------+----------
                                         |
                                        WSL2
```
通常はこのような接続になっていて、Windowsが通信するネットワーク(イーサネット)からWSL2インスタンスは隔離されています。IPv4的には家庭用ルーターでPCをインターネットに接続したのと同じようにNATが間に挟まっていて、内から外へアクセスできるようになっています。一方IPv6に関してはNATは存在せず、イーサネット側と`vEthernet (WSL)`側のルーティングが行われていないために通信が行えません。道は川向うまで来ているんですが、橋がつながってなくて通れないような状況です。

最近のブロードバンドルータには`ND Proxy(RA Proxy)`というルータを介して反対側のネットワークに所属しているように見せかける機能が備わっているものがありますが、同様の機能をWindowsが提供してくれれば、WSL2インスタンスもLAN側のIPv6ネットワークに参加できるようになります。おそらくそうした機能を実装しようとMicrosoftさんも頑張ってくれているのでしょう。

```:NDProxyでイーサネットに接続してるっぽくふるまう
イーサネット----------------+------------+----------
                           | ↓　　      :
                    Windows  ×          :
                           | ↑          :
vEthernet (WSL)------------+------------:+----------
                                        :|
                                        WSL2
```

IPv6での接続にはもう一つ`DHCPv6-PD`というプロトコルで 上流ルータが持っているネットワークの一部を下流に委譲する方法があります。筆者が構築した環境はこの手法です。

```:上流から情報をもらってルーティングする
イーサネット----------------+-----------------------
                           | ↓　
                    Windows  〇
                           | ↑
vEthernet (WSL)------------+-------------+----------
                                         |
                                        WSL2
```

さらに、`vEthernet (WSL)`はWSLという名前のHyper-Vスイッチなのですが、WindowsがPro以上の品目であれば、Hyper-Vマネージャを使ってWSLスイッチを、Windowsのイーサネット同様に外部に直接接続してしまう(=LAN側からDHCPやRAでネットワーク設定を直接受け取る)という方法も可能なようです。WSLのgithubではこの方法で接続しているという方をちらほら見かけました。

```:イーサネットに直接つなげてしまう                     
イーサネット===============+============+===========
vEthernet (WSL)           |　　        |
                       Windows         WSL
```

IPv6の世界ではあまり主流派の方法ではありませんが、IPv4同様にNATで接続するという方法もあります。


```:IPv6でもNATしてしまう
イーサネット----------------+-----------------------
                           | ↓　
                    Windows  NAT
                           | ↑
vEthernet (WSL)------------+-------------+----------
                                         |
                                        WSL2
```
ただ、NATだと、現状のWSL2のIPv4通信のように中から外は良いのですが、外部からWSL2インスタンスにアクセスしようと思うとまた別の問題が発生しそうです。


## IPv6通信できない理由まとめ
 - WSL2インスタンスがIPv6で通信できないのは、Windowsホストを挟む形でネットワークが隔絶しているから
 - WSL2でIPv6通信を可能にする方法はおおむね4つある
     1. ND Proxy(RA Proxy)をWindowsに実装する
     2. DHCPv6-PDで上流からプレフィクス委譲を受けてvEthernet をIPv6で上流ネットワークに接続する
     3. vEthernet (WSL)を操作してWindowsホストと同じネットワークにWSLインスタンスを接続してしまう
     4. IPv6パケットをNATで上流と接続する(VMWareがこの方法らしい？)

個人的意見としては1が実現できるのがクライアントPCには一番望ましいと思っています。なんとか実現できないかと疑似的にパケットを飛ばしてみましたが、上流下流それぞれの通信を中継して代理で返事をしないといけないのでWSL(これが可能なのはWSL1ですが)側の世界だけで対応するのは大変そうです。Windowsネイティブのアプリケーションの対応が必要になると思います。現時点では2の方式と3の方式が現状での現実的な解のようです。


3の方法でvEhternet (WSL)をWindowsホストと同じネットワークに接続するには Hyper-Vマネージャで WSLスイッチを`外部ネットワーク`に切り替えればよいのですが、

 - WSL2が vEthernet (WSL) を作る前に同名のスイッチを作成すると、WSL2が起動できません。
 　WSL2起動 -> wsl --shutdown -> スイッチを変更 -> WSL2 を起動という手順を辿る必要がありました。

 - 外部ネットワークに接続してもHyper-V側からIPアドレスを与えられている(DHCPらしきものが働いている？)
 - インタフェース情報を削除してから付け直さないといけないという話が一時githubで盛り上がっていました
 - 上流のRAを受け取ってIPv6は自動設定された(=確かに外部ネットワークにつながっている)

というような状況で確かにつながったんですがそもそもWSL2用に用意された仮想スイッチ、しかもWinNATの設定などは表から見えないようになっているものを外部ネットワークに変えてしまって大丈夫かなという不安が残ります。細かい点をキチンと調整できれば、上流ネットワークを選ばないので ND Proxy 同様接続場所が変わる場合には有用な方法だと思います。

## ひきつづき
引き続き DHCPv6-PD で接続するに至るまでWSL2とIPv6の世界を覗いてみたいと思います。