Reverse SSHによる、踏み台VPS経由のUbuntuマシンへのアクセスについての備忘録

## はじめに

Ubuntu 20.04LTSを載せたワークステーションを導入したので、そこへ外部からアクセスするための手法をまとめておく。同様にUbuntuを載せたRaspiにも全く同じ方法でアクセスしている。単純なSSH Remote Port Forwardの設定は良しとしても、自動起動を有効にするための`systemd`関係で少々ハマったので、自分用にその備忘録を残しておく。

## Reverse SSHを使うと何が嬉しいのか

**Gateway等をいじらなくても、内部のマシンに外部からアクセスできるようになること**。

## 接続構成

SSHは、以下のセッションを張る。

1. 最終的な接続先となるUbuntu WSをSSHクライアントとし、踏み台VPSの`sshd`へ常時接続 (`systemd`経由)
2. 接続元となるユーザをSSHクライアントとし、踏み台VPSの`sshd`へ接続
3. 踏み台サーバをSSHクライアントとして、1のSSH接続を通じてUbuntu WSの`sshd`へ接続

```
[Ubuntu WS] --(SSH Conn 1.)--> [踏み台VPS] <--(SSH Conn 2.)-- [User]
    |                              |
     <-------(SSH Conn 3.)---------
```

このとき、ユーザは2と3の接続を経由することでUbuntu WSとやり取りをすることになる。
キモとしては、1.のSSH接続においてRemote Port Forwardingを有効にすることで、踏み台VPSのlocal port経由でUbuntu WSにアクセス可能としているところ。

## まずは踏み台VPSの設定

`sshd`を立ち上げて、外部から公開鍵認証でアクセスできるようにしておく。TCP Keep Aliveとかの設定もした方が良いとは思うが今回はしていない。VPSでのSSHの設定は、[過去の備忘録](https://qiita.com/jqtype/items/126c33ea176f3ba506c3)に記載した時からほとんど変わっていない。

## Ubuntu WSからVPSへの常時接続設定

前提条件:

- Ubuntu WSから、踏み台VPSへSSHアクセスが可能
- Ubuntu WSへは、ローカルネットワークなどからはSSHで接続可能。
- 踏み台VPSとUbuntu WS共に、Reverse SSH専用のユーザ`rssh`を作成しておく。
  ※別に新規で作らず既存ユーザを使い回しても良い。

### `~/.ssh/config`の設定
ユーザ`rssh`のssh configを作成する。

```:~/.ssh/config
Host Fumidai-VPS                                ← 踏み台VPSの名前
  HostName              xxx.xxx.xxx.xxx         ← 踏み台VPSのIPアドレス
  Port                  50022                   ← 踏み台VPSのSSH Port
  ExitOnForwardFailure  yes
  ServerAliveInterval   60
  TCPKeepAlive          no
  IdentityFile          ~/.ssh/id_ecdsa_from_ws ← 踏み台VPSへのSSH接続に用いる秘密鍵
  User                  rssh                    ← 踏み台VPSのSSHユーザ名。rsshがいる前提。
```

### `systemd`経由での自動起動・自動再接続の設定
ユーザ`rssh`で、WSのブート時に自動でSSH接続されるようにする。

その際、SSH Remote Port Forwardingを有効にし、踏み台VPSの`localhost:2222`へのアクセスがUbuntu WSへ転送されるようにする。

#### 1. userレベルのsystemdの設定を作成

ユーザ`rssh`の`~/.config/systemd/user/reverse_ssh.service`を作成する。

```:~/.config/systemd/user/reverse_ssh.service
[Unit]
Description=Reverse SSH Tunneling
After=network.target auditd.service

[Service]
ExecStart=ssh -NR 2222:localhost:50022 Fumidai-VPS
Type=simple
Restart=always
RestartSec=1
StartLimitBurst=0

[Install]
WantedBy=default.target
```

#### 2. `XDG_RUNTIME_DIR`の設定

ユーザ`rssh`で`systemd`を有効にするのに、`~/.bashrc`ないし`~/.bash_profile`あたりに以下を追記しておく。

```:~/.bashrc
export XDG_RUNTIME_DIR=/run/user/`id -u`
```

追記した後は`$ source ~/.bashrc`をして変更を読み込んでおく。

コマンド`id`でわかる`rssh`のidのディレクトリが`/run/user/`以下にないようであれば、以下で`rssh`に対して`linger`を有効にしておく。

```:bash
$ sudo loginctl enable-linger rssh
```

#### 3. `systemd`登録

ユーザ`rssh`で`systemd`に`reverse_ssh.service`を登録する。

```:shell
$ systemctl --user daemon-reload
$ systemctl --user start reverse_ssh
$ systemctl --user enable reverse_ssh
```

### 4. 接続確認

踏み台VPSの**任意**のユーザより、以下のコマンドでUbuntu WSの**任意**のユーザ(e.g., `user_ws`)へSSH接続可能かどうかを確認する。

```:shell
$ ssh user_ws@localhost -p 2222
```

この例では、Ubuntu WSの`/etc/ssh/sshd_config`でパスワード認証が有効になっていると仮定している。もちろん設定すれば公開鍵認証も可能。

## ユーザクライアントの設定

`~/.ssh/config`にて`ProxyCommand`を設定することで、Ubuntu WSへ踏み台VPSを経由した認証を行う。`~/.ssh/config`に以下を追記。

```~/.ssh/config
Host Fumidai-VPS
  HostName       xxx.xxx.xxx.xxx
  IdentityFile   ~/.ssh/id_ecdsa_fumidai_vps ← 踏み台VPSでの公開鍵認証のための秘密鍵指定
  Port           50022
  User        　 user_vps                    ← 踏み台VPSのSSHユーザ

Host rssh
  ProxyCommand   ssh -W %h:%p Fumidai-VPS
  HostName       localhost
  IdentityFile   ~/.ssh/id_ecdsa_ubuntu_ws   ← Ubuntu WSでの公開鍵認証のための秘密鍵指定
  Port           2222
  DynamicForward 2222
  User           user_ws                     ← UbuntuWSのSSHユーザ
```

ここで、`user_vps`や`user_ws`、Reverse SSHを張っているユーザ`rssh`と異なっていても問題ない。

ここまで来れば以下のコマンドで接続可能なはず。

```:shell
$ ssh rssh
```

## 参考

- https://qiita.com/syoyo/items/d31e9db6851dfee3ef82
- https://qiita.com/miminashi/items/7904747c0353479c13ac
- https://blog.kamata-net.com/archives/12973.html
- https://blog.alprosys.com/2019/01/06/reverse-ssh-tunneling/