遠端控制內網電腦

緣由

有時會有學習或工作用的電腦沒有實體 IP (在內網),但又需要連線到那台電腦
這時可以利用 Reverse SSH Tunneling 機制來連線

所需環境與工具

  1. 一台有實體 IP 的伺服器
    如沒有可購買 VPS,如 Linode,最便宜方案一個月 5 美金

  2. OpenSSH
    Linux 有內建
    Windows 10 可從 設定 來啟用

  3. autossh (選用)

範例環境介紹

MachineAccountIPPortInfo
ServerAuserA192.168.0.10122Private IP (內網;目標電腦)
ServerBuserB149.12.34.561234Public IP (外網;中繼電腦)
ClientuserUser (你的電腦)

你想從 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
2
[userA@ServerA] $ ssh-keygen # 產一對 key
[userA@ServerA] $ ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected] # 把 public 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

  1. 仿照前面 開隧道 時 ServerA 改下指令:

    1
    [userA@ServerA] $ ssh -gNfR 0.0.0.0:1234:localhost:22 [email protected]

  2. ServerB 要設定 GatewayPorts:

    1
    [userB@ServerB] $ vim /etc/sshd_config

    裡面的 “GatewayPorts” 改成 yes (預設是 no) 並重開 sshd 服務:

    1
    [userB@ServerB] $ systemctl restart sshd

  3. 去防火牆把中繼 port 設為允許 (ssh 是 tcp)

    1
    [userB@ServerB] $ iptables -A INPUT -i eth0 -p tcp --dport 1234 -j ACCEPT

    把 iptables 設定存起來

    1
    [userB@ServerB] $ iptables-save

  4. Client 下指令 (記得這邊 account 要填 ServerB 的登入帳號)

    1
    [user@Client] $ ssh [email protected] -p 1234

其他相關指令

查看網路狀態

1
$ netstat -a|less       # less 代表翻頁檢視

登出

登入後如果想登出可執行以下指令:

1
$ exit

關閉 SSH Tunnel

以下為列出 process 資訊的指令:

1
2
3
$ ps -ef|grep 1234      # 列出使用 1234 port 的 process
$ ps aux|less # 列出正在進行的 process
$ ps aux|grep ssh # 列出 ssh 相關的 process

找到 process id 後就能刪除:

1
$ kill -9 [process id]  # 刪除指定 process id 的 process

斷線時自動重連

有連線就有可能斷線
這時候 serverA 就可以用 autossh 來建立 Reverse SSH Tunneling:

1
2
# -M 後面是監聽用的 port, 不可跟 localhost 前的 port 一樣, 設 0 代表強制關閉
[userA@ServerA] $ autossh -M 0 -o ServerAliveInterval=10 -o ExitOnForwardFailure=yes -gNfR 1234:localhost:22 [email protected]

或是可使用 cmd-boost 這個工具

如果要關閉 autossh:

1
$ pkill -3 autossh

參考資料

  1. Reverse SSH Tunnel實際運用,搭配auotssh永不斷線,putty建立反向tunnel
  2. 實現免密碼 ssh 登入遠端主機
  3. 25 Best SSH Commands / Tricks
  4. ssh通过代理登录远程主机及穿越跳板机
  5. What Is Reverse SSH Tunneling? (and How to Use It)
  6. SSH反向代理使用心得
  7. Reverse port tunnelling
  8. SSH COMMAND
建置網站記錄2-各種設定 2019 面試紀錄

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×