今天講遠程連接,所有代碼案例在:
https://github.com/suchocolate/test/tree/master/remote
本文僅適用於無可控防火牆的場景,如有自己的防火牆和無限制IP,請忽略本文。
1.簡單分析
機房拓撲如下
衆所周知,一般FW只允許內對外發起訪問,禁止外對內發起訪問。
在這種場景下,想要遠程,就需要一個在公網的代理節點幫忙。(實際這種由公網通過代理節點訪問私網的連接方式應該叫做反向代理,爲了便於理解本文簡稱代理)
如何實現:首先由內網機發起到代理節點的連接並保持連接,而後遠程client訪問代理節點,代理節點從隧道轉發給內網機,這樣就實現了遠程連接。
因此想實現遠程連接需要2個素材:
-
一個帶公網IP的代理節點。
-
合適的轉發方式。
2.我用過的轉發方式
我用過5種轉發方式(都是基於SSH隧道):
接下來我爲大家一一介紹,條件有限,我用3臺虛擬機和物理機模擬:
-
內網機:192.168.70.138 u41
-
代理:192.168.70.135 u42_proxy 192.168.137.21(假如這是公網ip)
-
client:192.168.137.1(就是我的物理機)
-
A主機:192.168.70.151 a_host
3.SSH:基礎的端口轉發
端口轉發是SSH自帶的功能,僅用SSH命令就可以實現。
1)遠程轉發
以圖爲例,首先內網機使用如下命令發起遠程(R)端口轉發,就能將代理上的15022端口轉發到內網機的22端口上:
ssh -fCNR 15022:localhost:22 [email protected]
# f:程序放到後臺
# C:數據壓縮,壓縮節省流量
# N:這不是一條遠程SSH命令
# R:遠程轉發,將遠程15022端口發到本地的22端口
可以看到在後臺運行了一個SSH遠程轉發的進程。
接下來只要在代理節點上使用如下命令就可以訪問內網機了。
ssh -p 15022 root@localhost
# p:端口15022
# root:內網機的賬號
# localhost:登陸的主機
# 意思就是登陸本機的15022端口,又因爲這個映射成了遠端的內網機的22端口
# 所以當登陸這個端口時,就是登陸內網機的22端口。
成功登陸到了內網機。
2)本地轉發
僅遠程轉發沒有預期的方便,這個遠程方式需要我們先登陸到代理節點,才能SSH訪問內網機。能不能實現client不登錄代理,就能登陸內網機?當然可以,我們先看一下代理節點的監聽端口:
可以看到,代理節點上監聽的是環回口的15022,所以只能在代理節點上訪問。如果想實現不登錄代理就轉發,我們還得在代理上開一個本地轉發,監聽任意地址,流量轉給15022:
接下來在代理節點運行本地(L)轉發命令:
ssh -fCNL *:15023:localhost:15022 root@localhost
# L:本地轉發命令,將15023轉發到本地的15022端口
# root:這裏的root是代理自己的賬號和密碼
可以看到,代理節點運行了SSH後臺本地轉發進程,並且在監聽0.0.0.0:15023端口了。
我們在client上新建一個到代理節點公網地址:192.168.137.21:15023的SSH會話,登陸驗證一下:
果然成功連上了u41內網機,流量經過代理做了一次本地轉發,而後經過代理和內網機的隧道做了一次遠程轉發,實現了遠程連接:
3)SSH轉發的總結
SSH的優點是不需要安裝額外軟件,只需執行SSH命令即可。缺點是連接不穩定,容易受到網絡影響,使用時需要兩端任意一方設置保持連接的配置:
# 內網機端
vi /etc/ssh/ssh_config
ServerAliveInterval 60
ServerAliveCountMax 3
# 代理機
vi /etc/ssh/sshd_config
ClientAliveInterval 60
ClientAliveCountMax 3
不過即使設置,也有可能因爲系統的故障斷連,這時需要使用Autossh。
4.Autossh:穩定的端口轉發
Autossh是一個用來保持SSH程序的軟件,它能夠在SSH程序Down掉後重啓SSH程序。
1)安裝方法
apt-get install autossh # debian系操作系統
yum install autossh # redhat系操作系統
2)必要設置
Autossh和SSH一樣都會在後臺工作,但Autossh在放到後臺工作後,不會彈出輸入密碼的提示,我們無法輸入密碼,因此只有免密登陸才能讓Autossh順利工作。免密方法如下:以下案例是內網機免密登陸代理機。
ssh-keygen # 3個回車即可
ssh-copy-id [email protected] #root想登陸的節點的賬號和密碼
3)內網機開遠程轉發
autossh -M 10060 -f -CNR 15022:localhost:22 [email protected]
# -M:autossh從10060端口發檢測消息,對端發回給+1端口就是10061
# -f:程序放到後臺
# -CNR:就是SSH的參數
可以看到Autossh其實就是幫我們開啓了遠程轉發,另外它有自己的保活機制,可以在網絡或系統異常時幫我們重啓轉發。
4)代理生成key並copy給自己
接下來就是在代理上做本地轉發,本地轉發時要代理節點ssh登陸自己,這個過程正常也需要輸入密碼,因此爲了讓Autossh正常工作,也得讓代理節點生成key並copy給自己。
ssh-keygen
ssh-copy-id root@localhost # 賬號名和主機都是代理自己的
5)代理節點運行Autossh本地轉發
autossh -M 10070 -f -CNL "*:15023:localhost:15022" root@localhost
可以看到代理節點開啓了本地轉發,我們通過client再次驗證一下結果:
成功轉發到到了內網機上。
6)Autossh的總結
Autossh雖然穩定,但是和SSH轉發一樣兩個節點都需要配置,如果用的人多,大家都要在代理上加配置,有安全隱患。我們可以使用frp簡化配置增強安全。
5.frp:穩定的應用自動轉發
frp 是一個可用於內網穿透的高性能的反向代理應用,支持 tcp, udp 協議,爲 http 和 https 應用協議提供了額外的能力,且嘗試性支持了點對點穿透。
frp分frps端和frpc端,代理節點運行frps,內網機運行frpc。
1)frp架構圖:
2)frp的工作機制
frpc和frps使用單獨的端口通信(本例指定7000),業務端口由frpc指定,frps自動開始監聽。當有流量時開始轉發,不需要額外配置,配置文件中也無需指定賬號密碼,降低了安全風險。
3)frp的下載:
下載地址:https://github.com/fatedier/frp/releases/
無需安裝,只需找到相應系統對應軟件,下載解壓即可運行。
4)frps的配置和運行
-
下載後,首先修改代理節點的配置:frps.ini
vi ./frps.ini
[common]
bind_port = 7000 # frps監聽的,用來和frpc交互的端口
-
運行:frps
nohup ./frps -c frps.ini> nohup.out 2>&1 &
# hohup:後臺運行
# frps:frps上的主程序
# frps.ini:frps的配置
# > nohup.out:log
# 2>&1:報錯也輸出到log
# &:後臺運行
5)frpc的配置和運行
-
修改內網機上的配置:frpc.ini
vi ./frpc.ini
[common]
server_addr = 192.168.70.135 # frps的地址
server_port = 7000 # frps監聽的,用來和frpc交互的端口
# frpc想讓frps轉發的應用,如果有多個frpc都想讓frps轉發,那麼其他
# frpc需要在ssh後面加序號,如[ssh2][ssh3]
[ssh]
type = tcp
local_ip = 127.0.0.1 # 轉發到本地的地址
local_port = 22 # 轉發到本地22端口
remote_port = 15800 # frps監聽轉發的端口
use_encrytion =true # 數據加密
use_compression =true # 數據壓縮
-
內網機運行:frpc
nohup ./frpc -c frpc.ini > nohup.out 2>&1 &
查看代理上的端口已經在監聽15800端口了,而且用的不是SSH的轉發。
6)frp的驗證
在client新建到192.168.137.21:15800的SSH會話,並登陸:
成功登陸內網機。
7)frp的總結
-
frps只需指定與frpc會話端口,不需要指定業務端口,配置省事。
-
frpc無需登陸frps,業務端口由frpc指定,安全自由。
8)frp的擴展
另外frp還支持http,https,dns,socket等的轉發,詳細的配置大家可以到github頁面查看。最後frps上還可以配置dashboard,用GUI監控frps上連接的情況:
vi ./frps.ini
[common]
dashboard_port = 7500
# dashboard 用戶名密碼,默認都爲 admin
dashboard_user = admin
dashboard_pwd = admin
6.SecureCRT:Windows上的端口轉發
1)場景假設
前3種都是在linux系統上的轉發,這第4種是在Windows系統上轉發,它適用於以下場景:(本節用另外的虛機192.168.70.151模擬A主機,物理機模擬Windows內網機)
假如內網有臺A主機不能上網連公網的代理節點,而有一臺Windows系統的內網機電腦可以連A主機的同時,還可以上公網,那麼這臺Windows內網機就可以用SecureCRT轉發。(可以把Windows內網機想象成一個路由器)
2)先讓Windows內網機建立到代理的SSH會話
3)在這個會話中設置遠程端口轉發
啓動SSH會話,可以看到代理節點已經在監聽15022,此時代理到內網機的隧道已經建立。
注意:這個轉發是將代理的15022端口轉到A主機的22端口,而SSH的案例中R轉發是將代理的15022端口轉到本地的22端口。
3)隧道的保持
SecureCRT的SSH會話也有可能斷連,我們可以讓SecureCRT運行一個腳本,來保持這個連接:keep.vbs
#$language = "VBScript"
#$interface = "1.0"
crt.Screen.Synchronous = True
' This automatically generated script may need to be
' edited in order to work correctly.
Sub Main
crt.Dialog.MessageBox("Script is running")
i=1
do while i>0
crt.Screen.Send "date" & chr(13)
crt.Sleep 1500000
loop
End Sub
CRT運行腳本的方法:【腳本】-【運行】在彈出的對話框中選擇keep.vbs。
4)先驗證:A主機<---內網機<---代理
在代理上驗證一下:
代理能夠登陸A主機。
5)client的轉發
按照SSH轉發的思路,接下來就需要在代理節點開本地轉發了,但其實還有另外的方法,即外部client與代理再建一個隧道。
接下來讓client建立與代理的隧道,並利用這個隧道,client上做本地轉發,即可免去代理上配本地轉發:
6)client上建立與代理的ssh會話
7)之後在這個會話中建立本地轉發:
8)啓動這個會話
此時從client到A主機的兩條隧道拼接完成。
9)接下來client再建立一個SSH會話:
IP指向127.0.0.1,端口15022。
10)登陸驗證
成功跨越2個隧道,到達A主機。
11)簡單分析
-
ssh client將流量發給client的端口15022。
-
15022是CRT的本地轉發,轉發透過SSH隧道傳到代理的15022上。
-
代理的15022是另外一個CRT的遠程轉發,代理透過SSH隧道轉給內網機。
-
這個遠程轉發是直接轉給A主機的,流量發給A主機。
7.Socket:自識別應用的轉發
以上4種方法只是展示了轉發SSH的應用,實際上還可以轉發其他端口應用,比如HTTP 80,DNS 53,VNC 3900等等。但無論轉發哪種,都需要一定的配置,而Socket轉發就可以免去設置多種端口的麻煩,只要有SSH隧道,就能Socket轉發。
1)Scoket轉發過程:
-
首先client建立到內網機的隧道
-
其次client內的軟件設置代理:
-
效果
這樣client就可以直接訪問內網機能訪問的資源了,效果如同client就置身於內網機中:
2)模擬案例展示:frp(基礎SSH代理)+CRT(socket)
我用frp實現內網機的ssh,配置參考frp案例。這樣client直接ssh15800就是內網機。
之後在A主機運行了http server,只接受內網機的訪問,其他IP禁止訪問http端口。用iptables實現:
iptables -I INPUT 1 -p tcp --dport 80 -s 192.168.70.138/32 -j ACCEPT
iptables -I INPUT 2 -p tcp --dport 80 -j DROP
3)client 上在這個ssh會話中配置socket轉發
登陸ssh會話,可以正常登陸到內網機,這樣隧道和socket轉發環境就搭建好了,接下來是client設置代理。
4)各種client設置代理
-
首先瀏覽器設置代理:firefox爲例
登陸網站驗證:可以登陸A主機了。
-
VNC設置代理:
-
Mobaxterm的遠程桌面也支持設置代理
只是Moba並沒有用CRT做的socket轉發,而是自己利用了SSH隧道。
總之只要有SSH隧道,所有支持設置代理的client都可以利用socket實現轉發,不用添加其他端口轉發等配置。
8.實際應用
綜合實際的情況,我選擇了frp保持隧道,只用ssh連接節點,只在需要訪問內部網頁時透過ssh隧道做socket轉發。
另外所有的轉發都是通過SSH隧道完成的,所有數據被壓縮,在另一端解壓縮,傳輸效率並不高(直連80mb/s,透過代理40mb/s)。尤其像使用阿里雲或百度雲主機時,默認帶寬只有1mb/s,傳文件是很不划算的。
另外建議使用autossh或frp時設置開機自啓動,避免節點重啓後失效。