wsl2 で立てたサーバーにローカルネットワーク内の他の端末からアクセスする

# この記事は何？
webアプリ開発中の通信の確認等で、WSL2内に立てたサーバーにローカルネットワーク内の他の端末からリクエストを行いたい場合がありましたので、そのときに行った設定のメモです。

# 方法


## 1. windowsマシンからWSL2 に接続するための設定を行う

通常は隔離された設定になっているので、WindowsからWSL2にポートフォワードしておく必要があります。
また、必要に応じてファイアウォールの開放も行います。
以下のpowershellスクリプトを利用し、ポートフォワードとファイアウォールの設定を行います。

```powershell
# 現在のユーザーが管理者権限を持っていない場合に、スクリプトを管理者権限で再実行するための処理です。
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) { Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs; exit }

# WSL 2 インスタンスの IP アドレスを取得します。
# bash.exe を使って、ip r コマンドを実行し、結果からIPアドレスを抽出します。
# IP アドレスが取得できない場合、スクリプトは終了します。
$ip = bash.exe -c "ip r |tail -n1|cut -d ' ' -f9"
if( ! $ip ){
  echo "The Script Exited, the ip address of WSL 2 cannot be found";
  exit;
}

# 通信を許可するポート番号のリストを指定します。
# このスクリプトでは、22, 3000, 18000 の3つのポートを指定しています。
$ports=@(22,3000,18000);
$ports_a = $ports -join ",";

# 以前に作成されたファイアウォールの例外ルールを削除します。
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";

# New-NetFireWallRule コマンドを使用して、指定したポート番号に対するインバウンドおよびアウトバウンドのファイアウォール例外ルールを作成します。
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";

# netsh interface portproxy コマンドを使用して、ポートプロキシの設定を行います。
# 指定したポート番号に対して、IP アドレスを介しての接続を許可します。
for( $i = 0; $i -lt $ports.length; $i++ ){
  $port = $ports[$i];
  iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=* connectport=$port connectaddress=$ip";
}

# 作成されたポートプロキシの設定を表示します。
iex "netsh interface portproxy show v4tov4";
```

上記スクリプトを powershellスクリプト(server_conf.ps1) として保存し、以下のように実行します。

```yaml
.\server_conf.ps1
```

## 2. WSL2でサーバーを立てる

アクセスしたいアプリのサーバーをWSL2上で起動します。


## 3. 端末のプライベートipアドレスを調べる

powershell で `ipconfig` を実行し、サーバーを起動した端末のプライベートipアドレスを調べます。
コマンドを実行すると以下のようにネットワークインターフェースの情報が表示されます。
```powershell
ipconfig

Wireless LAN adapter Wi-Fi:

   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: xxxx
   IPv4 アドレス . . . . . . . . . . . .: 192.xxx.xx.xx
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .: 192.168.11.1
```
プライベートIPアドレスは、通常、**"IPv4 Address" や "IPv4 アドレス"** とラベル付けされた行に表示されるので、メモしておきます。

## 4. 他端末からアクセスする

他端末をサーバーと同一のネットワークに繋ぎ、3で調べたIP にリクエストを投げるなどしてみます。うまく設定できていればアクセスできるはずです。

# ポートフォワードの設定を削除する

検証が終わったら以下の手順でポートフォワードの設定を削除しておきましょう.
削除を忘れると、**WSL2で起動したサーバーにlocalhostでアクセスできなくなることがあります!**

参考記事
https://qiita.com/yosse95ai/items/b3a134a6320dfc8b3abc

まずは以下のコマンドでポートフォワード設定を表示します。
```
# ポートフォワード設定表示
netsh interface portproxy show v4tov4
```
以下の様にポートフォワードの設定されているポートが一覧で表示されます。
```
ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               22          **************  22
*               3000        **************  3000
*               9000        **************  9000
```

2のスクリプトで指定したポートが表示されると思いますので、以下のコマンドで設定を削除します。
<ポート番号> に削除するポートを指定してください。

```
# ポートフォーワード設定削除
netsh interface portproxy delete v4tov4 listenport=<ポート番号>
```

# 参考にさせていただいたページ
* [WSL2 で立ち上げたサーバに LAN 内の別 PC からアクセスする](https://neos21.net/blog/2021/07/20-01.html)
* [WSL2 に外部からアクセスする](https://bayashi.net/diary/2020/1121)
* [localhostにスマホから繋げてみた!!(Windows編) - Qiita](https://qiita.com/TeppeiMimachi/items/11046390ec7270df1f2a)