2025年3月18日

Win11/WSL2への外部からのアクセス(ポートフォワーディング)について



宮島五重塔を望む
宮島五重塔を望む      



WSL2「Windows Subsystem for Linux 2」をインストールし,Linuxディストリビューションを立ち上げると,次は「外部ネットワークからどうやってアクセスするか」という課題に直面します。

それは,WSL2がHyper-Vと呼ばれる仮想環境上でLinuxカーネルを動作させるため,Windowsが使うIPアドレスとは全く別のIPアドレスが付与されるからです。

そのため,パソコン外部からWindows経由でアクセスがあった場合,どのようにWSL2に伝えるかが課題になります。

具体的には「netsh」コマンドを使って,WindowsのIPアドレスポートで入って来た通信を,WSL2のIPアドレスポートでリッスン「listen」させることになります。

※「netsh」コマンドは、ネットワーク全般の制御用コマンドです。

そこで,今回はSSHリモート通信を例に,WSL2のIPアドレスにアクセスするためのオーソドックスな「ポートフォワーディング」方法を学習します。

※ポートフォワーディングとは特定ポート番号宛てに届いたパケットを、予め設定したLAN側の機器に転送する機能です。

なお,WSL2のIPアドレスは,Windowsが再起動される度に原則変わりますので,その都度,「netsh」コマンドを使ってネットワークを再設定させなければなりません。

それでは,「netsh」コマンドを使ったネットワーク設定について見ていきましょう。

実証前提条件
・パソコン : Windows11 pro 24H2 (IPアドレス:IPv4固定値とする)
・Linux ディストリビューション : Ubuntu-24.04 LTS 起動中
・WSL2  バーション   :   2.4.10.0 
・テキストエディター :  Vim等でファイル内容を修正できる方


学習を始めます。





  1.Linuxディストリビューション等へのsshリモート通信準備

少し前のWSL2は,ローカルホストアドレス「127.0.0.1」にアクセス出来たので,それを使ってWindows固定IP:192.168.0.XXX」から入ってきたメッセージをポートリッスンポートフォワーディング」させることが出来ました。

ところが,今回の実証で確認すると,WSL2で稼働しているLinuxディストリビューションからローカルホストアドレス「127.0.0.1」を使うことが出来なくなっているようです。

この方法は,WSL2へのIPアドレスがPCの再起動毎に変わらないので良かったのですが,今回は,WSL2独自のIPアドレスを使わなければならなくなりました。

例えば,WSL2上にLinuxディストリビューション「Ubuntu-24.04」を構築した時,WSL2へのSSHリモートアクセス通信「IPアドレス:192.168.0.XXX,ポート番号:22」がWindowsに入って来たと想定します。

この時,WSL2に通信があったと認識させるには,SSHリモートアクセス通信「IPアドレス:192.168.0.XXX,ポート番号:22」を,WindowsからWSL2の独自IPアドレスに「ポートフォワーディング」させることになります。

それでは,「SSH通信によるリモートアクセス」を例に順次実証していきます。

まずは「Ubuntu-24.04」に「オープンSSHサーバ」がインストールされているかを確認します。



①オープンSSHサーバのインストール

オープンSSHサーバがインストールされているかは,Linuxディストリビューション「Ubuntu-24.04」を起動して以下のようなコマンドを入力します。

 ※「Ubuntu-24.04」ではssh通信のサービス名がsshdからsshに変更されています。

LinuxCode

sudo systemctl status ssh


オープンSSHサーバがインストールされていない場合は,以下のコマンドを入力します。


LinuxCode

sudo apt update
sudo apt-get update
sudo apt install openssh-server


apt update」や「apt-get update」は必要ないとも思いますが,念のため最新版にしています。インストールが終ったら次のコマンドを入力します。


LinuxCode

sudo systemctl enable ssh
sudo systemctl start ssh



これで「ssh.service」が起動したと思うので、次のコマンドで動作状況を確認します。


LinuxCode

sudo systemctl status ssh


出力メッセージ例

Output

● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/usr/lib/systemd/system/ssh.service; enabled; preset: enabled)
     Active: active (running) since Fri 2025-03-14 11:47:10 JST; 5s ago
TriggeredBy: ● ssh.socket
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 5646 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
   Main PID: 5648 (sshd)
      Tasks: 1 (limit: 4629)
     Memory: 4.7M ()
     CGroup: /system.slice/ssh.service
             └─5648 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"


このように出力されれば、OKです。「Ubuntu-24.04」では、「OpenSSHサーバ」は常時起動せず、「ssh.socket」サービスのトリガーによって起動されるように変わっています。



②SSHの簡易な接続設定

今回は、WSL2への外部からのアクセス方法についてですから,SSH接続は簡易なパスフレーズによる接続で実証します。

パスフレーズでのログインを可能にするため,「/etc/ssh/sshd_config」ファイルの中にある次のパラメータの「#」コメントを外します。


Parameter

PasswordAuthentication yes


修正したら,再度,次のコマンドで「ssh」を「restart」します。


