1. 程式人生 > >基於SSH埠轉發實現telnet的安全傳輸

基於SSH埠轉發實現telnet的安全傳輸

學過一點Linux的人看到這題目,可能就感覺有點白痴。確實,SSH的一大功能就是加密的遠端登入,何必多此一舉。

在此,不得不先宣告,本文的重點是實現SSH安全埠轉發的功能。熟悉SSH的人都知道,埠轉發也是SSH的一大功能。此功能可以加密非安全的TCP連線,如:FTP,IMAP,HTTP等協議。之所以選擇telnet,就在於telnet協議相對簡單,雖然此實驗不具有實用性,但能使我們更容易理解SSH埠轉發的工作原理。

一、實驗環境:

兩臺Linux虛擬機器,並且安裝有telnet、ssh和tcpdump。需要注意的是telnet和ssh都是CS工作模式,安裝包包括客戶端和伺服器。在宿主機上用putty登陸Linux。

二、實驗步驟:

1、在Linux 172.16.1.3上輸入下列命令:

 tcpdump -w pack2.sshtel host 172.16.1.2 and 172.16.1.3

用tcpdump捕獲兩臺虛擬機器之間傳送的資料包,並將其儲存到pack2.sshtel檔案中。

因為tcpdump不具有資料包分析功能,在此我們使用wireshark對軟體進行分析。

2、在Linux 172.16.1.2上建立埠轉發的命令:

ssh -L2000:localhost:23 172.16.1.3  

開啟一個到172.16.1.3的ssh連線,-L表明是本地轉發,此時TCP客戶端和SSH客戶端同在本地主機上(即172.16.1.2)。後面接著三個值,有冒號分開,分別表示:需要監聽的本地埠(2000),遠端主機名或IP地址(172.16.1.3)以及遠端的轉發目標埠號(23是telnet的埠號)。

上面的命令可完成登陸到172.16.1.3的功能,如果僅輸入ssh 172.16.1.3也能達到同樣的效果。然而,現在的這個SSH會話同時將Linux 172.16.1.2的2000埠轉發到Linux 172.16.1.3的23埠;在退出會話之前轉發一直有效。

【註明:關於建立SSH遠端埠轉發的命令還有另外一種格式 

  ssh  -P  [email protected] -L localpost:host:hostport  

  解釋如下:

            -P 用一個非特權埠進行出去的連線; 

            sshaccount 本地主機在遠端主機伺服器上的SSH連線帳號 

          -L 110:S:110 轉發本地埠(localport)的連線到遠端主機埠(hostport)。

也可以用高階埠(普通使用者使用,因為普通使用者不能在低於1024的埠上建立SSH隧道),如果用高階埠,如:-L 1110:S:110,這樣任何使用者都可建立這種加密隧道。】

3、再開啟一個遠端回話到Linux172.16.1.2,通過telnet遠端連線到Linux 172.16.1.3,並告知telnet客戶端使用被轉發的本地埠2000,命令如下:

 telnet localhost 2000

之所以另外開啟一個遠端會話,只是為了更清楚的看到埠轉發的過程。我們也完全可以讓ssh埠轉發的命令在後臺執行(ssh -f -L2000:localhost:23 172.16.1.3 sleep 7200),繼而在同一個putty遠端會話中完成telnet連線。

至此,SSH安全埠轉發telnet,實現telnet的加密傳輸就完成了。

三、資料包分析:

由於wireshark安裝的宿主機,所以需要使用ftp將pack2.sshtel檔案傳回到宿主機;

另外,arp協議,三次握手tcp連線過程不做詳細介紹,直接進入SSH協議的連線過程:

1、 版本協商

目前 SSH 實現中,比較普遍的協議版本號是 SSH2.0,但是因為還有一些網路裝置上執行的是比較老的版本號,所以在實現的時候必須考慮版本相容性問題。

當 TCP 連線建立之後,通訊的雙方都必須向對方傳送自己的版本字串,其中包括,SSH 的協議版本號、軟體版本號等,版本字串最長是 255 位元組。

版本協商包括兩種情況:舊的客戶端和新的伺服器端之間,以及新的客戶端和舊的伺服器端之間。

新的伺服器端實現時,必須有一個可以配置的相容選項,來控制是否相容舊的版本的客戶端登入。如果相容,這個伺服器端在版本協商階段往對端傳送的協議版本號就是 1.99。如果是 2.0 的客戶端登入,1.99 和 2.0 的伺服器端對於它來說應該是一致的,而對於 1.5 以及以下的客戶端來說,1.99 意味著這個伺服器相容 1.5 的版本,版本協商可以通過。如果伺服器配置成不相容 2.0 的協議,那麼它向對端傳送的協議版本號就是 2.0,當 1.5 的客戶端登入時,發現對端的協議版本號是 2.0,版本協商就不會成功,雙方斷開 TCP/IP 連線。

當新的客戶端登入舊的伺服器時,由於客戶端不能去相容伺服器,所以遇到舊的伺服器的時候,客戶端必須斷開連線,使用舊的版本再去登入。

2、演算法協商與金鑰交換

版本協商、演算法協商和金鑰交換都是以明文的方式進行,這些都可以在資料包中得到體現。從此對雙方互動報文的報文長度欄位、填充長度欄位、淨荷欄位、填充欄位以及之後的資料傳輸都必須使用協商出來的演算法進行加密。

四、實驗改進:

1、讓ssh -L2000:localhost:23 172.16.1.3的命令在後臺執行

讓程式在後臺跑後,不會佔據終端,我們可以用終端做別的事情,也就是說我們可以在同一終端進行telnet的連線,而不用再開啟一個到Linux 172.16.1.2的遠端終端。後臺執行的命令是:

ssh -f -L2000:localhost:23 172.16.1.3 sleep 7200

-f 引數表示讓埠轉發建立以後,就轉入後臺執行; sleep 7200表示該命令在後臺執行的時間,7200表示2個小時。

2、直接使用宿主機上的wireshark程式可以直接捕獲虛擬機器之間的資料包,不用在Linux 172.16.1.3上執行tcpdump,再將存有資料包的檔案傳送到宿主機。這樣實驗步驟更簡單。

五、改進後的實驗步驟:

1、在宿主機上執行wireshark,捕捉過濾器的過濾語句: host 172.16.1.2 and 172.16.1.3;

2、在Linux 172.16.1.2上建立ssh埠轉發:

   ssh -L2000:localhost:23 172.16.1.3 (非後臺執行,會佔據終端,需要另外開啟一個遠端終端來完成餘下試驗)

   ssh -f -L2000:localhost:23 172.16.1.3 sleep 7200(後臺執行,不會佔據終端,可以繼續使用該終端完成實驗);

3、依據是否選擇了後臺執行,選擇正確的終端進行telnet連線:telnet localhost 2000;

4、分析wireshark捕獲的資料包。

總結:SSH將本地埠(localhost 2000)轉發到遠端主機的23埠(ssh伺服器所監聽的埠),這樣凡事經過localhost 2000埠進行的tcp連線都會通過SSH的安全隧道傳送到遠端主機的23埠;只要我們將本地tcp連線的埠設定為轉發埠(localhost 2000),這樣該tcp連線就會通過SSH的安全隧道進行傳輸,將不安全的tcp傳輸變為保密傳輸。當然,SSH客戶端在建立連線時的埠仍是隨機產生的,所以在捕獲的資料包中我們不會發現轉發埠2000。