前言
公司有一台文件服務器(內部使用,無外網IP),上面主要安裝了SVN服務,用來存儲和共享各部門的文檔,因為都是內網,直接遠程(mstsc)上去就可以方便維護,但最近公司租了新的辦公室,部分員工被分配到這邊辦公,毫無疑問,無法遠程和使用SVN了。
要解決有很多方法,比如路由器端口映射、VPN,我們只說一種最簡單,也最奇妙的,SSH反向隧道
公司在雲上有一台公網Linux服務器(假設是 52.199.166.132),我用它來端口轉發
機器 | IP地址 | 用戶名 | 端口 |
A(內網) | 10.3.174.94 | administrator | 3389(遠程連接) 443(SVN) |
B(公網) | 52.199.166.132 | root | 23389(遠程連接) 10443(SVN) |
通俗的說我們要實現:
跳板機:遠程桌面連接 52.199.166.132:23389 實際連的內網的 10.3.174.94:3389
服務轉發:SVN連接 https://52.199.166.132:10443 實際連接的是內網的 https://10.3.174.94
開放端口
在B機器,執行以下命令,防火牆中開放端口10443和23389,並重啟防火牆(B機器的系統是CentOS 7)
firewall-cmd --zone=public --add-port=23389/tcp --permanent firewall-cmd --zone=public --add-port=10443/tcp --permanent firewall-cmd --reload
打開 /etc/ssh/sshd_config,將GatewayPorts參數設為yes,然后重啟sshd服務:
systemctl restart sshd.service
建立反向隧道
原理:內網的A通過SSH連接公網的B,並且兩者建立一個通信隧道,通常防火牆只限制入站不限制出站,所以SSH可以穿透防火牆
1. 保證B服務器已安裝和開啟SSH(現在SSH是Linux標配)
2. 因為A是一台Windows,需要單獨安裝一個SSH客戶端,比如 OpenSSH(Win10 已內置,可在 PowerShell 中使用)、Putty、SecureCRT 等,
我使用的Cygwin,這是一個Windows平台上運行的模擬UNIX環境,安裝Cygwin時記得選擇OpenSSH包 【Cygwin安裝教程(圖文)】
如果用其它SSH客戶端工具,注意 -i 后面的密鑰路徑格式
在終端中,執行兩條命令:
ssh -i "/cygdrive/d/id_rsa/test_centos_secret_key.pem" -fNR 10443:localhost:443 root@52.199.166.132 -p 22 ssh -i "/cygdrive/d/id_rsa/test_centos_secret_key.pem" -fNR 23389:localhost:3389 root@52.199.166.132 -p 22
執行成功,則SSH反向隧道建立
查看監聽端口
登錄機器B,通過 netstat 命令查看監聽端口,有23389 10443端口
然后在本地通過 telnet 查看23389和10443端口是否通
telnet 52.199.166.132 23389 telnet 52.199.166.132 10443
如果都通了,就大功告成了!
遇到的問題
1. 如果在A機器上執行SSH連接B失敗,提示:Warning: remote port forwarding failed for listen port
或者B上面監聽端口的IP地址不是0.0.0.0,而是127.0.0.1,可以在B上面把這兩個端口對應的進程 kill 掉,然后A重新連接
2. SSH超時會斷開(雖然我的一天都沒斷開過),不會重連,解決辦法是用 autossh,那在安裝 Cygwin 時一並安裝 autossh 包,A上的命令這樣寫:
autossh -i "/cygdrive/d/id_rsa/test_centos_secret_key.pem" -M 7777 -NR 10443:localhost:443 root@52.199.166.132 -p 22 autossh -i "/cygdrive/d/id_rsa/test_centos_secret_key.pem" -M 7777 -NR 23389:localhost:3389 root@52.199.166.132 -p 22
其中端口 7777 是負責監聽連接狀態,一旦連接不正常,通知A重連
參數說明
-p 22 遠程主機SSH端口,默認是22,也可以省略
-i "*.pem" 基於密鑰認證,如果基於口令認證,忽略
-f 表示后台執行,autossh 本來就在后台執行,所以不需要
-o ServerAliveInterval=180 保持連接Alive間隔180秒,可以調小
-N 表示不執行任何命令
-R 建立反向隧道
-L 建立正向代理
-M 監聽隧道狀態的端口,如果隧道不正常,告訴內網機器重連
-C 允許壓縮數據