<![CDATA[
うちにLinuxマシン一つあるんだけど、こいつは録画サーバーとして使ってるんで
何かあった時に落ちるととても悲しい
できればもう一つLinuxマシン作って、Dockerで色々立ち上げたりして遊びたいわけなんですが
そんな遊んでるマシンいっぱい転がってるわけないしなー
と思っていたところでふと思いついたんですが、
最近Windowsに入ってるWSL、こいつがかなり使えるって話題じゃないですか
WSLの中に入ってるLinuxを外部からログインできるようにしたら
色々捗るんじゃない?
なお、今回参考にしたURLはこちら
まず基本的にどうしたらいいの
WSLはWindowsの中のHyper-V、つまり仮想環境にLinuxを立ててる状態なんで、
親マシンのWindowsのIPアドレス体系と別に仮想のIPアドレスがある感じ
なんで、親マシンで通信を受けたら子マシンに伝達する、ポートフォワードが必要
それをやってあげるのがnetshコマンドだ
例えば親マシンが192.168.0.4ってIPアドレスで、子マシンのWSLが172.26.100.25だったとする
このWSLにSSHでアクセスしたい。ポートはデフォルトの22で。そういう場合
netsh interface portproxy add v4tov4 listenaddress=192.168.0.4 listenport=22 connectaddress=172.26.100.25 connectport=22
こういうコマンドを、管理者権限のPowerShellで実行するとよいです
んで、これだと親マシンのポート22が使えなくなって、ちょっと困るかもしれない
んー、WindowsでSSHなんてあんま使わないから実は困らないかもしれない。でも気持ち悪いかも
そういう場合、ポート10022で待ち受けたければ
netsh interface portproxy add v4tov4 listenaddress=192.168.0.4 listenport=10022 connectaddress=172.26.100.25 connectport=22
ってしてあげればOK
これが基本的な流れ。なあんだ、たった1行でいいんじゃん
って思うじゃん?
接続先の子マシンのIPアドレス、マシン起動するたび毎回変わるんだなこれ
何してくれるんじゃ
毎回取得しに行こうぜ
それじゃしょうがない、WSL側のIPアドレスを毎度取得しようぜっていう工夫が本文の引用先のURLの話です
いやWSLのIPアドレス固定にできないの? って話だけど、できないらしい
普通にHyper-V立てればいけるっぽいんだけど、それじゃ面倒臭えよな
ということでWSL側で少し苦労しましょう。少しだけでいいんです
まず接続したいWSLを規定にする。powershellで
wsl -s Ubuntu-24.04
とか、そんなコマンド打つ
そんで、接続先のWSLでこういうシェルを書くわけだ
ip address show eth0 | awk '/inet / {print $2}' | awk -F / '{print $1}'
うわあ何じゃこりゃ
awk怖い! 魔術!
てなるけど、まあ分解すると
ip address show eth0
で
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:83:9b:b5 brd ff:ff:ff:ff:ff:ff
inet 172.26.100.25/20 brd 172.26.111.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe83:9bb5/64 scope link
valid_lft forever preferred_lft forever
って感じでネットワーク情報をずらずら出してくるんで、そいつの文字列情報を切り貼りして
青文字の部分だけを持ってくるのが | awk '/inet / {print $2}' | awk -F / '{print $1}' っていうawkなんだな
これを適当な場所、例えば /usr/local/bin/getip.sh って場所に保存して
PowerShellで
bash /usr/local/bin/getip.sh
って実行してやれば、WSL側のIPが得られる
親側も取得しようぜ
一方、親マシンもわりとdhcpでアドレス取っているんで、起動のたびにIP変わったりする
そいつについてはPowerShellで結構簡単に取得できる。そのスクリプトはこれだ
(Get-NetIPAddress | where{$_.InterfaceAlias -eq "イーサネット" -and $_.AddressFamily -eq "IPv4"}).IPAddress
はいこれも黒魔術。何やってるか全然わからないっすね。分解していこう
まずGet-NetIPAddressで得られるのは
IPAddress : 192.168.1.18
InterfaceIndex : 16
InterfaceAlias : Wi-Fi
AddressFamily : IPv4
Type : Unicast
PrefixLength : 24
PrefixOrigin : Dhcp
SuffixOrigin : Dhcp
AddressState : Preferred
ValidLifetime : 21:34:30
PreferredLifetime : 21:34:30
SkipAsSource : False
PolicyStore : ActiveStore
...
こんな感じのリストだ。IP以外もいっぱい情報ついてくるのはWSL側と一緒なんだけど、
PowerShellはLinuxのshellと違ってこの値をちゃんと連想配列で返してくれる
だから、素直に絞りこみとかを使って情報取得できる。素敵!
絞り込みはInterfaceAliasおよびAddressFamilyで行う
Get-NetIPAddressやってみればわかるけど、本番のIPアドレスの他にDocker用の仮想IPアドレスとか
Bluetoothアダプタとか、そういういらないものがずらずら取れるので
$_.InterfaceAlias -eq "イーサネット"
って条件をつけておかないと複数表示されちゃう
また、IPv6の値とかが取れることもあるので、
$_.AddressFamily -eq "IPv4"
こちらの条件も必須だ
この2つを条件につけた命令が、さきほどのPowerShellというわけだな
一発アクセスPowerShellの完成
こうやってIPを自動取得して作ったPowerShellがこちら
$WSL2_IPV4=bash /usr/local/bin/getip.sh
$HOST_IPV4=(Get-NetIPAddress | where{$_.InterfaceAlias -eq "イーサネット" -and $_.AddressFamily -eq "IPv4"}).IPAddress
netsh interface portproxy delete v4tov4 listenport=10022 # 古い設定を削除
netsh interface portproxy add v4tov4 listenaddress=$HOST_IPV4 listenport=10022 connectaddress=$WSL2_IPV4 connectport=22
紹介先URLでは、これをタスクスケジューラに組み込んで勝手に実行とかさせてたけど
今んとこそこまでは不要かな
]]><![CDATA[
]]>