1.1 ssh安全隧道(一):本地端口轉(zhuǎn)發(fā)
如下圖,假如host3和host1、host2都同互相通信,但是host1和host2之間不能通信,如何從host1連接上host2?
對(duì)于實(shí)現(xiàn)ssh連接來(lái)說(shuō),實(shí)現(xiàn)方式很簡(jiǎn)單,從host1 ssh到host3,再ssh到host2,也就是將host3作為跳板的方式。但是如果不是ssh,而是http的80端口呢?如何讓host1能訪問(wèn)host2的80端口?
ssh支持本地端口轉(zhuǎn)發(fā),語(yǔ)法格式為:
ssh -L [local_bind_addr:]local_portremote_port middle_host
以上圖為例,實(shí)現(xiàn)方式是在host1上執(zhí)行:
[root@xuexi ~]# ssh -g -L 222280 host3
其中"-L"選項(xiàng)表示本地端口轉(zhuǎn)發(fā),其工作方式為:在本地指定一個(gè)由ssh監(jiān)聽的轉(zhuǎn)發(fā)端口(2222),將遠(yuǎn)程主機(jī)的端口(host2:80)映射為本地端口(2222),當(dāng)有主機(jī)連接本地映射端口(2222)時(shí),本地ssh就將此端口的數(shù)據(jù)包轉(zhuǎn)發(fā)給中間主機(jī)(host3),然后host3再與遠(yuǎn)程主機(jī)的端口(host2:80)通信。
現(xiàn)在就可以通過(guò)訪問(wèn)host1的2222端口來(lái)達(dá)到訪問(wèn)host2:80的目的了。例如:
再來(lái)解釋下"-g"選項(xiàng),指定該選項(xiàng)表示允許外界主機(jī)連接本地轉(zhuǎn)發(fā)端口(2222),如果不指定"-g",則host4將無(wú)法通過(guò)訪問(wèn)host1:2222達(dá)到訪問(wèn)host2:80的目的。甚至,host1自身也不能使用172.16.10.5:2222,而只能使用localhost:2222或127.0.0.1:2222這樣的方式達(dá)到訪問(wèn)host2:80的目的,之所以如此,是因?yàn)楸镜剞D(zhuǎn)發(fā)端口默認(rèn)綁定在回環(huán)地址上。可以使用bind_addr來(lái)改變轉(zhuǎn)發(fā)端口的綁定地址,例如:
[root@xuexi ~]# ssh -L 172.16.10.5host2:80 host3
這樣,host1自身就能通過(guò)訪問(wèn)172.16.10.5:2222的方式達(dá)到訪問(wèn)host2:80的目的。
一般來(lái)說(shuō),使用轉(zhuǎn)發(fā)端口,都建議同時(shí)使用"-g"選項(xiàng),否則將只有自身能訪問(wèn)轉(zhuǎn)發(fā)端口。
再來(lái)分析下轉(zhuǎn)發(fā)端口通信的過(guò)程。
當(dāng)host4發(fā)起172.16.10.5:2222的連接時(shí)(即步驟①),數(shù)據(jù)包的目標(biāo)地址和端口為"172.16.10.5:2222"。由于host1上ssh已經(jīng)監(jiān)聽了2222端口,并且知道該端口映射自哪臺(tái)主機(jī)哪個(gè)端口,所以將會(huì)把該數(shù)據(jù)包目標(biāo)地址和端口替換為"172.16.10.3:80",并將此數(shù)據(jù)包通過(guò)轉(zhuǎn)發(fā)給host3。當(dāng)host3收到該數(shù)據(jù)包時(shí),發(fā)現(xiàn)是host1轉(zhuǎn)發(fā)過(guò)來(lái)請(qǐng)求訪問(wèn)host2:80的數(shù)據(jù)包,所以host3將代為訪問(wèn)host2的80端口。
所以,host1和host3之間的通信方式是SSH協(xié)議,這段連接是安全加密的,因此稱為"安全隧道",而host3和host2之間通信協(xié)議則是HTTP而不是ssh。
現(xiàn)在再來(lái)考慮下,通過(guò)本地端口轉(zhuǎn)發(fā)的方式如何實(shí)現(xiàn)ssh跳板的功能呢?仍以上圖為例:
[root@xuexi ~]# ssh -g -L 2233322 host3]
這樣只需使用ssh連上host1的22333端口就等于連接了host2的22端口。
最后,關(guān)于端口轉(zhuǎn)發(fā)有一個(gè)需要注意的問(wèn)題:ssh命令中帶有要執(zhí)行的命令。考慮了下面的三條在host1上執(zhí)行的命令的區(qū)別。
[root@xuexi ~]# ssh -g -L 2233322 host3 [root@xuexi ~]# ssh -g -L 2233322 host3 "ifconfig" [root@xuexi ~]# ssh -g -L 2233322 host3 "sleep 10"
第一條命令開啟了本地端口轉(zhuǎn)發(fā),且是以登錄到host3的方式開啟的,所以執(zhí)行完該命令后,將跳到host3主機(jī)上,當(dāng)退出host3時(shí),端口轉(zhuǎn)發(fā)功能將被關(guān)閉。另外,host1上之所以要開啟端口轉(zhuǎn)發(fā),目的是為了與host2進(jìn)行通信,而不是跳到host3上,所以應(yīng)該在ssh命令行上加上"-f"選項(xiàng)讓ssh在本機(jī)host1上以后臺(tái)方式提供端口轉(zhuǎn)發(fā)功能,而不是跳到host3上來(lái)提供端口轉(zhuǎn)發(fā)功能。
第二條命令在開啟本地轉(zhuǎn)發(fā)的時(shí)候還指定了要在host3上執(zhí)行"ifconfig"命令,但是ssh的工作機(jī)制是遠(yuǎn)程命令執(zhí)行完畢的那一刻,ssh關(guān)閉連接,所以此命令開啟的本地端口轉(zhuǎn)發(fā)功能有效期只有執(zhí)行ifconfig命令的一瞬間。
第三條命令和第二條命令類似,只不過(guò)指定的是睡眠10秒命令,所以此命令開啟的本地轉(zhuǎn)發(fā)功能有效期只有10秒。
結(jié)合上面的分析,開啟端口轉(zhuǎn)發(fā)功能時(shí),建議讓ssh以后臺(tái)方式提供端口轉(zhuǎn)發(fā)功能,且明確指示不要執(zhí)行任何ssh命令行上的遠(yuǎn)程命令。即最佳開啟方式為:
[root@xuexi ~]# ssh -f -N -g -L 2233322 host3
1.2 ssh安全隧道(二):遠(yuǎn)程端口轉(zhuǎn)發(fā)
ssh除了支持本地端口轉(zhuǎn)發(fā),還支持遠(yuǎn)程端口轉(zhuǎn)發(fā)。顧名思義,遠(yuǎn)程端口轉(zhuǎn)發(fā)表示的是將遠(yuǎn)程端口的數(shù)據(jù)轉(zhuǎn)發(fā)到本地。
如下圖:假如host3是內(nèi)網(wǎng)主機(jī),它能和host2互相通信,也能和host1通信,但反過(guò)來(lái),host1不能和host3通信。這時(shí)要讓host1訪問(wèn)host3或host2就沒(méi)辦法通過(guò)本地端口轉(zhuǎn)發(fā)了,因?yàn)橐趆ost1上開啟本地端口轉(zhuǎn)發(fā),必須要和host3通信請(qǐng)求建立隧道。
可以通過(guò)在host3上發(fā)起遠(yuǎn)程端口轉(zhuǎn)發(fā)來(lái)實(shí)現(xiàn),因?yàn)閔ost3能和host1通信,host3可以請(qǐng)求在host1和host3之間建立隧道。
語(yǔ)法如下:
ssh -R [bind_addr:]remote1_port:host:port remote1
以上圖為例,實(shí)現(xiàn)方式是在host3上執(zhí)行:
[root@xuexi ~]# ssh -R 2233380 host1
這表示host3請(qǐng)求host1上的sshd服務(wù),在host1上建立一個(gè)套接字監(jiān)聽22333端口,它是host2端口的映射,當(dāng)有主機(jī)連接host1:22333時(shí),此連接中的數(shù)據(jù)全部都通過(guò)host1和host3之間的安全隧道轉(zhuǎn)發(fā)給host3,再由host3向host2的80端口發(fā)起訪問(wèn)。由于host3請(qǐng)求開啟的轉(zhuǎn)發(fā)端口是在遠(yuǎn)程主機(jī)host1上的,所以稱為"遠(yuǎn)程端口轉(zhuǎn)發(fā)"。
再考慮下面這條命令所開啟的遠(yuǎn)程轉(zhuǎn)發(fā)端口,它是在host3上執(zhí)行的。
[root@xuexi ~]# ssh -R 2233380 host1
該命令將自身的host3:80映射到host1:22333上,這也能讓host1和host2、host3通信,因?yàn)樗淼朗墙⒃趆ost1:22333<-->host3:80上的。
但是,遠(yuǎn)程端口轉(zhuǎn)發(fā)和本地端口轉(zhuǎn)發(fā)最大的一個(gè)區(qū)別是,遠(yuǎn)程轉(zhuǎn)發(fā)端口是由host1上的sshd服務(wù)控制的,默認(rèn)配置情況下,sshd服務(wù)只允許本地開啟的遠(yuǎn)程轉(zhuǎn)發(fā)端口(22333)綁定在環(huán)回地址(127.0.0.1)上,即使顯式指定了bind_addr也無(wú)法覆蓋。例如:
[root@xuexi ~]# ssh -R *host2:80 host1 [root@xuexi ~]# netstat -tnlp Active Internet connections (only servers) tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 8405/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1422/master tcp 0 0 127.0.0.1:22333 0.0.0.0:* LISTEN 8407/sshd tcp 0 0 :::22 :::* LISTEN 8405/sshd tcp 0 0 ::1:25 :::* LISTEN 1422/master tcp 0 0 ::1:22333 :::* LISTEN 8407/sshd
要允許本地的遠(yuǎn)程轉(zhuǎn)發(fā)端口綁定在非環(huán)回地址上,需要在host1的sshd配置文件中啟用"GatewayPorts"項(xiàng),它的默認(rèn)值為no。啟動(dòng)該選項(xiàng)后,不給定bind_addr或bind_addr設(shè)置為"*"都表示綁定在所有地址上。如下:
[root@xuexi ~]# ssh -g -R *host2:80 host1 [root@xuexi ~]# netstat -tnlp Active Internet connections (only servers) tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 8466/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1422/master tcp 0 0 0.0.0.0:22333 0.0.0.0:* LISTEN 8468/sshd tcp 0 0 :::22 :::* LISTEN 8466/sshd tcp 0 0 ::1:25 :::* LISTEN 1422/master tcp 0 0 :::22333 :::* LISTEN 8468/sshd
和前面的本地轉(zhuǎn)發(fā)端口一樣,建議的幾個(gè)選項(xiàng)是:"-g"、"-f"、"-N"。即推薦的命令寫法是:
[root@xuexi ~]# ssh -fgN -R 2233380 host1
現(xiàn)在,就可以通過(guò)訪問(wèn)host1:22333達(dá)到訪問(wèn)host2:80的目的了。如下圖所示。
1.3 ssh安全隧道(三):動(dòng)態(tài)端口轉(zhuǎn)發(fā)(SOCKS代理)
無(wú)論是本地端口轉(zhuǎn)發(fā)還是遠(yuǎn)程端口轉(zhuǎn)發(fā),都是將某固定主機(jī)及其端口映射到本地或遠(yuǎn)程轉(zhuǎn)發(fā)端口上,例如將host2:80映射到host1:2222。也就是說(shuō),本地或遠(yuǎn)程轉(zhuǎn)發(fā)端口和目標(biāo)端口所代表的應(yīng)用層協(xié)議是一對(duì)一的關(guān)系,2222端口必須對(duì)應(yīng)的是http的80端口,使用瀏覽器向host1:2222端口發(fā)起http請(qǐng)求當(dāng)然沒(méi)問(wèn)題,但是使用ssh工具向host1:2222發(fā)起連接將會(huì)被拒絕,因?yàn)閔ost2上http服務(wù)只能解析http請(qǐng)求,不能解析ssh連接請(qǐng)求。
ssh支持動(dòng)態(tài)端口轉(zhuǎn)發(fā),由ssh來(lái)判斷發(fā)起請(qǐng)求的工具使用的是什么應(yīng)用層協(xié)議,然后根據(jù)判斷出的協(xié)議結(jié)果決定目標(biāo)端口。
以下圖為例進(jìn)行說(shuō)明,host1處在辦公內(nèi)網(wǎng),能和host3互相通信,但它無(wú)法直接和互聯(lián)網(wǎng)和host2通信,而host3則可以和host2以及互聯(lián)網(wǎng)通信。
要讓host1訪問(wèn)互聯(lián)網(wǎng),又能和host2的22端口即ssh服務(wù)通信,顯然在host1上僅設(shè)置一個(gè)本地端口轉(zhuǎn)發(fā)是不夠的,雖然可以設(shè)置多個(gè)本地轉(zhuǎn)發(fā)端口分別映射不同的端口,但這顯然比較笨重和麻煩。使用動(dòng)態(tài)端口轉(zhuǎn)發(fā)即可。
語(yǔ)法格式為:
ssh -D [bind_addr:]port remote
以上圖為例,在host1上執(zhí)行:
[root@xuexi ~]# ssh -Nfg -D 2222 host3
執(zhí)行完上面的命令,host1將在本地開啟SOCKS4或SOCKS5服務(wù)來(lái)監(jiān)聽2222端口。只要客戶端程序工具(隱含了使用的應(yīng)用層協(xié)議類型)將其自身的代理設(shè)置為host1:2222,則該程序所有產(chǎn)生的數(shù)據(jù)都將轉(zhuǎn)發(fā)到host1:2222,再由host1:2222將數(shù)據(jù)通過(guò)隧道轉(zhuǎn)發(fā)給host3,最后由host3和互聯(lián)網(wǎng)或host2上對(duì)應(yīng)客戶端工具的應(yīng)用層協(xié)議的端口進(jìn)行通信。
其實(shí)很簡(jiǎn)單,假如host4使用IE瀏覽器作為客戶端工具,并將IE瀏覽器的代理設(shè)置為host1:2222,由于IE瀏覽器發(fā)起的請(qǐng)求使用的是http協(xié)議(此處不考慮其他可能的協(xié)議),那么IE瀏覽器產(chǎn)生的數(shù)據(jù)都轉(zhuǎn)發(fā)到host1:2222,再由host1:2222通過(guò)隧道轉(zhuǎn)發(fā)給host3,host3能聯(lián)網(wǎng),所以host4就實(shí)現(xiàn)了聯(lián)網(wǎng)功能。如下圖設(shè)置:
再比如host4上的QQ客戶端也可以設(shè)置代理。這樣QQ產(chǎn)生的數(shù)據(jù)都將通過(guò)host1:2222轉(zhuǎn)發(fā)出去,host1:2222再將QQ的數(shù)據(jù)轉(zhuǎn)發(fā)到host3上,host3知道這些數(shù)據(jù)使用的協(xié)議是oicq,所以host3會(huì)去連接騰訊的QQ服務(wù)器(oicq服務(wù)對(duì)應(yīng)的端口)。
ssh只支持socks4和socks5兩種代理,有些客戶端工具中需要明確指明代理類型。
和本地、遠(yuǎn)程端口轉(zhuǎn)發(fā)一樣,建議的選項(xiàng)是:"-f"、"-N"和"-g"。
由于ssh動(dòng)態(tài)端口轉(zhuǎn)發(fā)是ssh客戶端的功能,所以不使用ssh命令,使用SecurtCRT、putty等ssh客戶端工具都可以實(shí)現(xiàn)代理上網(wǎng)。例如,本地主機(jī)不能上網(wǎng),但能和172.16.10.6的SSH服務(wù)通信,而172.16.10.6能上網(wǎng),則可以在本地主機(jī)先使用SecurtCRT連接172.16.10.6,再在對(duì)應(yīng)的會(huì)話選項(xiàng)上做如下設(shè)置,使得本地主機(jī)也能上網(wǎng)。(注意:我沒(méi)說(shuō)可以FQ啊,好公民不FQ!!!)
然后,在本地主機(jī)查看下是否監(jiān)聽了SecurtCRT中指定的8888動(dòng)態(tài)轉(zhuǎn)發(fā)端口。
現(xiàn)在,本機(jī)所有數(shù)據(jù)包都通過(guò)SecurtCRT所連接的172.16.10.6流向外界。
鏈接:https://www.cnblogs.com/f-ck-need-u/p/10482832.html
-
主機(jī)
+關(guān)注
關(guān)注
0文章
985瀏覽量
35065 -
端口
+關(guān)注
關(guān)注
4文章
955瀏覽量
32014 -
SSH
+關(guān)注
關(guān)注
0文章
185瀏覽量
16303
原文標(biāo)題:SSH隧道:端口轉(zhuǎn)發(fā)功能詳解
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論