網路協議之:一定要大寫的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。它的互動流程如下所示:
-
客戶端和伺服器端進行連線,併發送一個greeting訊息,同時包含了支援的認證方法列表。
-
伺服器端選擇一個支援的認證方法,如果都不支援,則傳送失敗響應。
-
根據選中的認證方法,客戶端和伺服器進行後續的認證互動,互動流程跟選中的認證方法相關。
-
客戶端以SOCKS4相似的方式傳送連線請求。
-
伺服器端傳送和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/
最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!