ポートフォワーディングの多段転送のやり方

# <font color="#4472C4">はじめに</font>
いきなりですが、例えば、次のようなネットワーク構成の環境があるとしましょう。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/74be0f62-5a54-429d-8ce2-64f2834e6743.png)

そして、このネットワークには次の制約があります。
1. 自端末からAPサーバー(Linux2)には踏み台(Linux1)を踏まないと接続できない。
1. 踏み台サーバー(LInux1)からDBサーバー(DB)には接続できない。

IT業界に従事されているエンジニア、コンサルタントの皆さまであれば、一度は目にしたことがあるのではないでしょうか。
こうなると、DBに用がある場合、まずは踏み台サーバーを経由してAPサーバーにログインし、APサーバーの上でDBに接続、作業する必要があります。

そうなると、大体の場合、LinuxやUnixだとGUI環境がなく、CLIで作業することになります。
別にいいのですが、大量のデータをSELECTしたいときなど、とても見にくくなるので、できれば、自端末からGUIアプリケーションを使って効率的に作業したいですよね。

そんな時は、Teratermにもできるポートフォ、ネットワークに一時的な導線を作ってあげれば、自端末からDBサーバーに対する作業ができます。
また、ネットワークの上でもちゃんと踏み台、APサーバーを経由しているので、問題もありません。
※とは言いつつも、気軽にデータが触れることが問題だ！と云う場合もありますので、組織のポリシーに従いましょう。

今回は、そんなときの作業効率化を図るための記事です。
ただ、この後、具体的なやり方を語っていきますが、面倒なことをしなくても、このような構成を前提に、A5:SQL Mk-2など、トンネル機能があるSQLツールもありますので、それぞれのツールの機能で事足りる場合はそれらを使うのがいいでしょう。

# <font color="#4472C4">手順概略</font>
まずは、ざっくりとした手順を紹介します。
1. 踏み台サーバーからAPサーバーへのトンネルを作る。
1. 1で設定したトンネル経由でAPサーバーに接続する。
1. APサーバーからDBサーバーへのトンネルを作る。
1. 3で作ったトンネル経由でDBサーバーに接続する。

このように、複数の端末、サーバーでネットワークを転送することをポートフォワーディング（ポート転送）と云い、今回は複数のサーバーをまたいで転送していくので、「ポート多段フォワード」と云います。

# <font color="#4472C4">手順詳細</font>
ここからは、詳細な手順を解説していきます。

## 踏み台サーバーからAPサーバーへのトンネルを作る
まずは、踏み台サーバーからAPサーバーを結ぶトンネルを作ります。
ポートフォワーディングを使って仮想的にネットワークを結ぶことを「トンネルを作る」とも云います。
1段でトンネルを作るやり方は、当記事以外にもたくさんの参考記事があり、難しくありません。

トンネルを作るイメージです。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/3f4ba55b-06e0-4986-a068-f8b38e8a65b0.png)


図上、トンネルを丸い筒でイメージしています。
トンネルを作ることで、1つのコマンドで、端末からAPサーバーに接続できるようになります。

Teratermで踏み台サーバーにログインします。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/1206120d-e890-4655-984f-b812a2934020.png)

設定 ＞ SSH転送(O)より、ポートフォワーディングを設定します。
このとき、ローカルのポートは未使用のポートであれば何番でも構いません。
リモート側ホストのポートはSSHの22番を指定します。
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/e84a1bd5-fd87-4a8b-9dcd-778e99088795.png)

これで、踏み台、APサーバー間のトンネルができました。

## 1で作ったトンネル経由でAPサーバーに接続する
作ったトンネルでAPサーバーに接続します。
ここの理屈はよくわかっていないのですが、踏み台サーバーからAPサーバーに普通に接続するのではなく、トンネル経由で接続します。
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/9365a768-01f4-4d13-ab00-841825d21cc6.png)

ここでは、ログインするだけで、ポート転送の設定はしません。
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/9882f0a9-eba5-4db4-a20f-0923083d7438.png)

## APサーバーからDBサーバーへのトンネルを作る
これだけだと、まだAPサーバーまでしかトンネルが開通していないので、APサーバーからDBサーバーも開通させます。
![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/9a694c9a-b314-48a0-9f8f-0cc2cdf59a5f.png)

ここでは、sshこコマンドのオプションを使ってトンネルを作ります。
また、これも理屈はよくわかっていないのですが、自分から自分にポート転送を設定し、それを使ってトンネルを作ります。

踏み台サーバーにログインします。
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/8062ce61-0d1f-4f9f-96f8-fe1f3d753ddf.png)

自分から自分へのポートフォワーディングを設定します。
![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/cb1bbc1c-51a2-4126-bd2a-c4a603f87691.png)

最後に、転送のオプションをいれたコマンドでトンネルを作ります。
コマンド:`ssh root@Linux2 -L 10004:192.168.1.2:1521`
![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/4eeee5b1-8936-4f1d-9084-2c8ccae55b3c.png)

# <font color="#4472C4">DBに接続</font>
ここまでで、DBサーバーまでに通るトンネルは全て開通しました。
このトンネルを使ってDBサーバーに接続します。
接続には、自分から自分に設定したポートフォワーディングのポートを指定します。

こちらはOracleに接続するイメージです。
![011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/d7604c1a-56cc-436e-81d2-3c4d5fbcd9aa.png)

接続できました！
![012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189344/2b1380fb-293c-4392-8783-ff3885e6346c.png)

これで、好きなツールを使って、効率よく作業ができますね。
DB以外にも、多段フォワードを使ってできることは多いので、ネットワーク的な壁にぶつかった場合は、こちらの方法を試してみてください。

# <font color="#4472C4">おまけ</font>
これは完全に自分のメモなんですが、これまでの一連の作業をダブルクリックするだけで実行できるTeratermマクロを残しておきます。

```terminal:踏み台サーバからAPサーバーへのポートフォワーディング
;;=====================================================================
;; 接続先などのホスト情報をまとめる
HOSTADDR = 'localhost'
USERNAME = 'Linux1User'
PASSWORD = 'password'
;;=====================================================================

;; コマンドオプション組立て
COMMAND = HOSTADDR
strconcat COMMAND ':22 /ssh /2 /auth=password /user='
strconcat COMMAND USERNAME
strconcat COMMAND ' /passwd='
strconcat COMMAND PASSWORD

;; ウィンドウの色を変えたり設定を読み込ませる
strconcat COMMAND ' /F='
strconcat COMMAND 'C:\Users\Taro\TERATERM.ini

;; ポート転送を設定する
TRANSFER_SVR1 = 10003:Linux2:22
sprintf2 TRANSFER_SVR '%S' TRANSFER_SVR1

strconcat COMMAND ' /ssh-L'
strconcat COMMAND TRANSFER_SVR

;; 接続
connect COMMAND

end
```

```terminal:APサーバにログイン
;;=====================================================================
;; 接続先などのホスト情報をまとめる
HOSTADDR = 'localhost'
USERNAME = 'Linux2User'
PASSWORD = 'password'
;;=====================================================================

;; コマンドオプション組立て
COMMAND = HOSTADDR
strconcat COMMAND ':10003 /ssh /2 /auth=password /user='
strconcat COMMAND USERNAME
strconcat COMMAND ' /passwd='
strconcat COMMAND PASSWORD

;; ウィンドウの色を変えたり設定を読み込ませる
strconcat COMMAND ' /F='
strconcat COMMAND 'C:\Users\Taro\TERATERM.ini

;; 接続
connect COMMAND

end
```

```terminal:自分から自分の転送設定からSSH
;;=====================================================================
;; 接続先などのホスト情報をまとめる
HOSTADDR = 'localhost'
USERNAME = 'Linux1User'
PASSWORD = 'password'
;;=====================================================================

;; コマンドオプション組立て
COMMAND = HOSTADDR
strconcat COMMAND ':22 /ssh /2 /auth=password /user='
strconcat COMMAND USERNAME
strconcat COMMAND ' /passwd='
strconcat COMMAND PASSWORD

;; ウィンドウの色を変えたり設定を読み込ませる
strconcat COMMAND ' /F='
strconcat COMMAND 'C:\Users\Taro\TERATERM.ini

;; ポート転送を設定する
TRANSFER_SVR1 = 10004:127.0.0.1:10004
sprintf2 TRANSFER_SVR '%S' TRANSFER_SVR1

strconcat COMMAND ' /ssh-L'
strconcat COMMAND TRANSFER_SVR

;; 接続
connect COMMAND

;; コマンド入力のプロンプトが出たらコマンド投入
wait '$'
ssh root@Linux2 -L 10004:192.168.1.2:1521
;; このコマンドだとLinux2にログインする際のパスワード入力は必要

end
```

# <font color="#4472C4">おわりに</font>
筆者が試したときはこの手順を踏まないといけなかったのですが、理屈のわからない手順もありましたので、もっとシンプルに解決できるやり方があるかもしれません。
ご存じの方はぜひぜひコメントください。

# <font color="#4472C4">参考文献</font>
当記事を執筆するにあたり、お世話になった文献です。

https://yoneyore.hatenablog.com/entry/2016/10/09/211617
https://qiita.com/yuuki4891/items/bfe5c1d201524c6d1827