🐧

WSL2で開発中のWebアプリを同じLANのスマホで動作確認する方法

2022/06/04に公開

WSL2で開発中のWebアプリをスマホで即座に動作確認したい

スマホとPCが同一のWifiに接続している状態でスマホのブラウザから http://<PCのIPアドレス>:<Webアプリのポート> にアクセスして動作確認出来ることがよく知られています。
私は普段PC向けの業務システムやライブラリを作っているのでこの方法を使う機会がほとんどないのですが、久しぶりにスマホでの確認が必要になりました。

開発環境がWSL2の場合に固有処理が必要だったのでメモ代わりに公開しておきます。

WSL2固有処理だけ知りたい人のための結論

PowerShellを管理者権限で開いてください。
以下を1行ずつ入力してもいいし、ps1ファイルに書いて実行でもいいはずです。
私はPowerShellに慣れてないので1行ずつ打ち込んでます。

開始

$ports = @(3000, 8000) # Webアプリで使うポートを配列で指定
$fwRuleName = "WSL 2 Firewall Unlock"
$wsl2Address = wsl -e hostname -I | ForEach-Object { $_.trim() }

New-NetFireWallRule -DisplayName $fwRuleName -Direction Inbound -LocalPort $ports -Action Allow -Protocol TCP

for ($i = 0; $i -lt $ports.length; $i++) {
  $port = $ports[$i]
  netsh interface portproxy add v4tov4 listenport=$port listenaddress=* connectport=$port connectaddress=$wsl2Address
}

確認

Get-NetFireWallRule -DisplayName $fwRuleName | Get-NetFireWallPortFilter
netsh interface portproxy show v4tov4

終了

Remove-NetFireWallRule -DisplayName $fwRuleName

for ($i = 0; $i -lt $ports.length; $i++) {
  $port = $ports[$i]
  netsh interface portproxy delete v4tov4 listenport=$port listenaddress=*
}

ポートを一つしか使わないなら $ports = @(3000) の代わりに $port = 3000 と定義してfor文を解体するといいです。

開始

$port = 3000
$fwRuleName = "WSL 2 Firewall Unlock"
$wsl2Address = wsl -e hostname -I | ForEach-Object { $_.trim() }

New-NetFireWallRule -DisplayName $fwRuleName -Direction Inbound -LocalPort $port -Action Allow -Protocol TCP
netsh interface portproxy add v4tov4 listenport=$port listenaddress=* connectport=$port connectaddress=$wsl2Address

終了

Remove-NetFireWallRule -DisplayName $fwRuleName
netsh interface portproxy delete v4tov4 listenport=$port listenaddress=*

以下MSの公式ドキュメント通りだとスマホからのアクセスがFirewallに弾かれるので New-NetFireWallRule が必要でした。
https://docs.microsoft.com/ja-jp/windows/wsl/networking#accessing-a-wsl-2-distribution-from-your-local-area-network-lan

$wsl2Address に標準出力を代入する際に末尾の空白を ForEach-Object でtrimしましたがもっと短い記述があれば教えてください。
(% エイリアスはPowerShellに慣れてないと意味がわからないのでやめました)

参考にしたサイト

https://rcmdnk.com/blog/2021/03/01/computer-windows-network/
http://yanor.net/wiki/?Windows/WSL/ネットワーク/WSL2のホストへ外部からSSH接続する
https://aka-akatsuki.hatenablog.com/entry/2018/08/19/162819

上記だけでは接続できなかった人のための追加情報

PCのIPアドレスの確認

「windows ipconfig」でググってください。

WSL2のIPアドレスの確認

上記の開始コマンド内にもある

wsl -e hostname -I

で表示されます。

https://qiita.com/neko_the_shadow/items/25b797cb436078b9e832

Wifiルーターの設定

プライバシーセパレーターという機能が有効になっているとスマホからPCを見つけられません。
https://www.pfu.fujitsu.com/imaging/downloads/manual/cloud_cmn/ix100/jp/installationcloud/topic/ap.html

Webフレームワークの設定

最近のWebフレームワークはDNSリバインディング対策で「localhost」「127.0.0.1」以外のアクセスを弾くことがあります。
https://blog.tokumaru.org/2022/05/dns-rebinding-protection.html

Webフレームワークのドキュメントを読んで host: '0.0.0.0' に設定してください。

https://ja.vitejs.dev/config/#server-host
https://nuxtjs.org/ja/docs/features/configuration/#ホストとポート番号を編集する
https://nextjs.org/docs/api-reference/cli#development

デバッグ手順

上記のどこで失敗しているかわからないときは以下の手順で確かめると良いです。

  1. Windows側にWebフレームワークを素でインストール
  2. host: '0.0.0.0' を設定
  3. サーバー起動
  4. http://localhost:<port> にPCのブラウザでアクセスし表示確認
  5. ipconfig でPCのIPアドレスを確認
  6. スマホで http://<PCのIPアドレス>:<port> にアクセス
  7. 表示されないならWifiルーターのプライバシーセパレーター設定が怪しいので確認
  8. 表示されたらサーバー停止、Webフレームワーク削除
  9. WSL2側にWebフレームワークを素でインストール
  10. host: '0.0.0.0' を設定
  11. サーバー起動
  12. 記事最上部の開始コマンドを入力
  13. http://<PCのIPアドレス>:<port> にPCのブラウザでアクセス
  14. 表示されないなら netsh interface portproxy add ~ のコマンドが間違っているので netsh interface portproxy show v4tov4 で内容確認
  15. PCで表示されたらスマホで http://<PCのIPアドレス>:<port> にアクセス
  16. スマホで表示されないなら New-NetFireWallRule -DisplayName ~ のコマンドが間違っているので Get-NetFireWallRule -DisplayName $fwRuleName | Get-NetFireWallPortFilter で内容確認
  17. 表示成功

良きWSL2ライフを!

Discussion