踏み台サーバ経由で SSH ポートフォワーディングする手順

アクセスしたい。

そして、「手元の PC ⇔ 踏み台サーバ ⇔ 目的のサーバ」という経路でポートフォワーディングして、「目的のサーバ」が 8080 ポートで公開している Web サーバを、「手元の PC」の 18080 ポートで受け取って閲覧してみる。

目次

まずは経路確認

まずは、各サーバに入れることを確認する。

# 手元の PC から踏み台サーバに SSH 接続する
$ ssh -i ~/.ssh/id_rsa -p 22 bastion_user@129.000.0.00

## 踏み台サーバに接続できた

## 踏み台サーバから目的のサーバに SSH 接続する
$$ ssh -i ~/.ssh/id_rsa -p 22 target_user@target-host

### 目的のサーバに接続できた。目的のサーバの 8080 ポートには Web サーバが立っているテイ
$$$ curl http://localhost:8080/
Hello World, This server is TARGET-HOST.

ココが上手くいかない場合は、クラウド側のファイアウォール設定で22番ポートを封じている可能性がある。

このやり方の場合、「踏み台サーバ」から「目的のサーバ」に接続する際の鍵ファイル (~/.ssh/id_rsa) は、「踏み台サーバ」内に置いておく必要がある。

SSH 接続をポートフォワーディングしてみる

続いて、SSH 接続をポートフォワードしてみる。

# 手元の PC から踏み台サーバに接続し、「踏み台サーバから目的のサーバ」への接続経路を、ローカルの 10022 ポートに転送する
$ ssh -i ~/.ssh/id_rsa -p 22 bastion_user@129.000.0.00 -L 10022:target-host:22

このコマンドを実行すると、踏み台サーバに SSH ログインした状態になるので、このターミナルタブはそのままにして、別のターミナルタブで、次のようにアクセスする。

$ ssh -i ~/.ssh/id_rsa -p 10022 target_user@localhost

このようにすると、「手元の PC の 10022 ポート」を指定しているが、ポートフォワード設定によって「目的のサーバ」に SSH ログインできる。

この際、「目的のサーバ」に接続するために使っている鍵ファイルは、「手元の PC」にある ~/.ssh/id_rsa になるので、「踏み台サーバ」には秘密鍵ファイルを置いておく必要がなくなる。

このポートフォワード設定を ~/.ssh/config に書く

以上の2つのコマンドを ~/.ssh/config に起こしてみると、以下のようになる。

Host forward1
  HostName      129.000.0.00
  User          bastion_user
  Port          22
  IdentityFile  ~/.ssh/id_rsa
  LocalForward  10022 target-host:22

Host forward2
  HostName      localhost
  User          target_user
  Port          10022
  IdentityFile  ~/.ssh/id_rsa

ファイルを設定したら、$ ssh -fN forward1 を実行したあと、別タブで $ ssh forward2 と実行すると、目的のサーバに接続できる。

どこに「踏み台サーバ (bastion)」の情報を書くか、「目的のサーバ (target)」の情報を書くか、どこでフォワードするポート番号を指定するのかを整理して理解しておこう。

「目的のサーバ」の Web サーバのポートをローカルにポートフォワードする

ココまででポートフォワーディングのやり方が分かったと思うので、「目的のサーバ」が 8080 ポートで公開している Web サーバを、「手元の PC」の 18080 ポートで受け取って閲覧してみる。

$ ssh -i ~/.ssh/id_rsa -p 22 bastion_user@129.000.0.00 -L 18080:target-host:8080

このように叩くと踏み台サーバにログインした状態になるので、このターミナルタブはこのままに、ブラウザで次の URL にアクセスする。

ローカルの 18080 ポートにアクセスすると、踏み台サーバを経由して、「目的のサーバ」の 8080 ポートの内容が閲覧できる。最初に書いた例で行くと「Hello World, This server is TARGET-HOST.」なんていうメッセージが見えている、というワケだ。

# curl で見てみても良い
$ curl http://localhost:18080/
Hello World, This server is TARGET-HOST.

ポートフォワードをコマンド1発でバックグラウンド実行する

先程のやり方だと、踏み台サーバにログインした状態のターミナルタブが残ってしまう。コレではタブが邪魔臭いので、コマンド1発で実行したら、バックグラウンド実行してくれるようにしてみる。

$ ssh -i ~/.ssh/id_rsa -p 22 bastion_user@129.000.0.00 -L 18080:target-host:8080 -N -f -o ServerAliveInterval=60

前半の -i-p・踏み台サーバ情報、-L オプションによるポートフォワード指定までは全く同じ。違いは -N 以降のオプション群だ。

コレを指定して実行すると、SSH 接続後にプロンプトが元に戻り、SSH 接続のプロセスがバックグランド実行される。MacOS の場合は「ターミナル.app」自体を終了させても、http://localhost:18080/ にアクセスできる。

裏側ではずっとポートフォワードした状態になるので、ポートフォワードを終了する場合は、$ ps x | grep ssh でプロセス ID を調べ、kill してやる。


以上だ。