UbuntuをWindows11上で動かす その12: 外部から接続する

UbuntuをWindows11上で動かす その12: 外部から接続する Ubuntu
スポンサーリンク

前回はwsl.confを使ってSSHサーバなどをWSL2の起動時に動かせるようになりました。

これでWSL2の実用度が上がりましたが、こうなってくるとやりたいのがWSL2に外部(LAN上の他のPC)から接続するということです。

今回はこの設定を行いたいと思います。

スポンサーリンク

外部からのWSL2への接続問題

WSL2ではWindowsとLinuxが仮想ネットワークで接続された構成になります。

このとき仮想ネットワークのアドレスは172.28.32.0/24というようなクラスBのプライベートネットワークアドレスが振られます。

このネットワークアドレスも固定ではないようですが、この記事ではこのネットワークアドレスを例にして紹介します。

そして、WSL2のLinuxのIPアドレスは、このネットワークアドレスの範囲内で、起動する毎に異なる値が割り当てられます。

WSL2のネットワーク構成

Windowsの仮想ネットワーク上のIPアドレスは、Power Shellでipconfigコマンドを実行すると「イーサネット アダプター vEthernet (WSL)」として表示されます。

> ipconfig
(省略)
イーサネット アダプター vEthernet (WSL):

   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: fe80::84d2:xxxx:xxxx:xxxx%42
   IPv4 アドレス . . . . . . . . . . . .: 172.28.32.1
   サブネット マスク . . . . . . . . . .: 255.255.240.0
   デフォルト ゲートウェイ . . . . . . .:

Linux側のIPアドレスが起動毎に異なると、Windowsから接続する前にLinuxのIPアドレスを調べなければ行けません。

これでは使いにくいということで、WSL2を起動しているWindows上から「localhost」というホスト名でアクセスすると、Linuxにデータが転送される仕組みになっています。

この機能を使うと、例えば、SSHであれば、Windowsからlocalhostに対してSSH接続を行うと、WSL2のLinuxへのSSH接続を行うことができます。

UbuntuをWindows11上で動かす その5: SSHで接続する
今回はWSL2上のUbuntuにSSHサーバを導入して、SSHで接続できるようにします。WSL2は起動毎にIPアドレスが変わってしまうという仕様なのですが、localhostを指定するとフォワーディングされるのでIPアドレスを気にせずにSSH接続することができます。これで使い慣れたターミナルソフトPuTTYを使ってWSL2を操作できるようになります。ただ、手動でSSHサーバを起動しておく必要があるのが面倒な点です。

ところが、外部のPC(LAN上のPC)からWSL2のLinuxに接続するときには状況が変わってきます。

WSL2に外部から接続させたい

この状況では「localhost」という芸当は使えません。というのも「localhost」がそのPC自体を示すため、データがWSL2の方に飛んでいきません。

localhostでは接続できない

それではということで、WSL2のLinuxのIPアドレス(172.28.?.?)を調べて、そのIPアドレスで接続しようとしてもそれもうまくいきません。

これは他のPCからは、WindowsとWSL2のLinuxをつなぐ仮想ネットワークの存在がわからないからです。

WSL2のLinuxのIPアドレスでは接続できない

それではということで、WSL2を動かしているWindowsのアドレス(この例では192.168.10.2)を使ってみても、WSL2にはデータが届きません。

WindowsのIPアドレスでも接続できない

このようにWSL2では外部のPCからWSL2上のLinuxへの接続は一筋縄でいきません。

スポンサーリンク

Windowsのポートプロキシを使った接続

これまで説明した外部からのWSL2へ接続問題に対し、MicrosoftからはWindowsのポートプロキシ機能を使うように案内されています。

2022年3月現在の話です。Microsoftは他の方法も検討しているようです。

WSL を使用したネットワーク アプリケーションへのアクセス
Linux 用 Windows サブシステム (WSL) を使用する場合のネットワーク アプリケーションへのアクセスに関する考慮事項について説明します。

