WSLは開発用途のツールですが、サーバー的な活用もしたいという要望が一定数あります。ここではSSHを例に外部からアクセス可能なサーバーの構成例を紹介します。
WSL(Ubuntu)をインストールする
すっかり簡単になってしまったWSLのインストールから手順を踏んでみます。
PowerShellにて以下のコマンドを入力します。
PS C:\> wsl --install
以前は幾つかの手順が必要でしたが、現在はこのコマンド一つでインストールが進行します。一通りインストールが終わると再起動を求められるので指示に従ってください。起動するとウィンドウが一枚開いてユーザー名とパスワードの設定が促されます。
これで完了です。
sshdをインストールする
次は sshd をインストールします。この項目は WSL上のUbuntuにて操作を行います。
$ sudo apt update
$ sudo apt install openssh-server
これでインストール完了です。以前は systemdを使いたいという要望が沢山ありましたが、現在は WSL に Ubuntu をインストールすると systemd が有効になっているので sshd も自動起動できます。
既にインストール済みの環境で systemd を有効にしたい場合には /etc/wsl.conf に設定すれば有効になります。
確認の為、WSL(Ubuntu)からアクセスしてみましょう。
$ ssh localhost
外部からのアクセスを許可する
次は、外部からのアクセスを許可します。
WSL(ここでのWSLは仮想化システム、つまりWSL2を指しています)にて外部からのアクセスを行うには概ね3つの方法があります。
- ポートフォワードでWindowsからトラフィックを転送する
- ブリッジモードを使う
- ミラーモードを使う
ここではミラーモードを例にとります。他の方法も検索すれば設定方法が見つかると思います。
まず、ミラーモードを有効にします。先に紹介した Microsoft のドキュメントに記述があるのですが、この設定は .wslconfig に行います。
近々 GUI設定ツールが提供されるようなのでもっと手軽に操作できるようになるでしょう。
今現在はファイルを記述します。
PowerShell にて
PS C:\> notepad $env:USERPROFILE\.wslconfig
内容は以下を記述してください。既に .wslconfig が存在する場合には [wsl2] の下に networkingModeの行を追加してください。
[wsl2]
networkingMode=mirrored
メモ帳で新規ファイルを作成すると拡張子が .txt になるようなので修正しておきます。
PS C:\> ren $env:USERPROFILE\.wslconfig.txt $env:USERPROFILE\.wslconfig
一旦 WSLを終了します。
PS C:\> wsl --shutdown
スタートメニューから Ubuntu を起動すると Windows と同じ IPアドレスが設定された Ubuntu が起動します。
ファイヤーウオールを設定する
ミラーモードは Windowsファイヤーウオールで保護されているので外部からアクセスするには許可が必要です。これは Windows アプリケーション同様に Windowsセキュリティ(もしくはPowerShell)から設定します。
PowerShellから設定する場合には管理者権限のPowerShellで設定してください。
PS C:\> New-NetFirewallRule -DisplayName WSL_SSH -Profile private,public -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow
ネットワークプロファイルは Windows11 23H2 までは選択されているプロファイルですが、24H2では public 固定になっているようなので注意が必要です。
2024.07.01追記
24H2でネットワークプロファイルが変更になったと思ったのですが障害っぽい感じです。24H2でもWindws、WSL共に private となるケースもありました。
ファイヤーウオールを設定する際には、private, public 両方でポートを開放して確認した後に適宜正しい方の設定を残すようにしてください。
WSLを常駐させる
ここまでで外部からSSHアクセス可能なWSL環境が出来上がったのですが、一つ問題があります。WSLはターミナルの接続が切れると終了するようになっています。この為Windows起動時に立ち上げたとしてもすぐに終了してしまいます。
これを抑止する仕組みを組み込みます。
こういう systemdサービスを用意しました。WSLからWindowsコマンド実行中はターミナルの接続が切れても終了しない仕様を利用しています。
$ sudo curl -o /etc/systemd/system/wsl-persistent.service https://gist.githubusercontent.com/shigenobuokamoto/30dcee0e2d9045d1b18928d96178ed2e/raw/7f7b65568e6bc06ddc8b27eb44d566de806bcce0/wsl-persistent.service
$ sudo systemctl --now enable wsl-persistent
タスクスケジューラに登録する
仕上げとしてタスクスケジューラへ登録します。
タスクの作成から
全般:
●ユーザーがログオンしているかどうかに関わらず実行する
■パスワードを保存しない
トリガー:
スタートアップ時
操作:
プログラム: "C:\Program Files\WSL\wsl.exe"
引数: exit
Windowsを再起動すると WSLが自動起動していると思います。
Windowsにログインしなくても外部から SSHアクセスできます。
この設定のもう一つの効能として、使いたいときには既に WSLが起動しているという利点があります。WSL2は仮想マシンを使う関係上、起動には2~3秒かかります。そして最近では systemd の起動など初期化するものが多いので初回アクセス(起動を伴う)はわりと待たされます。しかし、Windowsとともに起動しておけばターミナルを接続するとすぐに利用できる状態になっています。