LinuxCode

sudo systemctl restart ssh


これでOpenSSHサーバ関係の設定は完了です。

本来は公開鍵暗号で設定する場合が多いのですが,今回は簡略的に実証するため,平文でのパスワードアクセスを許可しました。



③ファイアウォールのポート通過許可設定


次に外部ネットワークからWSL2にアクセスする際,WSL2が稼動するPCの「ファイアウォール」が,ポート番号「22」の通過を許可しているかの確認が必要です。

PCのファイアーウォールに何を採用しているかによりますが,身近なWindows  Defenderファイアーウォールを想定して,ポート通貨許可の設定をします。

WSL2が稼働するPCにMicrosoft Defenderファイアーウォールを利用している場合は,「Windows検索欄」>「コントロールパネル」>「カテゴリから大きなアイコンを選定」>「Windows  Defenderファイアーウォール」をクリックして,「Windows  Defender ファイアーウォールによるPCの保護」画面を開きます。

続いて,左項目欄から「詳細設定」をクリックします。すると「ローカルコンピューターの
セキュリティが強化されたWindows  Defender ファイアーウォール」という画面が開きます。

左の項目欄から「受信の規則」をクリックします。「受信の規則」画面が表示されますので右項目欄の「新しい規則」をクリックします。

新規の受信の規則ウィザード(規則の種類)」の画面が開きますので,「ポート(O)」の選択ボタンを押して,右下の「次へ(N)」ボタンをクリックします。

次に「新規の受信の規則ウィザード(プロトコルおよびポート)」の画面が開きますので,「TCP」はそのままで,「特定のローカルポート」の空欄に「22」と入力します。

続いて「新規の受信の規則ウィザード(操作)」の画面が開きますので,「接続を許可する」の選択ボタンを押して,右下の「次へ(N)」ボタンをクリックします。

続いて「新規の受信の規則ウィザード(プロファイル)」の画面が開きますので,家庭内や職場内であれば「プライベート」の選定ボタンを押して,右下の「次へ(N)」ボタンをクリックします。

最後に「新規の受信の規則ウィザード(名前)」の画面が開きますので,「自分が分かり易い名前と説明」を記述して,右下の「完了(F)」ボタンをクリックします。

これで「ポート番号22に関する受信許可」が登録されました。

続いて,「送信規則」も同様に登録します。


これで「Windows  Defender ファイアーウォール」の設定は終了です。説明画像を入れてませんので分かりづらいかも知れませんが,ご容赦ください。

また,この設定はコマンドで行うことが出来ます。「Powershell」を「管理者実行」で立ち上げて,以下のようなコマンドを入力します。


PowerShell(管理者実行)

New-NetFirewallRule -Displayname 'WSL2_Portin_Unlock' -Direction Inbound -LocalPort 22 -Action Allow -Protocol TCP
New-NetFirewallRule -Displayname 'WSL2_Portout_Unlock' -Direction Outbound -LocalPort 22 -Action Allow -Protocol TCP



④Windowsユーザ名のディレクトリ下にある「.wslconfig」の設定

これは,WSL2の設定パラメータを格納するファイルですが,直接修正すると間違う可能性が高いので,マイクロソフトが用意した「WSL Settings」というアプリを使うことにします。

Windowsスタートから入ってアプリ一覧から探して下さい。起動すると設定画面が開きます。左の項目欄で「ネットワーク」を選択します。主に必要な項目は,次の2項です。

  • ネットワークモード:NAT
  • Hyper-Vファイアーウォールが有効:オフ

Hyper-Vファイアーウォールが新たに追加されたので,これも設定しないといけないことになりました。




  2.netshコマンドによるリモートネットワーク設定


外部ネットワークからWSL2にアクセスするには,Windowsに来たメッセージをWSL2にポートフォワーディングする必要があります。

このために使うコマンドが「netsh」コマンドになります。

例えば,WindowsのIPアドレスが「192.168.0.XXX」でポートが「22」番だった場合に,WSL2のIPアドレスが「172.21.14.XXX」で受取ポートが「22」だったとすると,次のようなコマンドを「コマンドプロンプト」の「管理者実行」で入力します。


コマンドプロンプト(管理者実行)

netsh interface portproxy add v4tov4 listenaddress = 0.0.0.0 listenport = 22 connectaddress = 172.21.14.XXX connectport = 22


今回は実証なのでlistenaddressを「0.0.0.0」として,どんなアドレスでも受け入れる設定にします。

IPアドレスはIPv4を利用しており,内部ネットワークなのでIPv6は利用しないものとします。




  3.netshコマンドによるネットワーク設定の参照方法


ネットワーク設定を確認するため次のコマンドを入力します。


コマンドプロンプト(管理者実行)

netsh interface portproxy show all


【出力例】
Address            Port           Address                  Port
----------------     ----------   ---------------          ----------
0.0.0.0               22             172.21.14.XXX       22


このように出力されればOKです。

