網絡協議之:一定要大寫的SOCKS


簡介

很久很久以前,人們還穿的是草鞋,草鞋雖然穿着舒服,但是不夠美觀。然后人們就發現,用動物的皮也可以做成鞋,於是出現了皮鞋。但是皮鞋穿着磨腳,於是人們又發明了socks,套在腳上,代替腳跟鞋子接觸,既提高了舒適感,也減少了磨損,簡直是一舉兩得的事情,非常完美。

在網絡世界,也存在這樣的socks,為了和真實世界的socks進行區分,這里我們使用大寫的SOCKS。

SOCKS就是我們今天要講解的網絡代理協議。

SOCKS的故事

在講解SOCKS之前,我們回顧一下OSI網絡七層協議。

OSI是Open System Interconnect的縮寫,意為開放式系統互聯。

而SOCKS也是一種網絡協議,它的作用和socks一樣,用來代替客戶端和服務器端進行連接,也就是代理協議。

SOCKS在OSI七層協議的第五層,也就是會話層中,它處於表現層和傳輸層的中間。從上圖可以看到SOCKS的底層就是TCP和UDP協議。

作為一個代理協議,SOCKS可以提供基於TCP和UDP的代理,相較於HTTP的代理而言,SOCKS的代理更加底層,所以應用場景也會更多。

通常來說,SOCKS的標准端口是1080。

SOCKS的歷史

每個協議都有自己的發展史,SOCKS也不例外,如果要把所有協議的發展史以故事的形式講述起來一定會很有意思,大家可以期待一下,說不定某天這樣的文章就出現了。

代理是網絡中的一項基本功能,SOCKS代理最先是由美國MIPS科技公司的David Koblas設計的。MIPS公司以開發MIPS架構和基於該架構的一系列 RISC CPU 芯片而聞名。不過后面被一系列的收購,最終MIPS 架構被放棄了,轉而支持RISC-V架構。

MIPS在1992年被Silicon Graphics收購了,在那一年Koblas發表了關於SOCKS的論文,SOCKS一舉成名。

SOCKS最廣泛使用的協議版本是4和5。SOCKS4是NEC的Ying-Da Lee發明的。因為SOCKS 4中並沒有關於安全方面的約定,但是對於現在的網絡來說,安全越來越重要,所以出現了SOCKS5,SOCKS5協議最初是一種使防火牆和其他安全產品更易於管理的安全協議。

SOCKS協議的具體內容

現在常用的SOCKS協議主要有SOCKS4、SOCKS4a和SOCKS5。本節將會詳細講訴他們的協議構成。

SOCKS4

先看一下SOCKS4的請求數據package長得什么樣子的:

含義 VER CMD DSTPORT DSTIP ID
字節個數 1 1 2 4 可變

VER 占用1個字節,表示的是SOCKS協議的版本號,對於SOCKS4來說,這個值是0x04。

CMD 占用1個字節,表示的是要執行命令的代碼,有兩個選擇,其中0x01 表示建立一個TCP/IP 流連接,0x02表示建立一個TCP/IP端口綁定。

DSTPORT 占用2個字節,表示目標端口號。

DESTIP 占用4個字節,表示的是IPv4地址。

ID 占用字節不定,表示的是用戶ID。

對於請求數據,相應的返回數據如下:

含義 VN REP DSTPORT DSTIP
字節個數 1 1 2 4

VN占用1個字節,表示是返回的消息的版本。

REP占用1個字節,表示返回的code:

字節 含義
0x5A 請求授權
0x5B 請求拒絕或者請求失敗
0x5C 因為請求不包含客戶端ID或者服務器端無法連接客戶端而失敗
0x5D 因為客戶端ID不匹配而失敗

DSTPORT占用兩個字節,表示目的地的端口,如果沒有綁定的話,則為空。

DSTIP占用4個字節,表示客戶端綁定的目的地的IP地址。

舉個例子,如果客戶端想使用SOCKS4從Fred連接到66.102.7.99:80,請求如下:

0x04 | 0x01 | 0x00 0x50 | 0x42 0x66 0x07 0x63 | 0x46 0x72 0x65 0x64 0x00

其中最后一個字段是Fred的ASCII編碼。

如果服務器端返回OK,則對應的響應如下:

0x00 | 0x5A | 0xXX 0xXX | 0xXX 0xXX 0xXX 0xXX

其中0xXX可以是任意值。

當連接建立完畢之后,所有的SOCKS客戶端到SOCKS服務器端的請求都會轉發到66.102.7.99。

SOCKS4a

