存在するSSHドキュメント、リモートポート転送の場合、次のように表示されます。
ポートパラメータが「0」の場合、リスンポートはサーバーに動的に割り当てられ、実行時にクライアントに報告されます。併用する場合
-O forward
、割り当てられたポートは標準出力として印刷されます。
このポート番号をどのように取得または使用しますか?
stdoutで印刷されていることがわかりますが、ファイルに記録したいと思います。
NATファイアウォールの背後に複数のコンピュータがあり、すべて中央サーバーに接続され、SSH経由で再接続できるようにトンネルが設定されています。
現在これを行うには、独自のポート番号(12345など)を指定します。
ssh -R 12345:localhost:22 1.2.3.4
これは、次に接続して1.2.3.4
使用できるため機能します。
ssh -p 12345 localhost
ただし、記録を維持するのが難しく、最終的に接続が失敗した場合、再接続が機能しないことがあるため、各コンピュータにポート番号をハードコードしたくありません(ポートがまだ「使用中」なので)。
代わりに、次のものを使用できます。
ssh -R 0:localhost:22 1.2.3.4
報告される場所:
Allocated port 41191 for remote forward to localhost:22
しかし、そのポート番号をどのように記録しますか?
私はそれにアクセスする方法について明らかなものを見逃していると仮定します。
ポート番号をファイルに書き込むためにシェルスクリプトで実行できることはありますか?
1 つのオプションは、リスン ポートを確認することです。このオプションは、次のタスクを実行する複数のサーバーがある場合は機能しません。
sudo netstat -tpln | grep "127.0.0.1" | grep sshd
多少無駄なように見えますが、まずポート番号を取得して接続を切断してから使用できます。
port=`ssh -R 0:localhost:22 1.2.3.4 exit 2>&1 | grep 'Allocated port' | awk '/port/ { print $3 }'`;
ssh 1.2.3.4 record-port.sh "my-name" "${port}";
ssh -NTC -o ConnectTimeout=10 -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R "${port}:localhost:22" 1.2.3.4;
別のオプション(おそらく悪いかもしれません)は、ポートを直接ランダムに選択して使用する前に記録することです。
while true; do
port=$(((RANDOM %= 1000) + 2000));
ssh 1.2.3.4 record-port.sh "my-name" "${port}";
ssh -NTC -o ConnectTimeout=10 -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R "${port}:localhost:22" 1.2.3.4;
sleep 3;
done
答え1
まず、ポート転送を使用せずにプライマリ接続を接続します。
ssh -NMS /path/to/socket user@server
/path/to/socket
あなたが決めます。そこにソケットが作成されます。使用したいスクリプトから-f
。
次に、それを使用して-S /path/to/socket -O …
基本接続を制御します。たとえば、まだ有効であることを確認できます。
ssh -S /path/to/socket -O check placeholder
placeholder
大丈夫です。/path/to/socket
制御する基本接続を識別することです。
これでポート転送を要求できます。
ssh -S /path/to/socket -O forward -R 0:localhost:22 placeholder
このコマンドはポートを通知します。すぐに終了するので、出力をキャプチャできます。何も失われません。コマンドを繰り返すと、2 番目のポートを同じ宛先に転送するのではなく、同じポートを再度通知します。それでは、出力を変数に保存してみましょう。
port="$(ssh -S /path/to/socket -O forward -R 0:localhost:22 placeholder)"
これで変数を使用できます。
完璧になるために転送をキャンセルする方法は次のとおりです。
ssh -S /path/to/socket -O cancel -R 0:localhost:22 placeholder
デフォルトの接続を終了する前に明示的にキャンセルする必要はありません。次のように終了できます。
ssh -S /path/to/socket -O exit placeholder
最も基本的なスクリプトでは、上記のコマンドがすべて必要なわけではありません。以下が必要です。
ssh -fNMS /path/to/socket user@server
port="$(ssh -S /path/to/socket -O forward -R 0:localhost:22 placeholder)"
# anything you want, now you know the port
ssh -S /path/to/socket -O exit placeholder
処理する必要があるロジックがあるかもしれませんconnection refused
。
答え2
割り当てられたポートを取得するためにリモートサーバー上でスクリプトを実行したり、ソケットロックを生成する必要はありません。を持つことによって-o ExitOnForwardFailure=yes
オプション。
トンネルが確立されるのを待つので、"Allocated port ..."
コマンドが完了するとすぐにメッセージを受信できます。
これについてもっと学ぶ同様の質問に対するロイマの答え。