前置き
VSCodeのRemote DevelopなどでSSH接続の利便性が上がり、開発環境をLinux上に構築することが増えてきた昨今、SSHのPort Forwardingは開発する上でも便利に利用できる大変シャレオツな機能です。つーか普通にデバッグする時にVSCodeでもマッピングしてくれるしね。
ただ、その概念を覚えるためにググってみた時に、Webを結構探してみたのだけどもスッと入ってくる図が見つからなかったので、だったら自分で描いてしまおうということで、久しぶりの投稿と相成った。
SSH Config
SSH のPort Forwardingについては、単発であればコマンドラインでもできるけども、開発環境として長期的な利用も視野に入れてSSH Configを書くところから入りたい。
環境は以下のような構成だとします。
- SSHクライアント
- ホスト名:ssh-cl1
- IPアドレス:192.168.1.101
- SSHサーバー
- ホスト名:ssh-sv1
- IPアドレス:192.168.1.123
クライアントの ~/.ssh/config に以下のようなconfigを登録したとします。
Host ssh-sv1
HostName 192.168.1.123
User root
IdentityFile ~/.ssh/id_rsa
LocalForward 18080 127.0.0.1:8080
RemoteForward 15000 127.0.0.1:5000
なお、同じポート番号でバインドさせることが一般的かと思いますが、値が異なるほうが説明時にわかりやすいので敢えて変えてます。
よって、利用時には真似してローカルとリモートでポート番号を変える必要はありません。もちろん、ポート重複や複数台で登録したいからと、ポート番号を意図的に変えたい場合には参考にしていただければ幸いです。
あと、前方の「127.0.0.1:」は省きポート番号だけ記載しております。そのほうがわかりやすいと思うので。
Port Forwarding
順に見ていきましょう。
まず、LocalForwardの定義です。
これはSSH サーバーのポートをクライアント側(Local)に転送する機能です。
先に挙げたconfigの例では、サーバー側で起動している8080ポートをクライアントに18080ポートとしてバインドします。
次に、RemoteForwardの定義です。
これはSSH クライアントのポートをサーバー側(Remote)に転送する機能です。
先に挙げたconfigの例では、クライアント側で起動している5000ポートをサーバーに15000ポートとしてバインドします。
これでconfigとの対比もわかりますね。先に書かれたポート情報が転送先でのポート番号になり、あとに書かれている定義が転送元のどのポート番号かの定義になります。
動作確認
では、実際に挙動を確認してみましょう。
特定のポートでWebを簡単に起動させて確認できるように、どこのご家庭にでもあるPython環境で試します。え?無い??無料だからInstallすれば解決だよ。
まずはLocalForwarding。
サーバー側の準備はこれだけですね。SSH接続したらHTTPサーバーを8080で立てるだけ。
ssh ssh-sv1
python3 -m http.server 8080
今回のSSHクライアントはWindows10です。他の環境の方は適宜環境ごとの試験をしてください。
netstat -ano | Select-String ":18080"
Invoke-WebRequest http://localhost:18080
SSHサーバー上で立てたHTTPサーバーへのリクエストを、ローカルポートにバインドした18080宛に投げて、結果を受け取ることができました。
続いてRemoteForwarding。
クライアント側の準備はこれだけですね。HTTPサーバーを5000で立てるだけ。
python -m http.server 5000
今回のSSHサーバーはCentOS7ですので、netstatの代わりにssを使ってます。他の環境の方は適宜環境ごとの試験をしてください。
ssh ssh-sv1
ss -antu | grep "15000"
curl http://localhost:15000 | tail
SSHクライアント上で立てたHTTPサーバーへのリクエストを、リモートポートにバインドした15000宛に投げて、結果を受け取ることができました。