SSH を使用して一時的なポート フォワードを確立し、ローカル コマンドを実行してから終了し、ssh 接続を閉じます。
コマンドは、リモート サイトではなく、ローカルで実行する必要があります。
たとえば、DMZ 内のサーバーを考えてみましょう。マシンからのアプリケーションがポート 8080 に接続できるようにする必要がありますが、SSH アクセスしかありません。
これはどのように行うことができますか?
SSH を使用して一時的なポート フォワードを確立し、ローカル コマンドを実行してから終了し、ssh 接続を閉じます。
コマンドは、リモート サイトではなく、ローカルで実行する必要があります。
たとえば、DMZ 内のサーバーを考えてみましょう。マシンからのアプリケーションがポート 8080 に接続できるようにする必要がありますが、SSH アクセスしかありません。
これはどのように行うことができますか?
コマンドラインから OpenSSH を使用していると仮定すると....
SSH は、トンネルを維持し、可能な限りアクティブな状態を維持する接続を開くことができます。
ssh -fNT -Llocalport:remotehost:remoteport targetserver
または、サーバー上で一定期間実行されるものを SSH で起動することもできます。その時間帯はトンネルが開いています。リモート コマンドが終了した後も、トンネルがまだ使用されている限り、SSH 接続は維持されます。トンネルを 1 回だけ使用する場合は、短い「スリープ」を指定して、使用後にトンネルの有効期限が切れるようにします。
ssh -f -Llocalport:remotehost:remoteport targetserver sleep 10
ローカル側で実行されているスクリプトからトンネルを強制終了できるようにしたい場合は、シェルでバックグラウンドに設定し、pid を記録して後で強制終了することをお勧めします。Bourne シェルを含むオペレーティング システムを使用しているとします。
#/bin/sh
ssh -f -Llocalport:remotehost:remoteport targetserver sleep 300 &
sshpid=$!
# Do your stuff within 300 seconds
kill $sshpid
シェルを使用して ssh をバックグラウンド化するのが好みでない場合は、高度な ssh 機能を使用してバックグラウンド化されたプロセスを制御することもできます。hereで説明されているように、SSH の機能ControlMaster
とは、これを機能ControlPath
させる方法です。たとえば、以下を に追加します~/.ssh/config
。
host targetserver
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%r@%h:%p
これで、 への最初の接続targetserver
でコントロールが設定され、次のようなことができるようになります。
$ ssh -fNT -Llocalport:remoteserver:remoteport targetserver
$ ssh -O check targetserver
Master running (pid=23450)
$ <do your stuff>
$ ssh -O exit targetserver
Exit request sent.
$ ssh -O check targetserver
Control socket connect(/home/sorin/.ssh/cm_socket/sorin@192.0.2.3:22): No such file or directory
もちろん、これらのコマンドはシェル スクリプトにラップすることもできます。
次のようなスクリプトを使用できます (未テスト)。
#!/bin/bash
coproc ssh -L 8080:localhost:8080 user@server
./run-local-command
echo exit >&${COPROC[1]}
wait