これで,Linuxディストリビューションである「Ubuntu-24.04」にポート番号「22」でリモートアクセスする準備は整ったのですが,実際に外部ネットワークからのアクセスを利用するには,セキュリティを考慮する必要があります。


セキュリティ上の考慮点

外部ネットワークからWSL2にアクセスする際に考慮すべきポイントは,Linuxディストリビューションである「Ubuntu-24.04」内のセキュリティ設定になります。

これについては,公開鍵暗号の生成や「/etc/ssh/sshd_config」ファイル内の「PasswordAuthentication」や「PermitRootLogin」などの項目を設定することになります。

詳しくは,以下のブログカードを参照してください。


Ubuntu20.04 SSH接続環境の構築

Ubuntu20.04 SSH接続環境の構築

Ubuntu20.04へのSSH接続環境を構築します。但し,接続ツールはTeraTermです。





  4.netshコマンドによるネットワーク設定の削除方法


netsh」コマンドによる設定を削除する場合は次の様なコマンドを入力します。

コマンドプロンプト(管理者実行)

netsh interface portproxy delete v4tov4 listenaddress= 0.0.0.0 listenport= 22




  5.リモートアクセスツールなどによる通信確認


最後にリモートアクセスツールである「TeraTerm」などを活用して,平文のパスワードでLinuxユーザにアクセスできることを確認しました。

公開鍵暗号を使うには「TeraTerm」などのリモートアクセスツールを使うのが便利ですが,疎通しない場合に原因がよく分からないので,下記のコマンドで確認する方が手っ取り早いです。



コマンドプロンプト(管理者実行)

ssh -v usernme@IP_address



username   : Linuxインストール時のusernameを記述
IP_address  :  WSL2アクセスするWindowsのIPアドレスを記述

Connection timed out」,「Connection Refused」や「Connection reset」と出力されず,操作画面が表示されればOKです・

特に「Connection Refused」で接続できない場合は対応が難しいです。ファイアーウォールの設定,「ssh.service」のエラー,SSH鍵暗号の関係,WSL2の設定などについて,その原因を検討する必要があります。

ssh -v」コマンドでエラーを見ながら,修正のためのトライアル&エラーをするしかないと考えます。





  6まとめ(参考となる修復コマンド一覧など)


以上で,WSL2への外部からのアクセス方法の実証は終わりですが,今回は従来からあるポートフォワーディングによるものを学習しました。

実証結果から申し上げると,アクセスは出来るのですが極めて不安定で難しいと言わざるを得ない状況です。

特に,Windowsの進化に伴いWSL2の仕様変更が多すぎます。今回の実証でも,SSH通信が何度もエラーとなりました。

特に,PCの電源再起動時にネットワークエラーが発生する確率は非常に高いと感じます。

企業内や家庭内でちょっとしたサーバや数理計算機として使うなどでは良いかなという感じです。

また,今回はポートフォワーディングという従来からある方法を採用しましたが,現在,マイクロソフト社ではWSL2に「Mirrored」という新しいネットワーク方式を導入中のようです。

この「Mirrored」に係るネットワーク方式と,今回の「ポートフォワーディング」方式の自動化については別途研究してみたいと思います。

最後に,今回の実証ではSSH通信が成功するまで多数のErrorが発生しました。「Openssh-server」に係るところが主でしたが,修復のためにいろいろなコマンドを用いましたので,参考となるコマンド群を以下に追記します。

【参考コマンド群】

①sshサービスを再起動するコマンド

LinuxCode

sudo systemctl restart ssh.service
sudo systemctl restart ssh.socket

②sshサービスを有効化・無効化するコマンド

LinuxCode

sudo systemctl enable ssh
sudo systemctl disable ssh

③エラー時にジャーナルを見るコマンド

LinuxCode

journalctl -xe

④ポートリッスン時にIPV4とIpv6の待ち受け状態を調べるコマンド

LinuxCode

sudo sysctl net.ipv6.bindv6only

bindv6only = 0 の場合:IPv4orIPv6でリッスン
bindv6only = 1 の場合:リッスンしているのはIPv6接続のみ。

⑤SSH通信の確認時に使うコマンド

コマンドプロンプト(管理者実行)

ssh -v username@IP_address

⑥ssh通信エラー「Refused」や「TimeOut」でIpアドレスを強制許可・拒否するファイル

LinuxCode

sudo vim /etc/hosts.allow
sudo vim /etc/hosts.deny

⑦通信許可・通信拒否の構文確認コマンド

LinuxCode

sudo tcpdchk -v

なお,「tcpdchk」コマンドを使うには,「sudo apt install tcpd」が必要。


⑧ポートフォワーディングを動作させるWindows IP Helperサービスの起動コマンド

# ブート時の自動起動設定

コマンドプロンプト(管理者実行)

sc.exe config iphlpsvc start=auto

# サービスの起動

コマンドプロンプト(管理者実行)

sc.exe start iphlpsvc


以上です。それでは楽しいITリテラシーライフをお過ごしください。


(ご注意)情報の正確性を期していますが,実施される場合には自己責任でお願いします。



0 件のコメント:

コメントを投稿