使用 SSH 遠端埠轉發記錄動態分配的埠號
在 SSH 文件中,對於遠端埠轉發,它說:
如果埠參數為'0’,監聽埠將在伺服器上動態分配並在執行時報告給客戶端。當與 -O forward 一起使用時,分配的埠將被列印到標準輸出。
如何獲取/使用此埠號?
我可以看到它列印在標準輸出上,但我想將它記錄在一個文件中。
我有幾台電腦位於 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
但是我如何記錄那個埠號呢?
我假設我在如何訪問它方面遺漏了一些明顯的東西。
我可以在可以將埠號寫入文件的 shell 腳本中做一些事情嗎?
當您有多個伺服器執行此操作時,一個選項不起作用,它是檢查偵聽埠:
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
您首先連接主連接而不使用埠轉發:
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
該命令將告訴您埠。它將立即退出,這意味著您能夠擷取輸出。什麼都沒有失去。重複該命令,它將再次告訴您相同的埠,而不是將第二個埠轉發到相同的目的地。所以讓我們將輸出保存到一個變數中:
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
等。