13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

リモートマシンのWSL2にSSH接続したい

Posted at

はじめに

概要

リモートのWindows PCで動かしているWSL2に、SSH接続して開発をおこなおうとしたが、
色々と詰まった点があったのでまとめる。

環境

クライアント
OS: Windows 10 Home 64Bit

リモートマシン
OS: Windows 10 Home 64Bit
WSL2: Ubuntu-20.04

なぜやろうと思ったのか

新しいPCを買ったので、新PCをきれいに保つために、旧PCを開発専用機に新PCは開発用途では使用しないようにしようと考えた。
しかし、わざわざ移動したり2つのPCを操作するのが面倒だったため、新PCから開発できるようにしたくなった。
そのため、新PCをあまり汚さずに新PCから開発するという目的を達成するために、新PCから旧PCにリモート接続して開発をしようと考えた。
Windowsアプリケーションの開発経験がないかつ、サーバが専門なのでWSL2上で開発しようと考えた。

開発の際はVS CodeのRemote Developmentという拡張機能を利用して開発をしようと考えたため、直接リモートマシンのWSL2にSSH接続ができるようにしたかった。

手順と詰まったとこ

ポートフォワーディングを利用する(失敗)

手順

環境構築の手順は以下の2つを参考にした。

どちらもやっていることはWSL2上でSSHサーバが起動するようにし、リモートマシンの22番ポートへの接続をWSL2に転送するために、ポートフォワーディングを起動時に設定するスクリプトをタスクスケジューラで起動時に実行しているだけである。
しかし、私の場合はこれらの手順では直接WSL2にSSH接続することができなかった。

詰まった点

どのようにSSH接続できなかったかと言うと、
リモートマシン自体へはSSH接続できるのだが、そこからWSL2へ転送されていなかった。

リモートマシンからwslコマンドではなく、sshコマンドでアクセスしようとするとアクセスできなかった。
そのため、SSHサーバが起動していないのかと考え、systemctl status sshを実行すると下記のようなエラー文が出た。

$ systemctl status sshd
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

システムがPID 1でブートしていないとのことだった。
調べてみると下記のようなWEBページが見つかった。
Windows 10 Home(WSL2)のUbuntuでsystemctlを利用する方法(systemdをPID1で動作させる方法)

この記事によるとgenieを導入すると解決できるとのことだったので試した。
ただし、この記事の手順ではうまくいかないため、genieのGitHubのREADME.mdを参考に導入した。

genieのインストール

まず依存パッケージであるdotnet-runtime-5.0を入れた。
上述のサイトを参考に、バージョンの部分だけ変更し実行した。

sudo apt-get install -y gpg
wget -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget https://packages.microsoft.com/config/ubuntu/20.04/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-5.0.4

続いて、GitHubのREADMEに書かれているhttps://arkane-systems.github.io/wsl-transdebian/ に従ってwsl-translinux repositoryを追加した。
この際、<distro>を下記に従って変更する。
(適当に読んで脳死で<distroをそのままにしたり、Ubuntu-20.04に変えて地味に詰まってたので気をつけて)

Debian 10 buster
Debian 11 bullseye
Debian 12 bookworm
Debian (testing) sid
Ubuntu focal
Ubuntu bionic

apt install apt-transport-https

wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg

chmod a+r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg

cat << EOF > /etc/apt/sources.list.d/wsl-transdebian.list
deb https://arkane-systems.github.io/wsl-transdebian/apt/ <distro> main
deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ <distro> main
EOF

apt update

上述のサイトではpackagecloud.ioにあるスクリプトファイルを利用していたようだが、下記の通り利用できなくなっているため上記を実行する。

(The packagecloud.io repository is now deprecated. If you are still using it, please update your system to use the repository above.)

これでパッケージのリポジトリを追加できたので、下記を実行してgenieをインストールする。

sudo apt update
sudo apt install -y systemd-genie

genieのインストール後は上述のサイトに従って、
.bashrcに下記を追加して、起動時にsystemdがPID1でない場合genie -sを実行するようにする。

.bashrc
if [ "`ps -eo pid,cmd | grep systemd | grep -v grep | sort -n -k 1 | awk 'NR==1 { print $1 }'`" != "1" ]; then
  genie -s
fi

結果

再度systemctl status sshdを実行すると下記のようにsystemctlが実行できることが確認できた。

systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Mon 2021-03-29 16:17:58 JST; 4min 5s ago
       Docs: man:sshd(8)
             man:sshd_config(5)

しかし、systemctlは実行できたもののポートフォワーディングがうまくいかず、WSL2まで届かずリモートマシンにつながってしまう

多段SSHで接続する(解決)

ここで、リモートサーバ上のDBをDBクライアントで確認するときのことを思い出し、多段SSHでの接続を試してみようと考えた。

いろいろ試しているうちにリモートマシン上でssh localhostとすることでWSL2に接続することが確認できた。
そのため、これを利用して多段SHHによる接続を試みた。
これにより、新PCからリモートマシンのWSL2にSSH接続することができ、
VSCodeのRemote Developmentでも問題なく利用することができるようになった。

前述の手順で設定したポートフォワーディングが効いていたのかと思ったが、どうやらlocalhostでWSL2にアクセスできるようになってたらしい。
今までの苦労はなんぞやと……
それまでは、WSL2のIPは起動するごとに変わり、WSL2に付けられたホスト名もサポートされていなかったため、前述の手順のようなことが求められたのだと思われる。
参考: 「WSL 2」最大の課題であった“localhost”問題が解決 ~「Windows 10」Build 18945 - 窓の杜

手順

下記のようにC:\Users\{UserName}\.ssh\configに追記する。

.ssh\config
Host            Remote
  HostName      {RemoteHostName}
  User          {RemoteUserName}
  IdentityFile  C:\Users\{UserName}\.ssh\id_rsa

Host            WSL2
  HostName      localhost
  User          {WSL2UserName}
  IdentityFile  C:\Users\{UserName}\.ssh\id_rsa
  ProxyCommand  ssh.exe -l %r -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null {RemoteHostName} -W %h:%p

まとめ

  • 以前はWSL2のIPは起動ごとに変わりホスト名解決もできず、IPをわざわざ調べるなりポートフォワーディングなど迂遠な方法をしないとSSH接続はできなかったが、現在はlocalhostでアクセスすることができる
  • このlocalhostForwardingというオプションは、以前は.wslconfigで指定しないといけないようだったが、現在はデフォルトで使えるっぽい
  • リモートのリソースにアクセスするときはやっぱ踏み台なんだなって思った
13
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?