基本概念
SSH反向隧道可以實現SSH的內網穿透,其作用原理是:
- 內網機器監聽公網服務器的端口;
- 一旦公網機器收到來自端口的請求,則轉發/映射到內網機器的端口(內網機器的ssh默認端口爲22)
注意: 除了內網機器的端口需要爲
/etc/ssh/sshd_config
設備概覽
服務器代號 | IP | 對外暴露的SSH端口 |
---|---|---|
A(公網) | 114.114.114.114 | 2061 |
B(內網) | 192.168.1.101 | 22 |
C(內網) | 192.168.1.102 | 22 |
…(內網) | … | … |
適用場景
假設我現在有N臺內網機器,只有一臺公網機器,現在我需要利用公網機器作爲中轉站,操作內網機器…
搭建反向隧道
下面,我們對內網機器的SSH端口22
進行穿透。所有操作默認採用root
權限。
文章分爲三個部分:
- 正向代理(公網機器操作)
- 反向代理(內網機器操作)
- 穩定機器及開機自動建立反向隧道(內網機器操作)
公網機器配置
正向代理
當你知道內網機器IP時,你可以如下配置:
ssh -fCNL <內網機器B的IP>:<內網機器B的端口,如22>:localhost:<公網機器A的端口,如2601> localhost
其中ssh指令的各參數意義爲:
-f 後臺執行ssh指令
-C 允許壓縮數據
-N 不執行遠程指令
-R 將遠程主機(服務器)的某個端口轉發到本地端指定機器的指定端口
-L 將本地機(客戶機)的某個端口轉發到遠端指定機器的指定端口
-p 指定遠程主機的端口
但是,如果內網服務器採用DHCP或者分佈在兩個內網中,很難鎖定這個IP的值。
開放權限
這種情況下,我們可以修改公網機器的SSH配置文件/etc/ssh/sshd_config
,添加/修改以下內容:
GatewayPorts yes
然後刷新一下服務:
service sshd restart
或者,依舊採用ssh正向代理指令:(該方法需要設一下開機自啓,詳見下)
ssh -fCNL *:<內網機器B的端口,如22>:localhost:<公網機器A的端口,如2601> localhost
以上兩種方法都可以把被監聽的端口開放/綁定到任意IP0.0.0.0
上。
內網機器配置
我們假設爲2061
,即訪問公網機器端口2061
時會自動轉發到內網端口22
實現ssh登錄。
反向隧道
注意,推薦利用
autossh
建立反向隧道,而不是ssh
指令,詳見下文。
ssh -fCNR 2061:localhost:22 <公網機器A的ssh登錄用戶名>@<公網機器A的IP>
- <公網機器A的ssh登錄用戶名>: 指的是在公網機器上負責轉發請求的用戶,可以直接使用
root
,或者新建一個用戶bridge
。執行上述命令後會讓你輸入登錄公網機器的ssh密碼。
在公網機器A上執行指令:lsof -i:<公網機器A被監聽的端口,如2061>
,會看到:
此時,可以嘗試進行反向登錄了:
ssh <公網機器A的IP> -p <公網機器A的端口>
理論上將會順利穿透到內網機器,否則請檢查防火牆的設置。
- 你可以在內網機器使用指令
pus -aux | grep ssh
來查看相關進程,用kill -p <PID>
關閉相關反向隧道的進程。
穩定連接與開機自啓
由於SSH在一段時間沒有數據包之後,會自動斷開,所以我們需要設置一下autossh
。
(以下操作均在內網機器B進行)
- 首先是進行下載:
apt-get install autossh
, - 然後添加我們內網機器的ssh-key到公網以實現自動登陸:
ssh-copy-id <公網機器A的ssh登錄用戶名>@<公網機器A的IP>
。 - (Options)如果本機不存在key,你需要先執行
ssh-keygen -t rsa -C "[email protected]"
再進行第二步。 - 利用autossh建立反向隧道:
autossh -M 55555 -fCNR 2061:localhost:22 <公網機器A的ssh登錄用戶名>@<公網機器A的IP>
autossh
和與ssh
直接建立反向隧道的指令並無太大不同,只不過添加了一個端口用於進行心跳包的發送,即-M <port>
(樣例中爲55555
端口)
接下來,還需要設置開機自啓:(/etc/rc.local
文件根據系統版本有所不同,請自行搜索)
vim /etc/rc.local
添加上述autossh
指令即可。