WSL2でReactの localhost:3000 にアクセスできなくなった時

# はじめに
私はある日を境に，`crate-react-app`したアプリの`http://localhost:3000`へアクセスすることができなくなりました．
一方で，`yarn start`したとき`On Your Network`で示されるホスト経由だと，アプリを表示できるという現象に見舞われました．

いろいろ質問した末に，自己解決できたのでまとめます．

https://ja.stackoverflow.com/questions/88367/npm-start-%E3%81%97%E3%81%A6%E3%82%82-react-%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB-localhost-%E3%81%A7%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84

https://ja.stackoverflow.com/questions/88395/npm-start%E3%81%A7%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AB%E3%81%A0%E3%81%91%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84

# 環境
```
OS: Windows 10
WSL2: Ubuntu-20.04
```

# もくじ
- [解決方法](#解決方法)
    - [PowerShellを開く](#powershellを開く)
    - [WSLのホスト名を確認](#WSLのホスト名を確認)
    - [ポートフォワーディングの設定を消去](#ポートフォワーディングの設定を消去)
- [別の解決方法](#別の解決方法)
    - [wsl --shutdown](#wsl---shutdown)
    - [ファイアウォールの設定を見直す](#ファイアウォールの設定を見直す)
- [原因](#原因)
    - [なぜポートフォワーディンの設定をしたか](#なぜポートフォワーディンの設定をしたか)
    - [対策](#対策)
- [おわりに](#おわりに)
- [参考記事](#参考記事)

# 解決方法
私の場合，「<font color="#cc0000">Windows側でWSLへのポートフォワーディングの設定をしており，そのうち，古い設定が残ったままになっていた</font>」ことに起因していました．
ポートフォワーディングの設定をすること自体は悪くないのですが，古い設定値が残っていることがよくなかったみたいです．
WSLは再起動をかけるたびにホストが変わるので，このような現象が起きたと推測できます．

詳細な解説は後にして，ひとまず解決方法を示します.

## PowerShellを開く
管理者権限で`PowerShell`を開き，以下のコマンド実行します．

```:PowerShell
netsh interface portproxy show v4tov4
```
すると，ポートフォワーディングの設定値を見ることができます．私の場合は以下．

```text:出力結果
ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               22          172.23.233.206  22
*               3000        172.23.233.206  3000
*               3001        172.23.233.206  3001
*               8080        172.23.233.206  8080
```

出力結果が出た人は，古い設定値が残っていることに起因している可能性があります．

## WSLのホスト名を確認
以下のコマンドを実行して，WSLのホストを確認します．

```:PowerShell
bash.exe -c "ip r |tail -n1|cut -d ' ' -f9"
```
すると，現在のWSLのホストが表示されます.私の場合以下．

```
172.23.224.238
```
先ほどの「設定値の確認コマンドの結果に示されるホスト」と「現在のWSLのホスト」が違ってしまっていることが確認できました．これが原因です.

## ポートフォワーディングの設定を消去
以下のコマンドで，指定ポートのポートフォワーディングの設定値を消去できます．

```:PowerShell
netsh interface portproxy delete v4tov4 listenport=ポート番号
```
私は3000番にアクセスできなくなっていたので，3000番の設定を削除します．
そもそも，設定値があるうえでlocalhostにアクセスできていないということは，設定値が古い可能性があるので，すべて削除してしまってもいいかもしれません．

```:PowerShell
netsh interface portproxy delete v4tov4 listenport=3000
```

以上の操作で，`create-react-app`で作成したアプリの`http://localhost:3000`にアクセスできるようになりました．

# 別の解決方法
私自身は試してうまくはいかなかったが，ほかの人はうまくいっている方法をいくつか紹介しておきます．
私の解決方法が該当しなかった人は試してみてください．

## wsl --shutdown
ほんとに多くの人が解決できていました．(私の場合は関係ありませんでしたが)
WSLを一度落として，再起動をかけることで復活した報告です．

```:PowerShell
wsl --shutdown  # もしくはお使いのエディタからリモート接続を終了
wsl             # もしくはお使いのエディタで新しリモート接続を開始
```
以下のリンク内のスレッドを見ていただければいいかと思います．

https://github.com/microsoft/WSL/issues/4885

## ファイアウォールの設定を見直す
ファイアウォールでポートへのアクセスを制限されているかもしれません．
「セキュリティが強化された Windows Defender ファイアウォール」を開いて、設定を見直してみてください．(私の場合は関係ありませんでしたが)

以下のリンクの自己解決の部分で原因を言及していました．

https://ja.stackoverflow.com/questions/65881/windows10%E3%81%A7%E7%89%B9%E5%AE%9A%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AE%E9%96%8B%E6%94%BE%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84

# 原因
冒頭で述べた通り，Windowns側のポートフォワーディングの古い設定値が残っていることで，古い設定で解放されたポートへ`http://localhost:<port>`でのアクセスができないようになっていたみたいです．

ポートフォワーディングの設定において参考にしたサイトは以下です．

https://rcmdnk.com/blog/2021/03/01/computer-windows-network/#wsl2%E3%81%A7%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E8%A8%AD%E5%AE%9Awindows%E5%A4%96%E9%83%A8%E3%81%8B%E3%82%89

上でも言った通り，ポートフォワーディング事態は悪いことではなく，古い設定値が残ってしまい，現在のWSLのホストの値と違う値が設定されていることが原因でした．

## なぜポートフォワーディンの設定をしたか
WSLで`create-react-app`したアプリケーションに，外部の端末(スマホなど)からアクセスして，デザインの確認や使用感を試したかった時があり，その時にポートフォワードの設定をしました．

MacやUbuntuユーザであれば，そんな設定しなくていいじゃないかと思われそうですが，WSLを用いている場合，単純にWSLのポートにアクセスしようとしても，アクセスすることはできません．
さらに，Windowsのホストにアクセスしても，WSLのローカルホストへはアクセスできません．

これをかなえるために，Windowsに対するアクセスを，WSLへポートフォワーディングすることで，外部端末からWSLのローカルホストへアクセスしようという寸法です．

これで外部端末から，Windowsのホストにアクセスすれば，WSLのローカルホストへアクセスできます．(開放したポートに限る)

参考：[WSL2でのネットワーク設定(Windows外部から)](https://rcmdnk.com/blog/2021/03/01/computer-windows-network/#wsl2%E3%81%A7%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E8%A8%AD%E5%AE%9Awindows%E5%A4%96%E9%83%A8%E3%81%8B%E3%82%89)

## 対策
WSLでローカルホストをたてず，Windowsでローカルホストを立てればそれでおしまいなのですが，この記事を見ているということは，WSLを使っていて，WSLのローカルホストへ外部端末からアクセスしたい人だと思います．
なので以下を対策として挙げさせていただきます．

- **ポートフォワーディングの古い設定値を残さない**
    - 今回のケース
- **WSLを再起動したときはポートフォワーディングを再設定**
    - 再起動毎にWSLのホストが変わるため
- **ポートフォワーディングを設定しているということを失念しない**
    - WSL側ではなくWindows側の設定でおかしくなっているとは予想できなかった
    - 私がまさしくこのパターン

# おわりに
今回変な地雷を踏んでしまいましたが，解決できてよかったです．
同じ症状の方が救われればと思います．

それでは:wave:


# 参考記事
- [Windows WSL2に外部から直接アクセスするための設定](https://rcmdnk.com/blog/2021/03/01/computer-windows-network/)
- [Windows10で特定ポートの開放ができない](https://ja.stackoverflow.com/questions/65881/windows10%E3%81%A7%E7%89%B9%E5%AE%9A%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AE%E9%96%8B%E6%94%BE%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84)
- [Cannot use localhost to access a react-app running in WSL2 ](https://github.com/microsoft/WSL/issues/4885)