因為SOCKS4只能指定目的服務器的IP地址,這對應服務器有多個IP的情況下會有很嚴重的限制。所以SOCK4a對SOCK4進行了擴展,可以支持目標服務器的域名。

SOCKS4a也是由SOCKS4的作者Ying-Da Lee,提出來的。我們看下SOCKS4a的請求格式:

含義 VER CMD DSTPORT DSTIP ID DOMAIN
字節個數 1 1 2 4 可變 variable

SOCKS4a是在SOCKS4的最后加入了domain。

DOMAIN表示的是要連接到的目標服務器的域名。使用null (0x00)來結尾。對應的DSTIP的前三個字節設置為NULL,最后一個字節設置成一個非0的值。

服務端的響應和SOCKS4是一樣的。

SOCKS5

雖然SOCKS5是SOCKS的最新版本,但是SOCKS5和SOCKS4是不兼容的。SOCKS5支持認證,並且提供了對IPv6和UDP的支持。其中UDP可以用來進行DNS lookups。它的交互流程如下所示:

  1. 客戶端和服務器端進行連接,並發送一個greeting消息,同時包含了支持的認證方法列表。

  2. 服務器端選擇一個支持的認證方法,如果都不支持,則發送失敗響應。

  3. 根據選中的認證方法,客戶端和服務器進行后續的認證交互,交互流程跟選中的認證方法相關。

  4. 客戶端以SOCKS4相似的方式發送連接請求。

  5. 服務器端發送和SOCKS4相似的響應。

我們看下greeting消息的格式:

含義 VER NAUTH AUTH
字節個數 1 1 可變字節

VER 占用1個字節表示SOCKS的版本號,這里是0x05。

NAUTH 占用1個字節,表示支持的認證方法的個數。

AUTH 是可變字節,表示的是支持的認證方法。一個字節表示一個方法,支持的方法如下:

    0x00: 沒有認證
    0x01: GSSAPI 
    0x02: 用戶名/密碼 (RFC 1929)
    0x03–0x7F: methods assigned by IANA
        0x03: Challenge-Handshake Authentication Protocol
        0x04: 未分配
        0x05: Challenge-Response Authentication Method
        0x06: Secure Sockets Layer
        0x07: NDS Authentication
        0x08: Multi-Authentication Framework
        0x09: JSON Parameter Block
        0x0A–0x7F: 未分配
    0x80–0xFE: 內部使用的保留方法

對應的服務器端的響應如下:

含義 VER CAUTH
字節個數 1 1

VER 占用1個字節,表示的是版本號。對於SOCKS5來說,它的值是0x05。

CAUTH 占用1個字節,表示選中的認證方法。如果沒有被選中,則設置為0xFF。

選好認證方法之后,接下來就是客戶端和服務器端的認證交互了,這里我們選擇最基本的用戶名和密碼0x02認證為例。

客戶端發送認證請求:

含義 VER IDLEN ID PWLEN PW
字節個數 1 1 (1-255) 1 (1-255)

VER 占用1個字節表示當前用戶名和密碼認證的版本。

IDLEN 占用1個字節,表示用戶名的長度。

ID 占用1到255個字節,表示用戶名。

PWLEN 占用1個字節,表示密碼的長度。

PW 就是密碼。

對應的服務器端的響應如下:

含義 VER STATUS
字節個數 1 1

VER 占用1個字節,表示版本號。

STATUS 占用1個字節,表示服務器的響應狀態。

接下來,客戶端就可以和服務器端發送建立連接消息了:

含義 VER CMD RSV DSTADDR DSTPORT
字節個數 1 1 1 可變字節 2

CMD 是連接可選的命令,0x01表示建立TCP/IP流連接,表示建立TCP/IP端口綁定,0x03表示連接一個UDP端口。

RSV 是保留字節,必須是0x00。

DSTADDR是SOCKS5的地址。地址的定義是這樣的:

含義 TYPE ADDR
字節個數 1 可變字節

TYPE 表示地址的類型,0x01是IPv4地址,0x03是域名,0x04是IPv6地址。

ADDR 表示的是地址,如果是IPv4,則使用4個字節,如果是域名,則第一個字節表示長度,后面字節表示域名。如果是IPv6地址,則使用16個字節。

對應的服務器端的響應如下:

含義 VER STATUS RSV BNDADDR BNDPORT
字節個數 1 1 1 可變字節 2

總結

以上就是SOCKS4和SOCKS5的詳細協議內容。注意,SOCKS一定要大寫!

本文已收錄於 http://www.flydean.com/09-socks/

最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM