'.ssh/conig' を使わない多段SSHポートフォワーディング


 はじめに

検証でたくさんのサーバに多段ポートフォワーディングしないと行けなくなったが、
多段sshのやり方を調べると '.ssh/conig'に設定を記載する方法ばかりヒットするのと
そもそも多段sshがなぜ可能なのか、といった中身の話の解説記事が見当たらなかったので調べた内容をここに記録する

TL;DR

・運用とかでいろんなサーバ管理してる人
・でセキュリティポリシー厳しくて踏み台挟まないと行けない人
・加えてブラウザアクセスしたいけどポートフォワーディング経由じゃないと通信経路がそもそもないみたいなカッチカチな環境のお相手をしている人
・どちらかというとWindowsな人向け

時間が無い方へ

# stepsv ... 踏み台サーバのホスト名 or IP
# targetsv ... 接続したいサーバのホスト名 or IP
# -t 強制的に仮想端末(tty)作る

ssh.exe -t -l user -i private.key -L 10443:localhost:10443 stepsv "ssh -L 10443:targetsv:443 targetsv"

https://localhost:10443/ にブラウザアクセスするとめでたく targetsv443 ポートと通信できる。

(適当な)解説

そもそもsshコマンドにはリモート先サーバのコマンドを実行する機能がある。
こんな感じ

ssh -l user remotesv "ls -l"

そしてポートフォワーディングという機能
ポートフォワーディングは一つ上のリモート先コマンドの実行の応用みたいなもので、
リモート先でパケットを発砲しちゃう、という機能
もちろんReceiveしたパケットは手元の端末に戻してくれる。

簡単に言えばsshで張ったトンネルの中に自由なプロトコルを流すことができる
こんな感じ

ssh -l user -L 443:localhost:443 remotesv 

上記コマンドはまず remotesv にsshして、remotesv から localhost443 宛にパケットを発泡せよ、って意味のコマンド
なので remotesvの 443と通信できる。

で、この2つの機能を組み合わえて、
リモート先でさらにポートフォワーディングしたら数珠つなぎで更に先のサーバと通信できるんじゃね?って予感がする
絵にすると次のとおり。 -> がポートフォワーディング

localpc(10443) -> (10443)stepsv(10443) -> (443)targetsv

そしてこの予感は正しい。

で出来上がったコマンドが

ssh.exe -t -l user -i private.key -L 10443:localhost:10443 stepsv "ssh -L 10443:targetsv:443 targetsv"

他所のブログで何段まで行けるか検証してないからわからない、とか書いてる人いますが、理屈は上記のとおりなので接続数に制限はない。
ワンライナーの文字数制限がコマンドプロンプトやらbashやらのシェルにあるなら、そっちの制限には書かるるかもね。

バッチ化してみた

portfoward_remotesv_443.batというファイルを用意して以下のコードを記述する。
このバッチファイルを実行するとファイル名に記載のサーバとポートに対してポートフォワーディングを張ってくれる

@echo off

echo %0
set FILENAME=%0

rem アンダーバー区切りでバッチファイル名を分割、接続先と接続先ポートを取得
FOR /F "tokens=2,3 delims=_." %%i in ('echo %0') do (
  set HOSTNAME=%%i
  set PORT=%%j
)

rem パラメタ出力
echo %HOSTNAME%
echo %PORT%
echo ssh.exe -t -l user -i private.key -L %PORT%:localhost:%PORT% targetsv "ssh -L %PORT%:%HOSTNAME%:%PORT% %HOSTNAME%"

ssh.exe -t -l user -i private.key -L %PORT%:localhost:%PORT% targetsv "ssh -L %PORT%:%HOSTNAME%:%PORT% %HOSTNAME%"

おわり。