web-dev-qa-db-ja.com

シェルスクリプトの一部としてバックグラウンドでトンネルを実行する方法

私はこれらの 2つのコマンド を実行して、ファイアウォールの背後で保護されているaws上のrdsインスタンスに接続します(ec2インスタンスを介してトンネルするため)。

コマンド1:トンネルを開く(バックグラウンドで実行)

ssh -N -L port:Host:5432 user@$ip -i ~/.ssh/key.pub &

コマンド2:トンネルポートを介してデータベースに接続します:

PGPASSWORD=password psql dbname -U user -h ip_address -p port;

素晴らしいですが、両方を1つの関数にまとめたいと思います。しかし、私には何もうまくいきませんでした:

試行1:バックグラウンドスタッフなしで実行:

function db()
{
    ssh -N -L port:Host:5432 user@$ip -i ~/.ssh/key.pub &
    PGPASSWORD=password psql dbname -U user -h ip_address -p port;
}

単に私にこれを伝えます:

$proddb
[1] 62924
psql: could not connect to server: Connection refused
    Is the server running on Host "127.0.0.1" and accepting
    TCP/IP connections on port 6666?

最初のコマンドはバックグラウンドで実行されていますが:

ps aux | grep Host
(standard input):435:abdullah         62924   0.0  0.0  4315660   5828 s006  S     3:06PM   0:00.03 ssh -N -L port:Host:5432 user@$ip -i ~/.ssh/key.pub

そして、その直後に次のコマンドをすぐに実行した場合..私はうまくデータベースに接続します!

PGPASSWORD=password psql dbname -U user -h ip_address -p port;
user=>

これを機能させるにはどうすればよいですか?

4
abbood

最初のコマンドには、2番目のコマンドが実行されたときにトンネルを確立する時間がなかったため、「接続が拒否されました」。

&は使用せず、代わりにオプション -f を使用してください。

-f
コマンド実行の直前にバックグラウンドに移動するようにsshに要求します。これは、sshがパスワードまたはパスフレーズを要求するが、ユーザーがバックグラウンドでそれを望んでいる場合に役立ちます。これは、-nを意味します。リモートサイトでX11プログラムを開始するための推奨される方法は、ssh -f Host xtermのようなものです。
ExitOnForwardFailure構成オプションが「yes」に設定されている場合、-fで開始されたクライアントは、すべてのリモートポート転送が正常に確立されるのを待ってから、バックグラウンドに置かれます。

これらすべてをまとめて、関数のssh行を次のように置き換えます。

ssh -o ExitOnForwardFailure=yes -f -N -L port:Host:5432 user@$ip -i ~/.ssh/key.pub

この方法で関数を複数回実行しても、(multiple-1)無駄なsshが実行されたままになることはありません。

-Nを短いリモートスリープコマンドに置き換えることもできます。そうすれば、削除する必要がある場合に検索する必要のある、長期間有効なアイドルsshコマンドはなくなります。 sshはトンネル使用の終了を待ってから終了するため、短い遅延は問題になりません。

ssh -o ExitOnForwardFailure=yes -f -L port:Host:5432 user@$ip -i ~/.ssh/key.pub sleep 15
5
A.B