深入理解ssh端口轉發細節

深入理解ssh端口轉發細節

一.本地端口轉發
A機: 172.16.32.123
B機: 172.16.32.102, 10.0.0.2
C機: 10.0.0.1
(說明:C機與B機直連,C機無網關設置,只能與B機進行通信)

B機:(可以使用netstat -nap |grep 7001看到B機上啓動了一個監聽7001端口的服務)
luther@gliethttp:~$ ssh -CfNg -L 7001:localhost:22 [email protected]

A機:(連接B機上的7001端口,因爲B機將7001端口監聽到的數據,直接轉發給了C機,所以A將成功登錄到C機)
luther@gliethttp:~$ ssh -p 7001 [email protected]
     這樣A機就一下子連接到ip地址爲10.0.0.1的C機了,實現了連接穿透.

讓我們來仔細理解理解,A和C之間因不位於同一網段而不可見,B和A可見,B和C可見,
於是B就可以擔當起轉發A數據到C的角色.

連接圖:A <=> B <==> C

ssh -L <local port>:<remote host>:<remote port> <SSH地址>

我們再來拆解一下語句:
1. B和C建立ssh連接
ssh [email protected] 
2. 參數-CfNg -L的解釋
C - 壓縮數據傳輸
f - 後臺用戶驗證,允許沒有shell的不可登陸賬號使用
N - 不執行腳本或命令
g - 允許遠程主機連接轉發端口
L - 本地轉發
3. 7001
表示ssh語句執行時,會同時在B機上由ssh命令自動開啓一個監聽B機上7001端口的service服務
4. :localhost:22
   這個是最不易搞懂的地方,關鍵是這個參數是由誰來使用,當B機執行ssh的時候,C機上的ssh server
   會接受B機的ssh連接,同時B機的參數:localhost:22被傳遞到C機的ssh server行,ssh server會解析
   這個參數,C機上的ssh server會將B機ssh發送過來的數據,轉發到<remote host>的<remote port>端口上.
可以使用如下實例驗證:
a機: 172.16.32.102
b機: 172.16.32.123
c機: 172.16.32.112
d機: 172.16.32.54

只需要在b機上運行
luther@gliethttp:~$ ssh -CfNg -L 7001:172.16.32.112:22 [email protected]
然後在d機上運行
luther@gliethttp:~$ ssh -p 7001 172.16.32.123
數據流圖:
d <=> b <=> a <=> c
d機連接b機7001端口,b機將d機發送的數據轉發到a機的ssh server上,a機的ssh server根據
參數<remote host>:<remote port>即:172.16.32.112:22的定義,
將接收的數據進一步轉發到<remote host>的<remote port>端口上,也就是172.16.32.112的22端口上,
所以d機最終和c機建立了ssh連接[luther.gliethttp]

二.遠端端口轉發
另一種ssh端口轉發方式是使用參數-R,而不是-L.

ssh -R <local port>:<remote host>:<remote port> <SSH地址>
A機: 172.16.32.123
B機: 172.16.32.102, 10.0.0.2
C機: 10.0.0.1
(說明:C機與B機直連,C機無網關設置,只能與B機進行通信)

B機:運行如下命令
luther@gliethttp:~$ ssh -CfNg -R 7001:localhost:22 [email protected]

C機:查看由C機上ssh server根據B機ssh連接的參數-R 7001創建的監聽端口7001
     我們在C機上使用netstat -nap |grep 7001看到C機上啓動了一個監聽7001端口的服務,
     而C機上這個監聽7001端口的服務是C機的ssh server根據B機執行ssh連接時的
     參數-R 7001而由C機ssh server被動建立起來的.

同時C機上只能使用如下命令和C機自己身上的7001端口建立連接,不能使用ip地址,包括(10.0.0.1)
luther@gliethttp:~$ ssh -p 7001 luther@localhost
或者
luther@gliethttp:~$ ssh -p 7001 [email protected]
以上2條命令使得C機可以ssh到B機.
另外也可以和上面-L一樣,
B機:運行如下命令
luther@gliethttp:~$ ssh -CfNg -R 7001:172.16.32.123:22 [email protected]
這時B機建立與C機的ssh,同時通知C機的ssh server,在C機上開啓一個監聽端口7001,
這樣C機向C機本地的7001端口發送數據的時候,B機就能接收到,然後B機將根據
參數:172.16.32.123:22信息,將C機發送過來的數據轉發到A機172.16.32.123的22端口
於是C機執行
ssh -p 7001 luther@localhost
就是等於向A機172.16.32.123的22端口發出ssh連接[luther.gliethttp]

三.比較本地端口轉發-L和遠端端口轉發-R:
ssh -L <local port>:<remote host>:<remote port> <SSH地址>
ssh -R <local port>:<remote host>:<remote port> <SSH地址>
參數-L就是<local port>監聽端口在執行ssh的機器上建立,參數<remote host>:<remote port>由<SSH地址>主機處理
參數-R就是<local port>監聽端口在<SSH地址>主機上建立,參數<remote host>:<remote port>由執行ssh的機器處理

四.動態端口轉發-D,設置SOCKS4和SOCKS5代理功能
B機: 172.16.32.102, 10.0.0.2
C機: 10.0.0.1
在C機上執行
ssh -CfNg -D 7001 [email protected]
這樣C機上將建立一個7001監聽端口,C機可以向7001端口發送任何數據,然後B機10.0.0.2會將C機發送的數據
根據C機發送數據的端口號,動態的向外部遞交,一般用在SOCKS代理,
C機的localhost:7001就是代理參數,可以在firefox上設置,這樣C機就能通過B機上web網了.
到這裏我們可以看出-L就是-D的一個具體實例使用,但是-D不能像-L一樣,與指定的端口建立連接,所以-D使用在
SOCKS代理上[luther.gliethttp].
Firefox==>Edit==>Preferences==>Advanced
==>Network/Settings==>Manual proxy configuration
==>SOCKS Host: localhost
==>SOCKS Port: 7001
這樣C機就能使用firefox上網了[luther.gliethttp]
(注意:因爲C機的網關和DNS都沒有設置,所以只能使用firefox中直接輸入ip的方式上網,
比如www.google.com的ip地址爲64.233.189.103).

五.X協議轉發,實現ssh直接打開<SSH地址>主機上的GUI程序
A機(redhat): 172.16.32.102
B機(ubuntu): 172.16.32.123
首先A機進入桌面環境,打開一個terminal,
輸入
luther@gliethttp:~$   ssh -X [email protected]              注意-X大寫使能X11轉發,           -x小寫禁用X11轉發
但是缺點是隻能查看,不能拖動拷貝到本機
[root@localhost ~]# firefox         執行遠程機172.16.32.123上的firefox程序
[root@localhost ~]# nautilus /      執行遠程機172.16.32.123上的nautilus文件瀏覽器

總結:
A機公司局域網
B機公網linux主機
C機家裏的notebook
A機: 
luther@gliethttp:~$ ssh -CfNg -R 7001:localhost:22     用戶名@B機
C機: 
luther@gliethttp:~$ ssh -CfNg -L 7000:localhost:7001   用戶名@B機
C機: 
luther@gliethttp:~$ ssh -p 7000 A機用戶名@localhost    就可以登錄公司的A機了
C機: 
luther@gliethttp:~$ ssh -X -p 7000 A機用戶名@localhost 就可以執行A機上的圖形程序了,比如nautilus . 

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章