次のProxyCommandの詳細な説明とそのタスクの具体的な詳細を探しています。可能であれば、徹底的に分析して改善するのに役立ちますか?他に何もない場合は、読みやすさのためです。
ProxyCommand ssh gatewayserver 'exec 3<>/dev/tcp/targetserver/22; cat <&3 & cat >&3;kill $!'
答え1
/dev/tcp
(私のシステムにはデバイスはありませんが、次のセクションに接続されているTCPソケットをbash
割り当てる処理機能が組み込まれているようです。)/host/port
したがって、sshエージェントコマンドは、gatewayserver
次のことを行うシェルを安全に実行します。
exec 3<>/dev/tcp/targetserver/22
つまり、ファイル記述子3にソケット(targetserver
/に接続されている)を接続しますport
。それから:
cat <&3 & cat >&3; kill $!
これは、ファイル記述子0
(入力)と1
(出力)とファイル記述子(入力と出力)3
の間の双方向リダイレクト(2つの別々のプロセスを使用する)方法です。他のプロセスが返された後、kill $!
バックグラウンドプロセスを終了します。cat <&3
cat >&3
これらすべては、より標準的な内容にすぎません。
ProxyCommand ssh gatewayserver "tcpconnect targetserver port"
コマンドの代わりに/dev/tcp
(または)関数を使用してください。bash
tcpconnect
詳細は:
SSHが使用するプロキシコマンドは、リモートホストへの接続方法を定義するために使用されますtargetserver
(Sshプロトコルが使用されるため、暗号化は実際には必要ありません)。超過このチャンネル)。私たちの場合は、そのターゲットホストへの接続を確立しようとしています(おそらくファイアウォールが直接gatewayserver
接続をブロックしているため)。targetserver
だからプロセス
ssh gatewayserver 'exec 3<>/dev/tcp/targetserver/22; cat <&3 & cat >&3;kill $!'
始まります:
- filedescriptor(fd)
1
(標準出力とも呼ばれる)は、SSHクライアントがターゲットホストにデータを送信するために使用されます。 - fd
0
(標準入力とも呼ばれる) は、SSH クライアントがリモートホストからデータを読み取るために使用されます。
ssh gatewayserver
最初のホップでゲートウェイに初めて接続するために使用されます。ssh
元のホスト上のプロセスのfd / fdを、0
ゲートウェイホストで実行されているシェルのfd / fdに渡す新しいシェルをこのホストで起動します。このシェルで実行されるコマンドは次のとおりです。1
0
1
exec 3<>/dev/tcp/targetserver/22; cat <&3 & cat >&3;kill $!
コマンドがないと、exec
何もしません。シェル自体の次のリダイレクトのみを適用します。一般的なリダイレクトは次のとおりです。
n>file
fdをn
次にリダイレクトします(省略した場合はfile
書き込み専用で開く)。n
1
n<file
fdをn
次にリダイレクトします(省略した場合はfile
読みやすいように開きます)。n
0
n<>file
fdを(読み取りおよび書き込み用に開く)n
にリダイレクトします。file
n>&m
または に指定するn<&m
と、n<>&m
fd はn
以前に fd が指したファイルにリダイレクトされますm
。
ここでは以下が使用されます。
exec 3<>/dev/tcp/targetserver/22
これは、新しく作成されたfdを3
非常に特別なファイル/dev/tcp/targetserver/22
(実際のファイルではないがbash自体が理解するファイル)にリダイレクトします。ここでbashはtargetserver
ポート22
(サーバーが見つかると予想される場所)で通信するためにソケット(tcpプロトコルを使用する特別なファイル)を生成し、sshd
ファイルはfdで開きます(読み取りおよび書き込み用)3
。
これで、データをfd 0
(クライアントのデータ)に「ポンプ」し、それをfd 3
(宛先サーバーへの接続)に送信する必要があります。また、fdのデータを「ポンピング」3
し、それをfd 1
(クライアントの結果)に送り返すことで、逆方向通信を保証する必要があります。これら2つの「ポンプ」は、cat
2つのプロセスを使用して設定される。
cat <&3
(3
シェルのfdから読み書きします1
。)cat >&3
(0
シェルのfdから読み書きします3
。)
どちらもcat
並列に実行する必要があるため、1つはバックグラウンドで実行する必要があります。ここでは、fd 0
(おそらくtty)から読むことが前景に残りたいと思います。これは以下を提供します:
cat <&3 & #run in the background
cat >&3; kill $!
kill $!
バックグラウンドプロセスを終了するために使用されます($!
最後のバックグラウンドプロセスのpidに拡張されます)。このようにしてクライアントがクラッシュすると、フォアグラウンドプロセスが終了し、killが実行され、最後のプロセスも終了します。
それだけです!私たちは次の橋を建設しました。
ソースホスト - (ssh)→ゲートウェイ - (ポンプ+ソケット)→ターゲットサーバー(ポート22)
一つssh user@targetserver
について起源ホストは次に接続できます。ターゲット先生はこの橋を通り過ぎます!