WSL 2.0.0以降で提供された新機能を試しています。ミラーモードは別記事でも書いたように非常に有用なのですが、実現方法が今までと異なるので勝手が違うことがあるのも事実です。
今後改善される可能性もありますが、できないことは仕方がないので回避策を探ります。
Hyper-V内部スイッチへの経路がない
ミラーモードを試用すると基本的にはWindowsのネットワークスタックのごとく振舞います。VPNを接続すれば追加のインタフェースが生えてきてVPNへの経路が作成されます。USB-LANアダプタを追加しても同様に新しいインタフェースが追加されます。
ただ、、Hyper-V内部スイッチやBluetoothネットワークなど一部は除外されるようです。構造上仕方がないことなのか、優先度あるいは必要性の問題なのかは不明ですが使えません。
NATモードであれば、WSL も Hyper-V内部スイッチに接続されているので<仮想マシン名>.mshome.net
でアクセスできていましたから少し残念です。
直接経路がないならSSHでポートフォワードしてしまおう
幸い Windows にも SSH.exe があるのでこれを使って Windows -> Hyper-Vインスタンスへのポートフォワードを作ります。更に、ミラーモードでは Linux側からも localhost を介して Windows のサービスへアクセスできるようになりました。踏み台経由でのアクセスにはなりますがひとまず解決できそうです。
Windowsでポートフォワードする
前提条件として、Windows の %USERPROFILE%\.ssh や Linux の ~/.ssh には Hyper-V インスタンスへアクセス可能な秘密鍵を用意してください。パスワード認証でも構いませんが、いずれにせよ Windows 及び Linux(WSL) から Hyper-Vインスタンスへログインする準備が整っている必要があります。
SSH を用いたポートフォワーディングは検索すれば出てくると思いますがこのような形です。
PS C:\> ssh -NL 222:localhost:22 hypverv.mshome.net
hyperv という名前のインスタンスに SSH で接続し、localhost=hyperv の port22 と SSH 呼び出し元=Windows の port222 をつなぎ合わせます。
この状態で、WSLのLinuxから
$ ssh -p222 localhost
とすれば、 Linux(WSL) -- port 222 --> Windows -- port 22 --> Hyper-V の経路でSSHアクセスが可能になります。
ここでは SSH だけですが、他の通信も同様にポートマップすることで対応できます。
シームレスに接続したい
- ポートフォワードを作成して
- SSHで接続する
という二段階の方法でSSHアクセスできるようになりましたが面倒ですね。Linux(WSL)でSSHするときにオンデマンドでポートマップを作成できればよいですね。
~/.ssh/config に以下のように記述します。
match host=hypverv exec "pgrep -fa 222:localhost:22|grep -v pgrep || /mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe -command ssh -NL 222:localhost:22 hypverv.mshome.net &"
host hypverv
hostname localhost
port 222
match は条件に合致する場合にパラメタを追加するキーです。今回の条件は2つあって、一つは host=hypverv つまりホスト名が hypverv であること。もう一つは exec で実行するコマンドが成功した場合です。
今回の用法では失敗しても成功しても関係なくコマンド実行が目的なので match が成立した後設定するキーは何もありません。
実行するコマンドはログインシェル(Linuxなので通常はbash)に引数として展開されます。
分解して内容を見ていくと
pgrep -fa 222:localhost:22|grep -v pgrep
これはプロセスリストの中から "222:localhost:22" を探して、更に pgrep が含まれていないものを見つけます。もし見つかれば既にポートフォワードが実行状態なのでそこで終了。見つからなければ続きを実行します。
/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/PowerShell.exe -command ssh -NL 222:localhost:22 hypverv.mshome.net
PowerShellを呼び出して、SSH.exeを実行します。末尾に&
をつけてあるのでこれら一連の作業をバックグラウンドで実行します。
ここまででmatchの作業は終了です。
次に、以下の部分ですがこれはよくあるSSHの設定です。hypvervという名前が指定されたら、ポートとホスト名を記載されたモノに設定します。
host hypverv
hostname localhost
port 222
これらを ~/.ssh/config に準備しておけば以下のような通常の操作で(必要であれば)ポートフォワードを作成し、ポートフォワード経由でHyper-Vインスタンスにログインできるようになります。
$ ssh hyperv