我運行這些兩個命令始終連接到受防火牆保護的 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:在沒有背景的情況下運行:
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=>
我該如何進行這項工作?
答案1
當第二個命令運行時,第一個命令沒有時間建立隧道,因此給予「連線被拒絕」。
只是不使用&
而是使用該選項-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
答案2
@AB 的這個解決方案還可以用於在 dmz(互聯網或邊緣端點)和 mz(後端)之間創建一個“跳轉伺服器”,並透過 ssh 連接埠轉送隧道到後端主機,例如:
(必須使用firewall-cmd開啟所有對應連接埠)
desthost_ip是正在存取的服務的目標ip,它應該綁定有回應進程,即tomcat、webapp等。
在 dmz 邊緣:
ssh -o ExitOnForwardFailure=yes -f -L localhost_ip:port:desthost_ip:port user@dest_ip -i xyz.key sleep 15
所以,如果localhost也有公有網路ip;假設 desthost 正在運行基於 https 的服務,那麼這樣的事情就可以工作:
https://public_ip_of_localhost:port
這應該會顯示 desthost_ip:port 服務網頁。
ssh -o ExitOnForwardFailure=yes -f -L 192.168.1.199:8001:192.168.2.10:8081 [email protected] -i xyz.key sleep 15
和
https://192.168.1.199:8001
或者
https://public_ip_for_192.168.1.199:8001
將在 上調出服務頁面192.168.2.10:8081
。