SOCKS 是一種網絡傳輸協議,主要用於客戶端與外網服務器之間通訊的中間傳遞。SOCKS 是 "SOCKetS" 的縮寫。
當防火牆后的客戶端要訪問外部的服務器時,就跟 Socks 代理服務器連接。這個代理服務器控制客戶端訪問外網的資格,允許的話,就將客戶端的請求發往外部的服務器。
該協議設計之初是為了讓有權限的用戶可以穿過過防火牆的限制,使得高權限用戶可以訪問外部資源。
socks 協議的設計初衷是在保證網絡隔離的情況下,提高部分人員的網絡訪問權限,但是國內似乎很少有組織機構這樣使用。
但是由於 socksCap32 和 PSD 這類軟件,人們找到了 socks 協議新的用途:突破網絡通信限制,這和該協議的設計初衷正好相反。
這個協議最初由 David Koblas 開發,而后由 NEC 的 Ying-Da Lee 將其擴展到版本 4。最新協議是版本 5,與前一版本相比,增加支持 UDP、驗證,以及 IPv6。
根據 OSI 模型,SOCKS 是會話層的協議,位於表示層與傳輸層之間。
起源
最早,整個互聯網采用的是盲目信任的方式進行連接和組織的。當時,專家們在聚會的時候,討論的都是怎么讓網絡更加簡單和高效,一台主機在網絡上到底怎么才能更可靠的被別的主機所連接。一直到 1988 年,一個叫做 Morris 的蠕蟲,給整個互聯網一記重拳,后來大家討論將一個子網絡接入到互聯網的時候,安全也成了一個必須要討論的重要話題。
不過,提升網絡的安全性可沒有什么容易的辦法,想出來的大部分辦法都是通過減少內網服務器向公網暴露的機會,來最小化攻擊的概率,也就是我們常喜歡用的“最小原則”,如果沒有必要,就不進行授權。很多網絡在接入互聯網的時候,都選擇了單一出入口的方式。將本地的子網絡,置於防火牆的保護之后,再接入到互聯網,如此一來就極大減少了被攻擊的機會,網絡的安全性自然就提高了。
但是本地網絡置於防火牆之后,再訪問外部網絡的資源就會非常不便。為了解決這個問題,人們想出了各種方案。內外網隔離(笨拙,使用極其不便,但是維護成本很低),單一機器授權(只有一台機器可以和外網進行雙向訪問,使用仍然非常不便,而且維護成本高昂,因為有很多用戶的訪問權限要分配和收回),還有安全路由器(常見的一種策略是允許所有的出口流量,但是對進口流量禁止所有 1024 以下端口的訪問,這種策略的問題是,一旦路由被攻破,整個網絡就置於威脅之下)。
在這些方案之外,代理防火牆(Proxy Firewall)解決方案就被提出來了。路由器是在 OSI 模型的“網絡層”進行安全過濾,可以降低客戶端的成本,但是不夠完善,維護起來也比較困難,估計當年的硬件不像現在可以隨意修改配置吧。代理防火牆的方案,平衡了使用的便捷和維護的復雜度,是一種折衷。
代理防火牆工作在 OSI 模型的“會話層”,也就是“傳輸層”和“應用層”中間的地方。著名的 SOCKS 就是這樣一種“解決方案”。它是一種非常輕薄的解決方案,在客戶端,提供了一套開發類庫,叫 SOCKS 庫,對照着標准 socket 的 API,提供了五個 API 函數,名字跟 socket 的一樣,只是用 R 作為前綴。
在服務器端,提供了一個叫做 sockd 的伺服軟件,這個軟件部署在防火牆系統所在的一台主機上,通過簡單的配置文件就可以完成應用層的過濾(正因為它處於會話層,所以非常方便處理應用層過濾),允許或拒絕哪些目的地址和端口被接入,是非常容易維護的,給網絡管理員帶來了極大的方便。
在 1992 年公布之前,SOCKS 解決方案已經在 MIPS 內部使用了長達三年之久,沒有遇到明顯的問題和瓶頸,所以 David 認為這是一個久經烤驗的成熟方案。
發展
SOCKS 最初提出的時候,其性質是一個解決方案,包含一個類庫和一個服務端后台伺服程序。但是,NEC 公司的李英達?(Ying-da Lee),看到了它的優美之處,把它提煉出來,發展成了一種協議,變得更加通用,而且,大家都可以根據協議提出自己的實現。這位李同學,提出了 SOCKS 協議的第四個版本。也是流傳非常廣泛的版本。
從李同學開始,SOCKS 的定位也變得非常明確,就是在防火牆服務器上,提供一種 TCP 會話的轉發,允許用戶可以透明的穿透防火牆的阻攔。
這種協議的優勢在於,它完全獨立於應用層的協議,可以用在很多的場景,telnet,http,ftp 都不在話下,並且可以在 TCP 會話開始之前,完成訪問權限的檢查,之后只要做來回往復的轉發即可。而且由於此協議完全不關心應用層的協議,所以應用層通信可以加密,保護自己通信的內容不被代理所看到。
最新協議是版本 5,與前一版本相比,增加支持 UDP、驗證,以及 IPv6。
與HTTP代理的對比
SOCKS 工作在比 HTTP 代理更低的層次:SOCKS 使用握手協議來通知代理軟件其客戶端試圖進行的連接 SOCKS,然后盡可能透明地進行操作,而常規代理可能會解釋和重寫報頭。
雖然 HTTP 代理有不同的使用模式,CONNECT 方法允許轉發 TCP 連接;然而,SOCKS 代理還可以轉發 UDP 流量和反向代理,而 HTTP 代理不能(HTTP 本質使用的是 TCP 協議),socks 不管應用層是什么協議,只要是傳輸層是 TCP/UDP 協議就可以代理。
socks 支持多種用戶身份驗證方式和通信加密方式。
不足
由於承擔了額外的驗證協商的功能,導致 SOCKS5 在建立的時候,需要額外消耗多達三次握手,如果不需要驗證身份,也需要兩次握手,這就增加連接時候的延遲。
另外,因為 SOCKS5 協議本身完全不關注應用層的內容,所以,客戶端和目標服務器的通信,加密完全依賴客戶端和服務器的通信協議,如果服務器使用的是 HTTP 協議,那么通過代理走的流量,就相當於是明文在內網傳輸。安全性上不是很高。
不過,我們可以通過在外面包裹一層 TLS 來解決這個問題,就形成了 SOCKS5 over TLS 的解決方案,有效加密了通信的內容。TLS 負責加密連接,SOCKS5 負責代理協議控制。
互聯網上已經公布了 SOCKSv6 的草案,主要內容就是 SOCKS5 的問題修復,第一個就是多次握手已經不太適用於移動互聯網和衛星通信等網絡環境,需要被優化。客戶端會盡可能多的發送信息給服務器,並且要求創建 socket 之前,不等待驗證的結論等等
端口映射與端口轉發
端口映射是 NAT 的一種,功能是把在公網的地址轉翻譯成私有地址
端口映射就是將外網主機的 IP 地址的一個端口映射到內網中一台機器,提供相應的服務。當用戶訪問該 IP 的這個端口時,服務器自動將請求映射到對應局域網內部的機器上。端口映射有動態和靜態之分。
當用戶訪問提供映射端口主機的某個端口時,服務器將請求轉移到本地局域網內部提供這種特定服務的主機;利用端口映射功能還可以將一台外網 IP 地址機器的多個端口映射到內網不同機器上的不同端口。
端口映射功能還可以完成一些特定代理功能,比如代理 POP,SMTP,TELNET 等協議。理論上可以提供 65535(總端口數)- 1024(保留端口數)= 64511 個端口的映射。
端口轉發(Port forwarding),有時被叫做隧道,是安全殼(SSH) 為網絡安全通信使用的一種方法。端口轉發是轉發一個網絡端口從一個網絡節點到另一個網絡節點的行為,其使一個外部用戶從外部經過一個被激活的 NAT 路由器到達一個在私有內部 IP 地址(局域網內部)上的一個端口。
端口轉發應該是將發送到內網機器指定端口的數據丟給另外一個機器的某個端口,在轉發的過程可以對數據包進行修改和檢查;
端口映射就跟路由器一樣,你要提供 WEB 服務,那么就得先映射 80 端口,外部用戶通過 80 端口訪問你的 WEB 服務(外部用戶訪問 80 端口,就會被翻譯為內網 ip 的端口),映射過程只能源數據傳輸。