ssh本地端口转发,远程端口转发,隧道(这个解释不饶)
目錄
創建隧道時的常用選項
本地端口轉發
命令
原理
命令
原理
隧道
命令
創建隧道時的常用選項
“-L選項”:表示使用本地端口轉發創建ssh隧道
“-R選項”:表示使用遠程端口轉發創建ssh隧道
“-N選項”: 表示創建隧道以后不連接到sshServer端,通常與”-f”選項連用
“-f選項”:表示在后臺運行ssh隧道,通常與”-N”選項連用
“-g選項”:表示ssh隧道對應的轉發端口將監聽在主機的所有IP中,不使用”-g選項”時,轉發端口默認只監聽在主機的本地回環地址中,”-g”表示開啟網關模式,遠程端口轉發中,無法開啟網關功能。
本地端口轉發
命令
# 所有訪問本機9090端口都會訪問172.16.12.131上的3306
ssh -fCNg -L 9090:172.16.12.131:3306 root@172.16.12.131 # 所有訪問本機9090端口都會訪問172.16.12.131上的3306原理
首選,將實驗環境準備好,兩臺主機的信息如下
- ServerA:10.1.0.1
- ServerB:10.1.0.2
ServerA中并不存在mysql服務。
ServerB中已經安裝了mysql服務,mysql服務已經啟動并監聽了3306端口。
現在,我們只要在ServerA中執行如下命令,即可在ServerA與ServerB之間建立一條ssh隧道,執行如下命令時會提示輸入ServerB的密碼
如上圖所示,執行上圖中的命令后,我們直接從主機A連接到了主機B,這條連接就是我們創建的”ssh隧道”。
我們先來簡單的解釋一下上圖中命令的含義,為了方便解釋,我們把命令分成3部分理解,如下圖所示。
第1部分為-L選項,-L 選項表示使用”本地轉發”建立ssh隧道,本地轉發是什么意思呢?
“本地轉發”表示本地的某個端口上的通訊數據會被轉發到目標主機的對應端口,你可以把它抽象的理解成一種”映射”,注意,我們把執行上述命令的主機稱為”本地主機”。
比如,訪問本地(當前主機)的端口A,就相當于訪問目標主機的端口B,因為當你訪問本地的端口A時,通訊數據會被轉發到目標主機的端口B,這就是本地轉發,其實,”本地轉發”是與”遠程轉發”相對應的,但是我們還沒有介紹到遠程轉發,所以并不用在意那么多,我們只要先了解本地轉發的作用就行了。
剛才說過,”本地轉發”表示本地的某個端口上的通訊數據會被轉發到目標主機的對應端口,那么你一定能夠理解上述命令中第2部分的含義了
第2部分表示:通訊數據會從本地的9906端口上被轉發,最終被轉發到10.1.0.2的3306端口。
第3部分表示:我們創建的ssh隧道是連接到10.1.0.2上的root用戶的,其實,第3部分可以與之前的ssh連在一起去理解,比如,ssh root@10.1.0.2,其實就是使用ssh命令從ServerA中連接到ServerB的root用戶,這就是為什么執行上述命令以后,會提示我們輸入10.1.0.2中root用戶的密碼,當然,如果你已經在ServerB中配置好了ServerA對應用戶的公鑰,那么則可以省去輸入密碼的步驟直接連接,此時,ServerA的角色是ssh的客戶端,ServerB的角色是ssh的服務端,而這條ssh隧道就是建立在ServerA與ServerB之間的。
了解完上述命令的3個部分,我們來把它當做一個整體去理解一下
ssh -L 9906:10.1.0.2:3306 root@10.1.0.2上述命令表示從本機(ServerA)建立一個到ServerB(10.1.0.2)的ssh隧道,使用本地端口轉發模式,監聽ServerA本地的9906端口,訪問本機的9906端口時,通訊數據將會被轉發到ServerB(10.1.0.2)的3306端口。
好了,命令解釋完了,現在我們來試試實際的使用效果,注意,此刻我們已經創建了ssh隧道,從serverA中已經連接到了ServerB,不要退出這個ssh連接,否則剛才創建的ssh隧道將會消失(稍后會介紹怎樣后臺建立連接),此刻,我們再打開一個新的ssh連接,連接到ServerA,如下圖所示
在新鏈接中查看對應的端口號,本地回環地址的9906端口已經被監聽了(稍后介紹怎樣監聽ServerA中指定的IP,即非本地回環地址)。
此時,我們直接在ServerA中通過mysql命令訪問127.0.0.1的9906端口,就相當于訪問ServerB的mysql服務了,我們來試試。
執行mysql命令時需要指定IP與端口號,因為我的ServerB中的mysql只是用于測試,所以沒有為用戶設置密碼,如下圖即可連接
如上圖所示,已經可以正常在ServerA中連接到數據庫,但是連接的數據庫其實是ServerB中的mysql服務。
這就是通過ssh隧道訪問遠程主機的mysql服務的示例,這樣做就是利用ssh的安全特性加密了mysql的通訊數據。
在沒有使用ssh隧道時,直接從ServerA跨越公網訪問ServerB的mysql服務時,如果在ServerB中通過抓包工具對通訊網卡進行抓包,可以直接從抓到的數據包中看到mysql的傳輸數據。
但是如果使用了ssh隧道,并且在ServerB中僅對通訊網卡進行抓包時,則只能看到經過加密的ssh數據包,此時,如果對ServerB的本地回環網卡同時進行抓包,則可以看到未加密的mysql傳輸數據,不過,這并不影響mysql通訊數據跨越公網時的安全性,因為這時已經是ServerB本機中的數據傳輸了,也就是說,mysql通訊數據在跨越公網時,是經過ssh隧道加密的,mysql通訊數據到達ServerB本機以后,是明文傳輸的。
不過,當我們執行上述命令創建ssh隧道時,總會從ServerA中連接到ServerB中,而通常,我們只希望建立ssh隧道,并不會使用到這個新建立的ssh連接,而且在實際使用中,我們往往會在建立隧道以后,退出當前的ssh會話,所以,上述命令并不能滿足我們的需求,因為,我們一旦退出對應的ssh會話,相應的ssh隧道也會消失,所以,我們還需要配合另外兩個選項,”-N選項”與”-f選項”,我們一一道來。
首先來試試”-N選項”,當配合此選項創建ssh隧道時,并不會打開遠程shell連接到目標主機,我們來試試,如下圖所示,配合-N選項創建隧道,輸入ServerB的密碼以后,并沒有連接到ServerB,而是停留在了如下圖的位置
此時,再打開一個新的ssh會話連接到ServerA,可以看到,9906端口已經被監聽。
但是,這樣仍然不能滿足我們的要求,雖然建立隧道時并沒有連接到ServerB,但是,我們仍然不能關閉創建ssh隧道時所使用的ssh會話。
這時,只要配合”-f”選項即可,”-f”選項表示后臺運行ssh隧道,即使我們關閉了創建隧道時所使用的ssh會話,對應的ssh隧道也不會消失,”-f”選項需要跟”-N”選項配合使用,所以通常,我們會使用如下命令創建ssh隧道
ssh -f -N -L 9906:10.1.0.2:3306 root@10.1.0.2配合上述選項創建ssh隧道時,即使我們完全關閉了執行命令時的ssh會話,對應創建的隧道也可以完全正常運行。
不過,當我們使用上述命令建立隧道時,只有127.0.0.1這個回環地址的9906端口會被監聽,這樣就會出現一個小問題,也就是說,我們只能在ServerA本機上訪問9906端口,并不能通過其他主機訪問ServerA的9906端口,因為ServerA其他IP的9906端口并未被監聽,那么怎么辦呢?很簡單,使用如下命令,即可讓9906端口監聽在ServerA中指定的IP上
ssh -f -N -L 10.1.0.1:9906:10.1.0.2:3306 root@10.1.0.2在ServerA中執行上述命令時,ServerA的10.1.0.1的9906端口會被監聽,此刻,我們可以通過其他主機訪問10.1.0.1的9906端口,即可訪問到ServerB中的mysql服務,其實,與之前的命令相比,只是在9906前增加了ServerA中對應的IP地址罷了,很簡單吧。
如果你覺得這還不夠,希望ServerA中的所有IP地址的9906端口都被監聽,那么可以在建立隧道時開啟”網關功能”,使用”-g”選項可以開啟”網關功能”,開啟網關功能以后,ServerA中的所有IP都會監聽對應端口,示例如下
好了,說了這么多,終于把ssh隧道(本地轉發)給解釋明白了,不過,我們也只是說明了本地轉發,現在,我們來聊聊遠程轉發。?
遠程轉發
命令
公司內部
# 開啟web服務:python -m SimpleHTTPServer 80
ssh -fCNg -R 9002:172.16.12.131:80 root@10.10.17.31 # 開啟web服務:python -m SimpleHTTPServer 80公司外部
# 缺點,只能在131機器上訪問127.0.0.1,需要在公網IP上再建立一層端口轉發
ss -pantulo|grep 9002 訪問 curl http://127.0.0.1:9002 # 缺點,只能在131機器上訪問127.0.0.1原理
在了解遠程轉發之前,請先確定你已經理解了”本地轉發”。
老規矩,為了方便理解,我們先來描述一個場景。
公司有一臺服務器ServerB,ServerB處于公司的內網中,公司內網中的所有主機都通過路由器訪問互聯網(典型的NAT網絡),ServerB中有提供mysql服務,如果此時,我們想要通過外網訪問到ServerB中的mysql服務,該怎么辦呢?通常的做法是,通過路由器或者防火墻,將公司的固定外網IP上的某個端口映射到ServerB內網IP的3306端口上,這樣,我們只要訪問公司外網IP的對應端口,即可訪問到內網ServerB中的mysql服務了,但是,如果你沒有權限控制公司的防火墻或者路由器呢,這時該怎么辦呢?
假設,你無法控制防火墻去進行端口映射,但是,公司在公網上有另外一臺服務器ServerA,ServerA有自己的公網IP,你有權控制ServerA,這時,我們就可以利用ServerA達到我們的目的,聰明如你,一定想到了解決方案,沒錯,我們可以在ServerA與ServerB之間創建一條SSH隧道,利用這條隧道將ServerA中的某個端口(假設仍然使用9906端口)與ServerB中的3306端口連接起來,這樣,當我們訪問ServerA的9906端口時,就相當于訪問到內網ServerB中的mysql服務了,那么,我們能不能使用之前的”本地轉發”的方式,在ServerA中創建SSH隧道呢?我們來模擬一下,看看會不會遇到什么問題,如果想要使用之前的命令創建SSH隧道,那么我們則需要在ServerA中執行如下命令。
ssh -f -N -L AIP:9906:BIP:3306 root@BIP問題來了,ServerA有自己的公網IP,我們只要把上述命令中的AIP替換成ServerA的公網IP即可,但是ServerB是內網主機,雖然ServerB能夠通過公司內的路由器訪問到互聯網,但是ServerB并不持有任何公網IP,ServerB只有內網IP,所以,我們并不可能把上述命令中的BIP替換成B主機的內網IP,所以,使用上述命令是無法在ServerA中創建ssh隧道連接到ServerB的,那么該怎么辦呢?
雖然我們無法從ServerA中使用ssh命令連接到ServerB,但是,我們可以從ServerB中使用ssh命令連接到ServerA啊,雖然ServerB是沒有公網IP的內網主機,但是它仍然可以依靠公司的路由器訪問互聯網,所以,我們只要在ServerB中執行如下命令,即可從ServerB中連接到ServerA中。
ssh root@AIP那么,按照這個思路,我們似乎找到了方向,我們現在需要一種方法,能夠從ServerB中創建SSH隧道連接到ServerA,并且,隧道創建后,ServerA中會監聽9906端口,以便別人能夠通過外網訪問,也就是說,我們需要一種方法,能夠滿足如下兩個條件
- 條件1:從ServerB中主動連接到ServerA,即在ServerB中執行創建隧道的命令,連接到ServerA。
- 條件2:隧道創建后,轉發端口需要監聽在ServerA中,以便利用ServerA訪問到內網的ServerB。
這種方法就是”遠程轉發”。
你可能還是不太明白,沒有關系,我們先來實際動手操作一下,稍后,我們會對比本地轉發與遠程轉發的具體區別。
為了方便,我們仍然使用之前的實驗環境,假設ServerA是外網主機,ServerB是內網主機,ServerA的IP為10.1.0.1(假設此IP為公網IP),ServerB的IP為10.1.0.2,并且已經將之前本地轉發的進程關閉,相當于一個沒有任何隧道的新的實驗環境。
使用”-R選項”,可以創建一個”遠程轉發”模式的ssh隧道,我們在ServerB中,執行如下命令即可
上述命令在ServerB中執行,執行后,即可在ServerA與ServerB之間建立ssh隧道,此時,ServerB是ssh客戶端,ServerA是ssh服務端,隧道建立后,ServerA中的9906端口會被監聽,在ServerA中查看對應端口,如下圖所示從圖中可以看出,ServerA中的9906端口已經被監聽,此刻,我們通過外網IP登錄到ServerA,在ServerA中訪問本地回環地址的9906端口,即可訪問到內網ServerB中的mysql服務,如下圖所示。
不過你肯定注意到了,當使用遠程轉發的命令時,我并沒有指定監聽ServerA的外網IP,也沒有使用”-g選項”開啟網關功能,這是因為,即使你在命令中指定了IP地址,最終在ServerA中還是會只監聽127.0.0.1的9906端口,你可以在ServerB中嘗試一下如下命令
ssh -f -N -R 10.1.0.1:9906:10.1.0.2:3306 root@10.1.0.1即使在ServerB中執行上述命令時指定了IP或者開啟了網關功能,ServerA的9906端口仍然只監聽在127.0.0.1上,當然,如果你一心想要通過別的主機訪問ServerA的9906端口,也可以使用其他程序去反代ServerA的9906端口,還有,我在實際的使用過程中,如果使用遠程轉發穿透到內網,ssh隧道將會非常不穩定,隧道會莫名其妙的消失或者失效,特別是在沒有固定IP的網絡內,網上有些朋友提供了autossh的解決方案,不過我并沒有嘗試過,如果你有興趣,可以試一試。
隧道
命令
ssh -fCNg -D 127.0.0.1:6060 root@10.0.2.85配置代理
socks5 127.0.0.1 6060注:如果使用nmap掃描要用 sT 參數完成三次握手,否則數據不準確
總結
以上是生活随笔為你收集整理的ssh本地端口转发,远程端口转发,隧道(这个解释不饶)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 「Python」10个python项目
- 下一篇: bootstrap全局css样式