SSH隧道與埠轉發及內網穿透繫結本地埠
ssh是一種安全的傳輸協議,我一般使用就是在登陸伺服器或遠端執行命令,最近我意識到這是個強大的命令。
開講~
本地ssh隧道
工作中由於防火牆導致訪問某些網站或某些ftp連線超時,有什麼解決辦法呢。ssh隧道就是一種解決方式。
首先你需要了解一些資訊:
- 你自己的電腦不能訪問一個國外的ftp(10.10.10.10)。
- 你有一臺伺服器(20.20.20.20),伺服器可以訪問國外的ftp。
- 你和你的伺服器是可以互通的。
你當然可以先連線到個人伺服器進行檔案下載後通過其他方式再放到本地,但low,這裡可以使用ssh的隧道功能來實現。先看命令
ssh -CfNg -L 21:10.10.10.10:21 20.20.20.20
ftp localhost:21 # 現在訪問本地21埠,就能連線10.10.10.10的21埠了
# 至此就可以連線下載了。
先對引數做說明:
- -C:壓縮資料傳輸
- -f:ssh客戶端在後臺執行
- -N:不執行指令碼或命令,僅進行埠轉發
- -g:在-L/-R/-D引數中,允許遠端主機連線到建立的轉發的埠,如果不加這個引數,只允許本地主機建立連線。
- -L:做本地對映埠,被冒號分割的三個部分含義分別是
- 需要使用的本地埠號
- 需要訪問的目標機器IP地址
- 需要訪問的目標機器埠
- 用來建立隧道的中間機器的IP地址
遠端ssh隧道
由於公司內網機器使用公共的路由器出口進行上網,由於公司內部的裝置沒有自己的公網ip地址,所有也是個問題,但是ssh也能解決。
首先你需要有一些支援:
- 擁有一臺有外網IP的伺服器(20.20.20.20)。(這就夠了)
先上命令:
ssh -p 1207 -CfNg -R 2222:127.0.0.1:22 [email protected]
# 該命令在內網機執行
- -R:該引數的三個部分的含義分別是
- 對映到遠端機器使用的埠(2222)
- 需要對映的內部機器的IP地址(127.0.0.1)
- 需要對映的內部機器的埠(22)
- 最後的引數是外網連線的伺服器。
很簡單。基本都瞭解了。
ssh 隧道建立socket服務
如果我們需要藉助一臺中間伺服器訪問很多資源,一個個對映顯然不是高明的辦法。幸好,SSH客戶端為我們提供了通過SSH隧道建立SOCKS伺服器的功能。
通過下面的命令我們可以建立一個通過20.20.20.20的SOCKS伺服器。
ssh -N -f -D 1080 20.20.20.20 # 將埠繫結在127.0.0.1上
ssh -N -f -D 0.0.0.0:1080 20.20.20.20 # 將埠繫結在0.0.0.0上
ssh隧道使用問題及解決辦法
自動重連
隧道可能因為某些原因斷開,例如重啟,長時間沒有資料通訊而被路由器切斷等等。因此我們可以使用簡單的迴圈或supervisor
來控制隧道的重新連線。重連時要避免要求輸入密碼而卡死程式,對於密碼登陸可以採用sshpass
或免密登陸方式。如果通過其他程式控制隧道連線,應當避免將SSH客戶端放到後臺執行,也就是去掉-f引數。
保持長連線
有些路由器會把長時間沒有通訊的連線斷開。SSH客戶端的TCPKeepAlive選項可以避免這個問題的發生,預設情況下它是被開啟的。如果它被關閉了,可以在ssh的命令上加上-o TCPKeepAlive=yes來開啟。
另一種方法是,去掉-N引數,加入一個定期能產生輸出的命令。例如: top或者vmstat。
ssh -R 2222:localhost:22 [email protected] "vmstat 30"
檢查隧道狀態
有些時候隧道會因為一些原因通訊不暢而卡死,例如:由於傳輸資料量太大,被路由器帶入stalled狀態。這種時候,往往SSH客戶端並不退出,而是卡死在那裡。一種應對方法是,使用SSH客戶端的ServerAliveInterval和ServerAliveCountMax選項。 ServerAliveInterval會在隧道無通訊後的一段設定好的時間後傳送一個請求給伺服器要求伺服器響應。如果伺服器在 ServerAliveCountMax次請求後都沒能響應,那麼SSH客戶端就自動斷開連線並退出,將控制權交給你的監控程式。這兩個選項的設定方法分別是在ssh時加入-o ServerAliveInterval=n和-o ServerAliveCountMax=m。其中n, m可以自行定義。
如果將ip繫結到外網地址上
使用上面的方法,對映的埠只能繫結在127.0.0.1這個介面上。也就是說,只能被本機自己訪問到。如何才能讓其他機器訪問這個埠呢?我們可以把這個對映的埠繫結在0.0.0.0的介面上,方法是加上引數-b 0.0.0.0。同時還需要開啟SSH伺服器端的一個選項-GatewayPorts。預設情況下它應當是被開啟的。如果被關閉的話,可以在/etc /sshd_config中修改GatewayPorts no為GatewayPorts yes來開啟它。
~很煩。