緣由
有時會有學習或工作用的電腦沒有實體 IP (在內網),但又需要連線到那台電腦
這時可以利用 Reverse SSH Tunneling 機制來連線
所需環境與工具
範例環境介紹
Machine | Account | IP | Port | Info |
---|---|---|---|---|
ServerA | userA | 192.168.0.101 | 22 | Private IP (內網;目標電腦) |
ServerB | userB | 149.12.34.56 | 1234 | Public IP (外網;中繼電腦) |
Client | user | User (你的電腦) |
你想從 Client 這台電腦連到工作用的電腦 ServerA,預期連線流程大概如下:
1 | Client -----> ServerB --| 防火牆 |--> ServerA |
又因為 ServerA 沒有實體 IP,ServerB 無法直接連到 ServerA
可以利用 Reverse SSH Tunneling 機制
ServerA 先連到 ServerB 建立隧道:
1 | ServerB <==| 防火牆 |== ServerA |
ServerB 再依靠該隧道 port 1234 連到 ServerA:
1 | ServerB ≡≡| 防火牆 |≡≡> ServerA |
免密碼登入
連線時會需要帳密
如果想免密碼登入可執行此步驟把 public key 傳給對方
1 | [userA@ServerA] $ ssh-keygen # 產一對 key |
目標電腦設定
Server A 開一個隧道到 ServerB
1 | [userA@ServerA] $ ssh -NfR 1234:localhost:22 [email protected] # f 代表背景執行 |
連到目標電腦
方法 1
Client 先連到 ServerB
1 | [user@Client] $ ssh [email protected] |
因為前面 ServerA 已經開一個隧道過來
所以 ServerB 就能連到 ServerA 了
1 | [userB@ServerB] $ ssh userA@localhost -p 1234 |
方法 2
使用一個指令來達成 “先連到 ServerB 再下指令連到 ServerA”
1 | [user@Client] $ ssh -t [email protected] "ssh userA@localhost -p 1234" |
方法 3
直接以 ServerB 當跳板連到 ServerA
1 | [user@Client] $ ssh -o "ProxyJump [email protected]" userA@localhost -p 1234 |
或是
1 | [user@Client] $ ssh -J [email protected] userA@localhost -p 1234 |
方法 4 (推薦)
原本 ServerB 只能透過 localhost 來連到 ServerA
此方法是 Server A 設定時加上 “-g” 這個 option
(允許遠端主機連到本地的轉發 port)
讓 Client 透過 ServerB 的 port 直連到 ServerA
仿照前面 開隧道 時 ServerA 改下指令:
1
[userA@ServerA] $ ssh -gNfR 0.0.0.0:1234:localhost:22 [email protected]
ServerB 要設定 GatewayPorts:
1
[userB@ServerB] $ vim /etc/sshd_config
裡面的 “GatewayPorts” 改成 yes (預設是 no) 並重開 sshd 服務:
1
[userB@ServerB] $ systemctl restart sshd
去防火牆把中繼 port 設為允許 (ssh 是 tcp)
1
[userB@ServerB] $ iptables -A INPUT -i eth0 -p tcp --dport 1234 -j ACCEPT
把 iptables 設定存起來
1
[userB@ServerB] $ iptables-save
Client 下指令 (記得這邊 account 要填 ServerB 的登入帳號)
1
[user@Client] $ ssh [email protected] -p 1234
其他相關指令
查看網路狀態
1 | $ netstat -a|less # less 代表翻頁檢視 |
登出
登入後如果想登出可執行以下指令:
1 | $ exit |
關閉 SSH Tunnel
以下為列出 process 資訊的指令:
1 | $ ps -ef|grep 1234 # 列出使用 1234 port 的 process |
找到 process id 後就能刪除:
1 | $ kill -9 [process id] # 刪除指定 process id 的 process |
斷線時自動重連
有連線就有可能斷線
這時候 serverA 就可以用 autossh 來建立 Reverse SSH Tunneling:
1 | # -M 後面是監聽用的 port, 不可跟 localhost 前的 port 一樣, 設 0 代表強制關閉 |
或是可使用 cmd-boost 這個工具
如果要關閉 autossh:
1 | $ pkill -3 autossh |
Comments