TL;DR
- @yabeenicoさんの記事 wsl2でsshサーバを起動し、外部からそこに接続 (Qiita) をもとにssh接続のためポートフォワード設定をやった。
- 上の記事で省略されている、タスクスケジューラの設定をやってみた。
- これだけではsshできず!sshの自動再起動スクリプトを設定することでsshできるようになった。
はじめに
日本時間5/28にWindows10 2004 がリリースされ、wslがwsl2にアップデートされました
このwsl2ではネットワークの仕様がwsl1と大きく変更されておりwsl1と同じ方法でsshサーバーを有効にすることができません。このあたりの事情と解決方法についてはInsider Previewで既にwsl2を試されていた方々が検証してくれています。
特に、@yabeenicoさんの記事[1]ではwsl2のネットワーク仕様からssh設定の自動化までが大変分かりやすくまとめられて、本当に勉強になります。
ただ、[1]の記事では作成したスクリプトの自動起動方法について以下のように触れられているだけです。(まあ本題じゃないですからね。)
このスクリプトを、タスクスケジューラでログオン時に自動起動するように設定すれば完了です。
タスクスケジューラ is なに???
windows何もわからない自分はこの設定に数時間かかりました・・・
ということで、この記事では自分のような悲劇を再び生まないように、[1]をベースとしたwsl2のssh起動自動化方法を紹介します。
検証環境
- Windows: Windows 10pro 2004
- WSL2 (WSL1からバージョン変更したもの)
- Linuxディストリビューション: Ubuntu (20.04および18.04)
- Windowsの管理者アカウントを使用
wsl2側の設定
- とりあえずwslでsshが入っていることを確認しておきましょう。
$ sudo apt install -y openssh-server
-
以降の設定は[1]と基本的に同様です。
-
ポートフォワード用のシェルスクリプトをport-forward.shとして作成します
- [1]では/opt/binに配置していますが、自分は/opt/に配置しています。
-
ファイルを作成します。(例はvimの場合)
$ sudo vim /opt/port-forward.sh
- 以下を作成したファイルに入力します。
#!/bin/bash
IP=$(ifconfig eth0 | grep 'inet ' | awk '{print $2}')
netsh.exe interface portproxy delete v4tov4 listenport=22
netsh.exe interface portproxy add v4tov4 listenport=22 connectaddress=$IP
- rootにのみ実行権限を付けておきましょう。
$ sudo chmod 700 /opt/port-forward.sh
windows側のスクリプト作成
- 上のスクリプトをwslに叩かせるためのスクリプトを作成します。
- 自分はドキュメントフォルダ
%homepath%\Documents
にport-forward.bat
として作成しました。- もし複数のディストリビューションをインストールされている場合は設定したいものを
-d <ディストリビューション名>
で指定する必要があります。 - rootにのみ実行権限を付けているため、[1]の例とは異なりwslのrootユーザーとして実行する必要があります。
- もし複数のディストリビューションをインストールされている場合は設定したいものを
wsl -u root --exec /bin/bash /opt/port-forward.sh
rem Ubuntuというディストリビューションを指定するときは以下のコマンド。
rem wsl -d Ubuntu -u root --exec /bin/bash /opt/port-forward.sh
タスクスケジューラの設定
- ここからが本題です。
- スタートメニューで
スケジューラ
と入力するとタスクスケジューラが表示されるのでクリックしてください。
-
タスクの作成
をクリック
- この画面でタスクの詳細な設定を行います。
- 名前は
wsl-port-forward
としました。(適当でいいです。) - 今回はコンピューターがスタートアップ時点で(ログオン前に)タスクを実行させたいため
ユーザーがログオンしているかどうかにかかわらず実行する
にチェックをいれます。- なん
となくパスワードを保存しない
にチェックをいれます。
- なん
- ポートフォワーディングの実行には管理者権限が必要なため、
最上位の特権で実行する
にチェックを入れます。 - 構成を
Windows 10
に変更します。
- 名前は
- タスクの実行タイミングを指定します。トリガータブに移動し
新規
をクリックします。
-
タスクの開始
でプルダウンからスタートアップ時
を選択、OKで閉じます。
- 次に実行するスクリプトの指定です。操作タブに移動し、
新規
をクリックします。
- 操作は
プログラムの開始
のまま、参照
ボタンからプログラム/スクリプト
の欄に先ほど作成したport-forward.bat
のパスを入力します。OKで閉じます。
- これでタスクの登録は終了です。OKを押して
タスクの作成
ウィンドウを閉じてください。なお、作成したタスク一覧はタスクスケジューラのタスクスケジューラ ライブラリ
から確認できます。 - では再起動してsshができるようになっているか確認してみましょう!
問題発生!
- これでwsl2にsshできるようになる・・・ハズですが自分の環境ではうまくいきませんでした。
$ ssh <user名>@<IPアドレス>
kex_exchange_identification: Connection closed by remote host
- どうやらwsl2にまでは到達できているものの何らかの問題がsshサーバーで発生しているようです。
- いろいろ試したところsshのサービスをWindows起動時に再起動することでssh接続ができるようになりました。
- 実はwsl1の頃も同様の処理が必要でした。2. Windows Subsystem for Linuxにssh接続する (Qiita) で詳しく説明されています。
-
systemctl enable ssh
などでwsl側での自動起動を有効にしても問題は解消しませんでした。
-
- 実はwsl1の頃も同様の処理が必要でした。2. Windows Subsystem for Linuxにssh接続する (Qiita) で詳しく説明されています。
sshサーバー再起動自動化
-
この操作も自動化したいので、sshのサービスをWinodws起動時に再起動するスクリプトを作成、タスクスケジューラに設定していきます。
-
先ほどと同様に、ドキュメントのフォルダ
%homepath%\Documents
にwsl2-ssh-restart.bat
として以下のスクリプトを保存します。- ここでも複数のディストリビューションを使用されている場合はディストリビューション名の指定
-d <ディストリビューション名>
が必要です。 - 3. Windows10のWSL上にあるServiceを簡単に自動起動させる(Qiita) の記事でwsl1向けに紹介されているものを流用しています。
- ここでも複数のディストリビューションを使用されている場合はディストリビューション名の指定
@echo off
wsl -u root -- service ssh restart
rem ubuntuというディストリビューションを指定するときは下のコマンド。
rem wsl -d Ubuntu -u root -- service ssh restart
- 先ほどと同様にタスクスケジューラに設定します。
- この操作は管理者権限が必要ないので、
最上位の特権で実行する
のチェックはつけません。
- 操作 -> 新規 と進みます。実行するスクリプトとして
wsl2-ssh-restart.bat
のパスを入力します。 OKで閉じます。
-
トリガー
->新規
と進み、からスタートアップ時にタスクを起動するよう設定します。
- これで設定は終了です!お疲れさまでした。
- 再起動してしばらく待ってからsshを実行してみましょう!
- sshできるようになるまで1分ほど時間がかかります。
うまくいかないときは
- コマンドプロンプトやpowershellを管理者権限で起動したうえで、作成した2つのスクリプト
port-foward.bat
とwsl2-ssh-restart.bat
を手で実行してみましょう。スクリプトに問題がなければこれでssh接続ができるようになるはずです。 - ポートフォワードができているか不安な場合は[1]で紹介されている以下のコマンドをPowerShellで実行することでポートフォワードの状態を確認できます。
- 以下のようになっていればOKです。(アドレスは違ってOK)
> netsh.exe interface portproxy show v4tov4
ipv4 をリッスンする: ipv4 に接続する:
Address Port Address Port
--------------- ---------- --------------- ----------
* 22 172.29.240.72 22
-
設定したタスクが実行されているかはタスクスケジューラの
タスクスケジューラ ライブラリ
から確認できます。 -
低スペックなPCだとwslが起動する前にタスクが実行されてしまうことがあります。タスクスケジューラのトリガーの設定で、5分 ~ 15分程度の遅延時間を設定してもいいかもしれません。
まとめ
- [1] の記事で紹介されているスクリプトをタスクスケジューラで自動実行する方法についてまとめました。
- 自分の環境(wsl1からwsl2へアップグレードした環境)によるものかもしれませんが、sshの再起動も必要でした。
- @yabeenicoをはじめ記事を引用させていただいた方々、素晴らしい記事を本当にありがとうございました!
それでは楽しいwsl2ライフを!
引用させていただいた記事
- 1. wsl2でsshサーバを起動し、外部からそこに接続(Qiita)@yabeenico
- 2. Windows Subsystem for Linuxにssh接続する (Qiita)@ezmscrap
- 3. Windows10のWSL上にあるServiceを簡単に自動起動させる(Qiita)@nashi2603
変更履歴
- (6/6) port-foward用のバッチファイルを一部修正(bash -> /bin/bash)