「ポートプロキシ機能」というのは聞き慣れない機能ですが、要はWindowsがあるネットワークから受信したデータを他のネットワークに転送する機能です。

interface portproxy の netsh コマンド
IPv4 および IPv6 のネットワークとアプリケーション間でプロキシとして機能させるために、netsh interface portproxy コマンドを使用します。

この機能を使って次のように通信できるようにするということのようです。

WSL2で外部からの接続させるための構成

早速試してみましょう。

使用するポートの確認

ポートプロキシ機能では転送するポートを一つずつ設定する必要があります。

このため、WSL2のLinuxのポートに接続したいのかを決めておきます。また、対応するWindowsのポート番号も決めておきます。

今回は次のようにしました。

用途 プロトコル Windowsのポート
(転送元)
Linuxのポート
(転送先)
ssh TCP 10022 22
xrdp TCP 13390 3390

転送元を転送先と同一にしても良いのですが、Windowsで使用する可能性もあるかもしれないので、10000を足したポート番号を転送元のポート番号としました。

今回はssh用とxrdp用のポート番号しか設定しませんが、WSL2のLinuxでWebサーバを動かしたりする場合はポート番号80やポート番号433を転送先とした設定が必要になります。

Windowsのファイルアウォールの設定変更

Windowsで接続を受け付けるポート(転送元となるポート)が決まったら、そのポート番号を受信可能にする必要があります。

コントロールパネルから「Windows Defenderファイアウォール」を開きます。

ファイアウォールの詳細設定を選択

右側に「詳細設定」があるのでこれを選択します。

これでファイアウォールを設定する画面なりますので、左側のペインで「受信の規則」を選択したら、右側のペインで「新しい規則」を選択します。

新しい規則を選択

規則の種類は「ポート」を選択します。

規則の種類尾を選択

次にWindowsで受信可能とするポートを指定します。今回はTCPの10022と13390を受信するので次のようになります。

プロトコルとポートを選択

操作は「接続を許可する」とします。

操作を選択

次はこの規則がいつ適用されるかの設定ですが、目的はLAN上のPCからWSL2のLinuxへの接続なので「パブリック」はチェックを外しておきます。

プロファイルを選択

最後にこの規則の名前と説明を入力します。

規則の名前を設定

これで受信の規則一覧に、今回作成した規則が現れれば設定完了です。

受信ルールの追加完了

WSL2のLinuxのIPアドレスの確認

あとで必要になるので、WSL2のLinux上で下記のコマンドを実行してIPアドレスを調査しておきます。

$ hostname -I
172.28.37.141

ポートプロキシの設定

ようやく本丸のポートプロキシの設定となりました。

Wndows側でPowerShellを管理者権限で立ち上げます。そして次のコマンドを実行してみます。

> netsh interface portproxy add v4tov4 listenport=10022 connectaddress=172.28.37.141 connectport=22

これでWindowsのポート10022へのアクセスをWSL2のLinuxのポート22(SSHサーバ)に転送する様になります。

転送したいポートが複数ある場合は、listenportとconnectportの数値を変えて同様の設定をしていきます。

> netsh interface portproxy add v4tov4 listenport=13390 connectaddress=172.28.37.141 connectport=3390

ちなみに設定状態を確認するコマンドは「netsh interface portproxy show all」になります。

> netsh interface portproxy show all

ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               10022       172.28.37.141   22
*               13390       172.28.37.141   3390

LAN上のPCからの接続

あとはLAN上のPCから、WSL2を動かしているWindowsのIPアドレスに対して、WSL2のLinuxで使用したい機能に応じたポート番号で接続します。

今回の例では、WSL2のLinuxへSSHで接続したい場合は、WindowsのIPアドレス(192.168.10.2)のポート番号10022に対して接続を行います。

SSHによる接続

WSL2のSSHサーバで公開鍵認証のみにしている場合は、公開鍵の登録を行っておきましょう。

接続先をIPアドレスではなくホスト名(コンピュータ名)としている場合は、PuTTYの接続設定でIPv4を使用するようにしておきましょう。

