web-dev-qa-db-ja.com

一時的なSSHトンネルを設定するためのBashスクリプト

Cygwinでは、次のようなBashスクリプトが必要です。

  1. リモートサーバーへのSSHトンネルを作成します。
  2. トンネルを使用するローカルでいくつかの作業を行います。
  3. 次に、トンネルをシャットダウンします。

シャットダウンの部分に困惑しています。

現在、私は不完全なソリューションを持っています。 1つのシェルで次を実行してトンネルを作成します。

# Create the tunnel - this works! It runs forever, until the Shell is quit.
ssh -nNT -L 50000:localhost:3306 [email protected]

次に、別のシェルウィンドウで作業を行います。

# Do some MySQL stuff over local port 50000 (which goes to remote port 3306)

最後に、完了したら、最初のシェルウィンドウを閉じてトンネルを削除します。

次のような1つのスクリプトでこれをすべて実行したいと思います。

# Create tunnel
# Do work
# Kill tunnel

トンネルプロセスを追跡するにはどうすればよいですか?

122
jm.

これは、ssh「制御ソケット」を使用してきれいに行うことができます。すでに実行中のSSHプロセスと対話してpidを取得するには、それを強制終了します。次のように、「制御ソケット」(マスターの場合は-M、ソケットの場合は-S)を使用します。

$ ssh -M -S my-ctrl-socket -fnNT -L 50000:localhost:3306 [email protected]
$ ssh -S my-ctrl-socket -O check [email protected]
Master running (pid=3517) 
$ ssh -S my-ctrl-socket -O exit [email protected]
Exit request sent. 

My-ctrl-socketは作成される実際のファイルであることに注意してください。

この情報は 非常にRTFM OpenSSHメーリングリストの返信 から取得しました。

301
Chris McCormick

-fオプションを使用して、SSHにバックグラウンドを設定することはできますが、$!を使用してPIDを取得することはできません。また、トンネルを使用する前にスクリプトを任意の時間スリープさせる代わりに、-oで-o ExitOnForwardFailure = yesを使用すると、SSHはすべてのリモートポート転送が正常に確立されるのを待ってからバックグラウンドに配置できます。 psの出力をgrepして、PIDを取得できます。たとえば、使用できます

...
ssh -Cfo ExitOnForwardFailure=yes -NL 9999:localhost:5900 $REMOTE_Host
PID=$(pgrep -f 'NL 9999:')
[ "$PID" ] || exit 1
...

目的のPIDを取得していることを確認してください

19
Maine Guy
  • ssh&を使用してバックグラウンドに移動し、コマンドラインフラグを使用して反対側にシェルを作成しない(トンネルを開くだけ)ことを指示できます(-N)。
  • PID=$!でPIDを保存します
  • あなたのものをする
  • kill $PID

編集:$を修正しましたか?に$! &を追加しました

18
ZeissS

個別のタスクのために新しいシェルを起動することを好み、次のコマンドの組み合わせをよく使用します。

  $ Sudo bash; exit

または時々:

  $ : > sensitive-temporary-data.txt; bash; rm -f sensitive-temporary-data.txt; exit

これらのコマンドは、すべての作業を行えるネストされたシェルを作成します。終了したら、CTRL-Dを押すと、親シェルもクリーンアップして終了します。簡単にスローできますbash;kill部分の直前のsshトンネルスクリプトに入れて、ネストされたシェルからログアウトするとトンネルが閉じられるようにします。

#!/bin/bash
ssh -nNT ... &
PID=$!
bash
kill $PID
4
too much php

別の潜在的なオプション-expectパッケージをインストールできれば、すべてをスクリプト化できるはずです。ここにいくつかの良い例があります: http://en.wikipedia.org/wiki/Expect

2
Phil Pelanne

sshを最後に&で起動して、バックグラウンドに配置し、実行時にそのIDを取得できます。次に、完了したらそのIDのkillを実行する必要があります。

2
Valentin Rocher