1. 程式人生 > >How系列-公網如何ssh到內網的Linux系統中?

How系列-公網如何ssh到內網的Linux系統中?

斷開 ctrl+ stat avg 密鑰 tunnel 密鑰對 linu ssh -n

起因

最近碰到一件事:B同學在他電腦的Ubuntu虛擬機中學習搭建服務器碰到了問題,要我幫他看下。我總不能一個QQ遠程桌面連過去,那樣操作會卡到崩潰。ssh過去是最好的方法,不過他的電腦跟我不在一個局域網,又是虛擬機,要怎麽連過去呢?

怎麽解決?

有兩種方法:

  1. 通過一臺公網服務器,通過ssh命令建立反向隧道
  2. 通過第三方的ngrok服務建立tcp反向隧道

它們的原理都是使用了反向隧道,原理見下圖:

技術分享圖片

正向與反向的區別在於正向連接是使用者通過自己的客戶端操作服務器資源;反向連接是使用者通過服務器操作客戶端資源。結合上圖理解:

  • 客戶端1ssh連接公網服務器時,所有的操作都在服務器上,所以稱為正向隧道
    ;
  • 客戶端2ssh連接公網服務器的2244端口時,公網服務器全部轉發客戶端1,使用者通過公網服務器操作客戶端1,所以公網服務器到客戶端1的連接稱為反向隧道

第一種方法

客戶端1執行一條命令即可建立反向隧道:

$ssh -N -f -R *:2244:localhost:22 106.10.10.xxx

其中-N表示不執行命令,只轉發;-f表示後臺運行;-R表示反向隧道;*:2244:localhost:22表示監聽服務器的2244端口,所有包轉發到本地的22端口;106.10.10.xxx為服務器IP

我只要在客戶端2執行ssh -p 2244 [email protected]就能連接客戶端1的電腦了。

實際使用中會發現,該通道會經常自動斷開,這是正常現象。可通過autossh實現斷開重連。使用autossh之前,必須確保該客戶端與服務器連接使用了無密碼的密鑰對登陸

$autossh -M 5678 -N -f -R *:2244:localhost:22 106.10.10.xxx

其中-M 5678表示通過5678端口監聽連接狀態,有問題就重連。

第二種

使用ngrok(1.x版本)就簡單多了,一條命令搞定,也不需要知道服務器的密碼或傳公鑰,適合第三方服務器提供跳板服務。

$ngrok -proto=tcp 22
ngrok                                                                                                                                                                (Ctrl+C to quit)
                                                                                                                                                                                     
Tunnel Status                 online                                                                                                                                                 
Version                       1.7/1.7                                                                                                                                                
Forwarding                    tcp://106.10.10.xxx:2244 -> 127.0.0.1:22                                                                                                           
Web Interface                 127.0.0.1:4040                                                                                                                                         
# Conn                        0                                                                                                                                                      
Avg Conn Time                 0.00ms

根據上面的輸出,我只要在客戶端2執行ssh -p 2244 [email protected]就能連接客戶端1的電腦了。

默認情況下,ngrok的轉發端口是隨機的,如果要固定,編輯~/.ngrok,按如下添加通道:

server_addr: 106.10.10.xxx:4443
trust_host_root_certs: false
tunnels:
  ssh:
    proto:
      tcp: "22"
    remote_port: 2244

然後通過以下命令啟動:

ngrok start ssh

How系列-公網如何ssh到內網的Linux系統中?