WSL2にInternetからssh、を試してみる
自宅のWSL2の環境に外部からsshする必要があったので、構成をいろいろと考えていて、いったんできたので記録に残す。
構成
自宅のPCに直接sshログインするにはいろいろと敷居が高い(固定IPアドレスやらなにやら)ので、ここウン十年近く運用しているVPSを踏み台として、繋げようと思い立つ。
構成図はいうのような感じ。
+-----+
| |
| PC | @anywhere
| |
+-----+
|
[Internet]
|
v ssh
+-----+
| |
| VPS | @ホスティング事業者
| |
+-----+
|
[Internet]
|
v ssh
+-----+
| |
|Win/ | @自宅
| WSL2|
+-----+
まず、VPSとWSL2との間をなんとかして、繋げなければならない。
Remote Port Forwarding
こういうとに役立つのがsshのport forwarding機能。つまり、WSL2からVPSに対してsshコネクションを張る。このとき、remote port forwardingを行うことでそれを実現する。
つまり、以下のようにVPSのsshd(port: 22)にssh接続するわけだが、
+-----+
| |
| VPS |
| |
+-----+
^ port: 22(ssh)
|
|
|
+-----+
| |
|Win/ |
| WSL2|
+-----+
このときに、「VPSの特定portを叩くと、WSL2の特定portに繋がる」ように指示するのである。sshコマンドを叩いたWSL2から見るとVPSはremoteである。だから、remote port forwardingと呼ばれる(はず)。
以下の図のように「VPSのport: 10022 を叩くと、WSL2のport 22に繋がる」という接続をしたい場合、
+-----+
| |
| VPS |
| |
+-----+
| port: 10022
|
|
v port: 22(ssh)
+-----+
| |
|Win/ |
| WSL2|
+-----+
WSL2上で叩く ssh コマンドは以下となる。
ssh -R 10022:localhost:22 VPS
こうすることで、外部からVPSにssh loginさえできれば、VPS上で
ssh localhost -p 10022
と叩くことでWSL2に接続出来るようになる。
あ、もちろん、WSL2上で sshd が動いている前提です。
Port Forwardingの永続化
ここまででも繋がるのだが、sshのコネクションが切れる可能性があるということ。切れてしまうと、sshでWSL2に入れないので、Port Forwardingすることもできない。
Port Forawrding自体も常に動くように設定すれば解決ですね。
以前は、このようなサービスの永続化をするときには(私は)DJBのdaemontoolsを使用していましたが、それはもう過去。いまは systemdがありますから、それを使うことにしましょう。
こんな感じに serviceファイルを /etc/systemd/system 配下に作成します。
$ cat /etc/systemd/system/secure-tunnel@.service
[Unit]
Description=Setup a secure tunnel to %I
After=network.target
[Service]
ExecStart=/usr/bin/ssh -o StrictHostKeyChecking=no -F /etc/default/secure-tunnel.config -NT %i
# Restart every >2 seconds to avoid StartLimitInterval failure
RestartSec=5
Restart=always
[Install]
WantedBy=multi-user.target
sshコマンドの引数 -Fオプションで指定しているconfigファイルの中身は以下です。
$ cat /etc/default/secure-tunnel.config
Host VPS
HostName VPS.example.jp
Port 22
User VPS_user
IdentityFile /secure/path/to/VPS-id_ed25519
RemoteForward 10022 localhost:22
ServerAliveInterval 60
ExitOnForwardFailure yes
$
Hostname, Port, User, IdentityFileなども含めて例示ですので、適切に変更ください。
さて、この作成したサービスファイル secure-tunnel@.service を systemd に登録することでport forwardingの永続化がじつげんできます。
WSL2上で叩くコマンドは以下。
sudo systemctl enable --now secure-tunnel@VPS
ポイントはアットマークの後ろ。/etc/default/secure-tunnel.config で指定した Host の値(ここでは VPS)を指定します。これで、VPSに対してremote port forwardingするsshコマンドが叩かれることになります。そして、万が一、このsshコネクションが切れたとしてもsystemdが責任を持ってsshコマンドを叩いてくれます。
多段ssh
と、繋がるようになってめでたしめでたしですが、外部のPCからWSL2に接続するまでに2回ssh接続が必要となります。毎回毎回打ち込むのは大変なので、楽をしましょう。
外部のPCの ~/.ssh/config を以下のように設定します。
Host VPS
HostName VPS
User VPS_user
Port 22
IdentityFile ~/.ssh/id_ed25519
Host VPS-WSL2
HostName VPS-WSL2
User WSL2_user
ProxyCommand ssh -W localhost:10022 VPS
1つ目のHostは、単純なVPSへの接続の設定です。
2つ目のHostが、多段sshのための設定です。HostNameはknown_hostsへの記録のために使用され、UserはWLS上のユーザーです。ProxyCommandがVPSに接続し、localhost(=VPS)の10022ポートを叩けというものです。
ですので、以下のように外部のPCからsshコマンドを叩くと、
ssh VPS-WSL2
ProxyCommandの内容が評価されます。まず、VPSに繋がり、そのあと、localhost(=VPS)の10022ポートにフォワードされ、結果としてWSL2のsshに繋がっちゃう・・・というわけです。
便利ですね、Port Forwarding。
以上、わたしの備忘録にお付き合いいただきありがとうございました。