IPv4の指定

ポートプロキシの設定はIPv4のみに対応しています。プロトコルを自動としておくと、IPv6で接続を試して失敗→IPv4で接続して成功という流れになり、接続確立まで時間がかかります。

これで問題なく接続できるはずです。これは次のような通信になるからです。

ポートプロキシを使った接続

同様にWSL2のLinuxへxrdpで接続する場合は、リモートデスクトップの設定で接続先のコンピュータとし「WindowsのIPアドレス:転送するポート番号」とすればOKです。今回の例では「192.168.10.2:3390」を指定することになります。

リモートデスクトップでの接続

スクリプト化する

これまで行った設定でLAN上のPCからWSL2のLinuxへ接続できることを確認しました。

ここで問題になるのが

  • WSL2のLinuxのIPアドレスは起動する毎に変わってしまう
    → ポートプロキシの設定を毎回やり直す必要がある

ということです。

Windowsを再起動すると、WSL2のLinuxも起動し直すことになるので、ポートプロキシの設定をやり直す必要があります。

毎回、WindowsでPowerShellを立ち上げてコマンドを打ち込むのも面倒です。そこでポートプロキシの設定処理をスクリプト化してワンタッチでできるようにしましょう。

まず適当なディレクトリに下記の内容のファイルを作成し、wsl2-portproxy.batという名前で保存します。

FOR /F "usebackq" %%i in (`wsl -d Ubuntu exec hostname -I`) do set IP=%%i

netsh interface portproxy delete v4tov4 listenport=10022
netsh interface portproxy add v4tov4 listenport=10022 connectaddress=%IP% connectport=22

netsh interface portproxy delete v4tov4 listenport=13390
netsh interface portproxy add v4tov4 listenport=13390 connectaddress=%IP% connectport=3390

WSL2でUbuntu以外のディストリビューションを利用している方は、1行目の「Ubuntu」の部分をお使いのディストリビューションに合わせて変更してください。

このバッチファイルでは、1行目でwslコマンドを使ってLinux側のIPアドレスを取得(IP変数に格納)し、その値を使ってポートプロキシのの設定をおなっています。

ポートプロキシの設定をしたい場合は、このwsl2-portproxy.batを右クリックして「管理者として実行」を選択します。

管理者として実行

管理者として実行すると「このアプリがデバイスに変更を加えることを許可しますか?」という表示が出るので「はい」を選択します。

WSL2でLinuxを起動したら、このwsl2-portproxy.batを管理者権限で1回実行すれば、外部から接続するためのポートプロキシの設定が行われます。

WSL2のLinuxが停止している状況でこのwsl2-portproxy.batを実行すると、自動的にWSL2のLinuxが起動します(そのため、数秒時間がかかります)。

これはLinuxのIPアドレスを取得するために、WSLコマンドを利用しているからです。

まとめ

今回はWindows Subsystem for Linux (WSL2)で導入したUbuntuに、外部のPCから接続する方法を紹介しました。

WSL1の頃は簡単にできたのですが、WSL2になってからネットワークの構成が変更になっているため、少々設定が複雑になっています。

次回はWSL2のLinuxをWndowsの起動時に自動的に立ち上げる設定をしたいと思います。

コメント

  1. 匿名 より:

    WSL インスタンスのホストの WIndows 上で Windows 付属の OpenSSH sshd を動作させ、WSL に connect する側の外部マシンの ssh に ProxyCommand を以下のように ~/.ssh/config に:

    Host win11-wsl
    User auser
    ProxyCommand ssh win11 -W localhost:22

    と設定しておくと、外部マシンから:

    % ssh win11-wsl

    で win11 というホストで動作している WSL インスタンスに ssh できます。
    公開鍵認証をするなら、win11, WSL のそれぞれの ~auser の .ssh/ に公開鍵を置き、.ssh/authorized_keys に公開鍵の中身を追記した上で、適宜 ssh のオプションに -A など追加することで可能です。

タイトルとURLをコピーしました