Ssh-Tunneling

使用 SSH 遠端埠轉發記錄動態分配的埠號

  • May 4, 2020

在 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等。

引用自:https://unix.stackexchange.com/questions/584479