我們知道,ssh會自動加密和解密所有得ssh用戶端與伺服器之間得網絡資料。但是,ssh還同時提供了一個非常有用的功能,就是端口轉發。它能夠将其他tcp端口的網絡資料通過ssh連結來轉發,并且自動提供了相應加密和解密服務。這一過程也叫做“隧道”,這是因為ssh為其他的tcp連結提供了一個安全的通道來進行傳輸而得名。例如,telnet ,smtp ,ldap這些tcp應用均能夠從中獲益,避免了使用者名,密碼以及隐私資訊的明文傳輸。而與此同時,如果工作環境中的防火牆限制了一些網絡端口的使用,但是允許ssh的連接配接,那麼也是能夠通過将tcp端口轉發來使用ssh進行通訊。總的來說ssh端口轉發能夠提供兩大功能:
加密ssh client端至ssh server端之間的通訊。
突破防火牆的i限制完成一些之前無法建立的tcp連接配接
在實驗室裡有一台ldap伺服器,但是限制了隻有本機上的部署的應用才能直接連接配接此ldap伺服器。如果我們由于調試或者測試的需要想臨時從遠端機器直接連接配接到這個ldap伺服器,那我們就需要通過下圖的方式,也就是本地端口轉發來實作了。
如上圖所示,選擇了一個空閑端口7001,資料流方向将會如下所述:
我們在ldap client 上的應用将資料發送到本機的7001端口上。
本機的ssh client會将7001端口收到的資料加密并轉發到ldap server的ssh server上。
ssh server會解密收到的資料并将之轉發到監聽的ldap的端口上。
最後再将從ldap傳回的資料原路傳回以達到我們的目的。
整個過程應用并沒有直接連接配接ldap伺服器,而是連到了本地的一個監聽端口,但是ssh轉發完成看剩下的所有事情,加密、轉發解密通訊。那麼如何在ldap client上建立ssh的本地端口轉發呢?其實很簡單,隻需要一條指令:
注:ldap服務監聽端口是389
同樣以ldap服務為例,但是在這裡由于網絡或防火牆的原因我們不能用ssh直接從ldap clie,那麼我們就得選擇遠端端口轉發了。具體如下圖所示:
和本地端口轉發相比,這次得圖裡,ssh server和ssh client的位置對調了一下,但是資料流依然是一樣的。我們在 ldap client上的應用将資料發送到本機的 7001 端口上,而本機的 ssh server 會将 7001 端口收到的資料加密并轉發到 ldap server 的 ssh client 上。 ssh client 會解密收到的資料并将之轉發到監聽的 ldap 389 端口上,最後再将從 ldap 傳回的資料原路傳回以完成整個流程。
同樣的,我們隻需要通過一條指令就可以實作上述流程
由上述的本地端口轉發和遠端端口轉發我們發現,兩種轉發方式的資料流是一緻的,那麼他們到底有什麼差別呢?
首先,ssh端口轉發是需要的ssh連接配接的,而ssh連接配接室友是有方向的,從ssh client到ssh server.
其次,我們的應用也是有方向的,比如我們想要連接配接到ldap的伺服器,則我們需要從ldap的client去連接配接ldap的server,連接配接方向也是從client到server端。
最後,我們可以看到,本地端口轉發的應用的連接配接方向和ssh的連接配接方向是一緻的;而遠端端口轉發應用連接配接方向和ssh連接配接方向是相反的。
是以說,我們可以直接通過應用的連接配接方向和ssh的連接配接方向來判斷,如果這兩個連接配接的方向一緻,那我們就說它是本地轉發。而如果兩個方向不一緻,我們就說它是遠端轉發。
ssh動态綁定
這是ssh×××的基本原理:利用ssh動态綁定的功能。那麼何謂ssh動态綁定呢?動态綁定是ssh端口轉發功能的一種形式。
首先,牆内的客戶機跟牆外的代理伺服器,建立好ssh連接配接,并設定動态綁定
此時牆内客戶機上的ssh會監聽本地的一個端口7001
客戶機上的程式,将對www.youtube.com:80的請求告知7001端口的ssh,ssh将此請求通過ssh加密連接配接發送到牆外伺服器的ssh上
由于建立的動态綁定,伺服器會将www.youtube.com:80的請求發送給www.youtube.com上的80端口,并在收到回複後,通過原路傳回給客戶機的ssh,
如下圖所示:
客戶機的ssh傳回給應用程式在這裡ssh用戶端已經不僅僅是個用戶端了,它同時打開了7001端口偵聽本機應用程式的請求。這是ssh跟傳統用法最大的差別。而服務端的ssh也不僅僅是處理用戶端的請求,而是将請求轉發到對應的主機和端口,這裡的動态二字展現在服務端的ssh的轉發目标是不固定的,是根據用戶端的請求而定的。
socks代理
那麼如何讓應用程式知道應該把請求發送給本機的7001端口呢?
答案就是socks代理。
實際上socks代理普遍被許多應用程式支援:qq、浏覽器、msn…是以在上述的模型中,客戶機的ssh實際上就是實作了一個socks代理的角色,這個socks代理偵聽了7001端口,并将所有的請求都代理給伺服器的ssh,并利用ssh動态綁定,讓伺服器進一步轉發請求。
ssh隧道的搭建
其實ssh搭建很簡單,我們隻需要牆外有一台支援ssh的伺服器就可以了,然後在用戶端ssh執行如下指令:
上述指令中-d表示動态綁定,7001表示本地socks代理的偵聽端口,可以改成别的,後面的username@remote-host就是你登入遠端伺服器的使用者名和主機。當然,這個指令後會提示輸入密碼,就是username這個使用者的密碼。
密碼正确輸入後,隧道也就成功打通了。最後在浏覽器或者其他應用程式上設定socks代理,代理指向127.0.0.1,端口7001即可,這樣科學上網就實作了。