他のPCから自分のPCのWSLに接続したい

WSL2上で動かしているROSに,同じネットワーク上の別のPCから接続したかった.

WSL2はWindowsホストとは別のIPアドレスを持つ仮想マシンとしてNAT越しに動いているため,外部のPCからWSL2に直接アクセスすることはできない.そこで,Windowsホストの特定のポートに来た通信をWSL2に転送する形で対応する.

1. Windowsホストに疎通できるようにする

まずは,そもそもWindowsホストにPingが通るようにする.Windows Defender ファイアウォールの受信規則を追加する.

  1. コントロールパネルからWindows Defender ファイアウォールを開く
  2. 左側の「詳細設定」を選択
  3. 「受信の規則」を右クリックし,「新しい規則…」を選択
  4. 「カスタム」を選択して「次へ」
  5. 「すべてのプログラム」を選択して「次へ」
  6. プロトコルの種類で「ICMPv4」を選択し,「カスタマイズ…」をクリック
  7. 「特定のICMPの種類」を選択して「エコー要求」にチェックを入れ,「OK」→「次へ」
  8. ローカルIPアドレスとリモートIPアドレスに「任意のIPアドレス」(もしくは必要な範囲)を指定して「次へ」
  9. 「接続を許可する」を選択して「次へ」
  10. 「ドメイン」「プライベート」「パブリック」すべてにチェックを入れて「次へ」
  11. 分かりやすい名前を付けて「完了」

参考:Windows WSL 2 can’t ping host machine

この設定で,とりあえず他のPCからWindowsホストにPingが通るようになる.なお,この設定はコマンドでも可能で,後述の netsh advfirewall を使う.

2. WSL2へのポートフォワーディング設定(PowerShell・管理者権限)

netsh コマンドでポートフォワーディングを設定すると,Windowsホストのポートに来た通信がWSL2に転送され,他のPCからWSL2上のプロセスに接続できるようになる.

以下は,ROS Bridge(WebSocketの9090番)を対象にした場合の設定.

# ポートフォワーディング(172.19.35.202 は WSL2 のIPアドレス)
netsh interface portproxy add v4tov4 listenport=9090 connectport=9090 connectaddress=172.19.35.202

# ファイアウォール
netsh advfirewall firewall add rule name="WSL2 Firewall Unlock for ROS" dir=in action=allow protocol=TCP localport=9090
netsh advfirewall firewall add rule name="WSL2 Firewall Unlock for ROS" dir=out action=allow protocol=TCP localport=9090

確認.

netsh interface portproxy show all
netsh advfirewall firewall show rule name="WSL2 Firewall Unlock for ROS"

消すとき.

netsh interface portproxy delete v4tov4 listenport=9090 listenaddress=*
netsh advfirewall firewall delete rule name="WSL2 Firewall Unlock for ROS"

WSL2のIPアドレスはWSLを再起動するたびに変わる.そのため,起動のたびに wsl hostname -I でアドレスを確認して portproxy を貼り直す必要がある.

wsl hostname -I

ROSの場合の注意

上記のポートフォワーディングは,接続先のポート番号が固定されている通信であればうまくいく.

一方でROS1のノード間通信は,マスター(11311番)以外のポートが起動のたびに動的に割り当てられるため,ポートを1つ開けるだけでは通信できない.そのため,ポート番号が固定されているROS Bridge(9090番)を経由させる方法をとった.このあたりは以下の記事が分かりやすい.

【ROS/WSL2】WSL2上のROSと外部PCで通信してみたかった - Qiita

【ROS/WSL2】ROS Bridgeを使用した複数マシン(複数ROS master)間の通信 - Qiita

Windows 11(22H2以降)とWSL 2.0.0以降の環境であれば,.wslconfig でネットワークをミラーモード(networkingMode=mirrored)にすることで,WSL2がホストと同じネットワークインターフェースを共有するようになり,こうしたポートフォワーディングの設定自体が不要になる.

参考

Accessing network applications with WSL | Microsoft Learn