SOCKSv5 協議的通信通常分為以下幾個主要階段:
- 方法協商階段 (Method Negotiation)
- 方法依賴的子協商階段 (Method-Dependent Sub-negotiation) - 本例為用戶名/密碼認證
- 請求發送階段 (Request Sending)
- 請求回復階段 (Request Reply)
- 數據傳輸階段 (Data Transfer)
場景設定回顧
- 客戶端 IP: 192.168.1.10
- SOCKS 服務器 IP: 10.0.0.1 (SOCKS 端口 1080)
- 目標服務器 IP: 203.0.113.5 (Web 服務器,端口 80)
- 認證憑據: 用戶名
myuser
,密碼mypass
階段一:方法協商 (Method Negotiation)
這是 SOCKSv5 會話的開始。客戶端與 SOCKS 服務器建立 TCP 連接后,首先會告訴服務器它支持哪些認證方法。服務器則會從中選擇一個并通知客戶端。
1.1 客戶端發送方法選擇報文 (Client Method Selection Message)
目的: 客戶端向 SOCKS 服務器聲明其支持的 SOCKS 版本和可用的認證方法列表。
報文格式:
+----+----------+----------+
|VER | NMETHODS | METHODS |
+----+----------+----------+
| 1 | 1 | 1 to 255 | (單位:字節)
+----+----------+----------+
-
VER (1 字節): SOCKS 協議版本。對于 SOCKSv5,此字段固定為
X'05'
(十進制 5)。 -
NMETHODS (1 字節):
METHODS
字段中包含的方法標識符八位字節的數量。范圍是 1 到 255。 -
METHODS (1 到 255 字節): 一個或多個方法標識符的列表,每個標識符占用一個字節。
X'00'
(0): 無需認證 (NO AUTHENTICATION REQUIRED)X'01'
(1): GSSAPIX'02'
(2): 用戶名/密碼 (USERNAME/PASSWORD)X'03'
到X'7F'
(3-127): IANA 分配的公共方法X'80'
到X'FE'
(128-254): 保留用于私有方法X'FF'
(255): 無可接受的方法 (NO ACCEPTABLE METHODS)
示例報文 (客戶端 -> SOCKS 服務器):
假設客戶端支持“無需認證”和“用戶名/密碼認證”。
十六進制: 05 02 00 02
報文內容解析:
05
: SOCKSv5。02
: 客戶端提供了 2 種認證方法。00
: 第一個方法,X'00'
(無需認證)。02
: 第二個方法,X'02'
(用戶名/密碼認證)。
1.2 SOCKS 服務器回復方法選擇報文 (Server Method Selection Message)
目的: SOCKS 服務器告知客戶端它將使用哪種認證方法。
報文格式:
+----+--------+
|VER | METHOD |
+----+--------+
| 1 | 1 | (單位:字節)
+----+--------+
- VER (1 字節): SOCKS 協議版本。固定為
X'05'
(十進制 5)。 - METHOD (1 字節): SOCKS 服務器從客戶端提供的列表中選擇的認證方法。如果服務器無法接受任何方法,則此字段為
X'FF'
(255),此時客戶端必須關閉連接。
示例報文 (SOCKS 服務器 -> 客戶端):
服務器選擇“用戶名/密碼認證”。
十六進制: 05 02
報文內容解析:
05
: SOCKSv5。02
: 服務器選擇了X'02'
(用戶名/密碼認證)。
階段二:方法依賴的子協商 (Method-Dependent Sub-negotiation) - 用戶名/密碼認證
由于服務器選擇了用戶名/密碼認證,客戶端和服務器將根據 RFC 1929 定義的用戶名/密碼認證子協議進行交互。
2.1 客戶端發送用戶名/密碼認證請求 (Username/Password Authentication Request)
目的: 客戶端向 SOCKS 服務器提交用于認證的用戶名和密碼。
報文格式:
+----+--------+----------+--------+----------+
|VER | ULEN | UNAME | PLEN | PASSWD |
+----+--------+----------+--------+----------+
| 1 | 1 | 1 to 255 | 1 | 1 to 255 | (單位:字節)
+----+--------+----------+--------+----------+
- VER (1 字節): 用戶名/密碼認證子協議的版本。目前固定為
X'01'
(十進制 1)。 - ULEN (1 字節):
UNAME
字段的長度(字節數)。 - UNAME (1 到 255 字節): 用戶名,可以是任何 ASCII 字符。
- PLEN (1 字節):
PASSWD
字段的長度(字節數)。 - PASSWD (1 到 255 字節): 密碼,可以是任何 ASCII 字符。
示例報文 (客戶端 -> SOCKS 服務器):
用戶名 myuser
(6 字節),密碼 mypass
(8 字節)。
十六進制: 01 06 6D 79 75 73 65 72 08 6D 79 70 61 73 73 77 64
報文內容解析:
01
: 用戶名/密碼認證子協議版本 1。06
: 用戶名長度為 6 字節。6D 79 75 73 65 72
:myuser
的 ASCII 碼。08
: 密碼長度為 8 字節。6D 79 70 61 73 73 77 64
:mypasswd
的 ASCII 碼。(這里假設密碼是’mypasswd’而非’mypass’以匹配提供的十六進制長度,即08對應8個字符)
2.2 SOCKS 服務器回復用戶名/密碼認證結果 (Username/Password Authentication Reply)
目的: SOCKS 服務器告知客戶端認證是否成功。
報文格式:
+----+--------+
|VER | STATUS |
+----+--------+
| 1 | 1 | (單位:字節)
+----+--------+
- VER (1 字節): 用戶名/密碼認證子協議的版本。固定為
X'01'
(十進制 1)。 - STATUS (1 字節): 認證狀態碼。
X'00'
(0): 認證成功。X'01'
(1): 認證失敗。
示例報文 (SOCKS 服務器 -> 客戶端):
認證成功。
十六進制: 01 00
報文內容解析:
01
: 用戶名/密碼認證子協議版本 1。00
: 狀態碼X'00'
表示認證成功。
階段三:請求發送 (Request Sending)
認證成功后,客戶端可以向 SOCKS 服務器發送實際的操作請求,例如建立連接、綁定端口或關聯 UDP。
3.1 客戶端發送 SOCKS 請求報文 (SOCKS Request Message)
目的: 客戶端請求 SOCKS 服務器執行特定操作(例如,建立到目標服務器的連接)。
報文格式:
+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 | (單位:字節)
+----+-----+-------+------+----------+----------+
- VER (1 字節): SOCKS 協議版本。固定為
X'05'
(十進制 5)。 - CMD (1 字節): 命令碼,表示客戶端請求的操作類型。
X'01'
(1): CONNECT (建立 TCP 連接)X'02'
(2): BIND (綁定端口,用于接受服務器發起的連接,如 FTP 的數據通道)X'03'
(3): UDP ASSOCIATE (關聯 UDP 中繼服務)
- RSV (1 字節): 保留字段,必須設置為
X'00'
(0)。 - ATYP (1 字節):
DST.ADDR
字段的地址類型。X'01'
(1): IPv4 地址,DST.ADDR
字段長度為 4 字節。X'03'
(3): 域名,DST.ADDR
字段的第一個字節表示域名長度,后續是域名本身。X'04'
(4): IPv6 地址,DST.ADDR
字段長度為 16 字節。
- DST.ADDR (可變長度): 目標地址。長度由
ATYP
字段決定。 - DST.PORT (2 字節): 目標端口號(網絡字節序,即大端序)。
示例報文 (客戶端 -> SOCKS 服務器):
請求連接到目標服務器 203.0.113.5
的端口 80
。
十六進制: 05 01 00 01 CB 00 71 05 00 50
報文內容解析:
05
: SOCKSv5。01
: 命令X'01'
,表示 CONNECT。00
: 保留字段。01
: 地址類型X'01'
,表示 IPv4 地址。CB 00 71 05
: 目標 IP 地址203.0.113.5
(203.0.113.5 的十六進制)。00 50
: 目標端口80
(80 的十六進制)。
階段四:請求回復 (Request Reply)
SOCKS 服務器處理客戶端的請求,并返回操作結果。
4.1 SOCKS 服務器回復請求結果 (SOCKS Reply Message)
目的: SOCKS 服務器告知客戶端其請求(如 CONNECT)的執行結果,并提供服務器綁定的地址和端口(僅在成功時有意義)。
報文格式:
+----+-----+-------+------+----------+----------+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 | (單位:字節)
+----+-----+-------+------+----------+----------+
- VER (1 字節): SOCKS 協議版本。固定為
X'05'
(十進制 5)。 - REP (1 字節): 回復碼,表示請求的結果。
X'00'
(0): 成功 (succeeded)X'01'
(1): 通用 SOCKS 服務器故障 (general SOCKS server failure)X'02'
(2): 規則集不允許連接 (connection not allowed by ruleset)X'03'
(3): 網絡不可達 (Network unreachable)X'04'
(4): 主機不可達 (Host unreachable)X'05'
(5): 連接被拒絕 (Connection refused)X'06'
(6): TTL 過期 (TTL expired)X'07'
(7): 命令不支持 (Command not supported)X'08'
(8): 地址類型不支持 (Address type not supported)X'09'
到X'FF'
(9-255): 未分配
- RSV (1 字節): 保留字段,必須設置為
X'00'
(0)。 - ATYP (1 字節):
BND.ADDR
字段的地址類型。與請求中的ATYP
定義相同。 - BND.ADDR (可變長度): SOCKS 服務器為客戶端綁定的地址。在 CONNECT 請求成功時,這是 SOCKS 服務器用于連接到目標主機的源 IP 地址。
- BND.PORT (2 字節): SOCKS 服務器為客戶端綁定的端口。在 CONNECT 請求成功時,這是 SOCKS 服務器用于連接到目標主機的源端口號(網絡字節序)。
示例報文 (SOCKS 服務器 -> 客戶端):
CONNECT 請求成功,SOCKS 服務器使用其 IP 10.0.0.1
和端口 49168
進行連接。
十六進制: 05 00 00 01 0A 00 00 01 C0 10
報文內容解析:
05
: SOCKSv5。00
: 回復碼X'00'
,表示成功。00
: 保留字段。01
: 綁定地址類型X'01'
,表示 IPv4 地址。0A 00 00 01
: 服務器綁定地址10.0.0.1
(SOCKS 服務器自身的 IP)。C0 10
: 服務器綁定端口49168
(C010 的十六進制值)。
階段五:數據傳輸 (Data Transfer)
如果 SOCKS 請求成功 (例如,CONNECT 成功),SOCKS 服務器和客戶端之間的 TCP 連接就建立成了代理通道。此后,客戶端發送到此連接的數據會被 SOCKS 服務器透明地轉發到目標服務器,反之亦然。
這一階段不再有 SOCKS 協議特定的報文頭,而是直接傳輸應用層數據。
5.1 客戶端發送應用數據
目的: 客戶端向目標服務器發送其應用層數據(例如,HTTP GET 請求)。
報文格式: 無 SOCKS 協議頭。直接是應用層協議數據。
示例報文 (客戶端 -> SOCKS 服務器 -> 目標 Web 服務器):
客戶端發送 HTTP GET 請求。
原始文本 (或其字節流表示):
GET / HTTP/1.1<CRLF>
Host: 203.0.113.5<CRLF>
Connection: close<CRLF>
<CRLF>
5.2 SOCKS 服務器轉發應用數據
目的: SOCKS 服務器將從目標服務器收到的應用層響應轉發給客戶端。
報文格式: 無 SOCKS 協議頭。直接是應用層協議數據。
示例報文 (目標 Web 服務器 -> SOCKS 服務器 -> 客戶端):
目標 Web 服務器回復 HTTP 響應。
原始文本 (或其字節流表示):
HTTP/1.1 200 OK<CRLF>
Content-Type: text/html<CRLF>
Content-Length: 1234<CRLF>
<CRLF>
<html>...網頁內容...</html>
至此,一個完整的 SOCKSv5 代理通信過程就完成了。理解這些詳細的報文格式有助于調試和實現 SOCKSv5 客戶端或服務器。