日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ssh本地端口转发,远程端口转发,隧道(这个解释不饶)

發布時間:2025/3/15 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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本地端口转发,远程端口转发,隧道(这个解释不饶)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。