SOCKS

SOCKS 是一種網路傳輸協議，名字取自 SOCKetS，主要用於客戶端與外網伺服器之間通訊的中間傳遞。

當防火牆後的客戶端要訪問外部的伺服器時，就跟 SOCKS 代理伺服器連線。這個代理伺服器控制客戶端訪問外網的資格，允許的話，就將客戶端的請求發往外部的伺服器。

這個協議最初由 David Koblas 開發，而後由 NEC 的 Ying-Da Lee 將其擴充套件到 SOCKS4。最新協議是 SOCKS5，與前一版本相比，增加支援 UDP、驗證，以及 IPv6。

根據 OSI 模型，SOCKS 是會話層的協議，位於表示層與傳輸層之間。

SOCKS 協定不提供加密。

與 HTTP 代理的對比

SOCKS 工作在比 HTTP 代理更低的層次：SOCKS 使用握手協議來通知代理軟體其客戶端試圖進行的 SOCKS 連線，然後儘可能透明地進行操作，而常規代理可能會解釋和重寫報頭（例如，使用另一種底層協議，例如 FTP；然而，HTTP 代理只是將 HTTP 請求轉發到所需的 HTTP 伺服器）。雖然 HTTP 代理有不同的使用模式，HTTP CONNECT 方法允許轉發 TCP 連線；然而，SOCKS 代理還可以轉發 UDP 流量（僅 SOCKS5），而 HTTP 代理不能。HTTP 代理通常更瞭解 HTTP 協議，執行更高層次的過濾（雖然通常只用於 GET 和 POST 方法，而不用於 CONNECT 方法）。

版本分支

2.1 SOCKS 4

下面是客戶端向 SOCKS 4 代理伺服器，傳送的連線請求包的格式（以位元組為單位）：

VN 是 SOCK 版本，應該是 4；
CD 是 SOCK 的命令碼，1 表示 CONNECT 請求，2 表示 BIND 請求；
DSTPORT 表示目的主機的埠；
DSTIP 指目的主機的 IP 地址；
USERID 表示使用者標識 ID，結尾值為 0（NULL）；

代理伺服器而後傳送回應包（以位元組為單位）：

VN 是回應碼的版本，應該是 0；
CD 是代理伺服器答覆，有幾種可能：
90，請求得到允許；
91，請求被拒絕或失敗；
92，由於 SOCKS 伺服器無法連線到客戶端的 identd（一個驗證身份的程序），請求被拒絕；
93，由於客戶端程式與 identd 報告的使用者身份不同，連線被拒絕。
DSTPORT 與 DSTIP 與請求包中的內容相同，但被忽略。

如果請求被拒絕，SOCKS 伺服器馬上與客戶端斷開連線；如果請求被允許，代理伺服器就充當客戶端與目的主機之間進行雙向傳遞，對客戶端而言，就如同直接在與目的主機相連。

2.2 SOCKS4a

SOCKS 4A 是 SOCKS 4 協議的簡單擴充套件，允許客戶端對無法解析域名的目的主機進行存取。

客戶端對 DSTIP 的頭三個位元組設定為 NULL，最後一個位元組為非零；對應的 IP 地址就是 0.0.0.x，其中 x 是非零，這當然不可能是目的主機的地址，這樣即使客戶端可以解析域名，對此也不會發生衝突。USERID 以緊跟的 1 位元組的 0（NULL）作結尾，客戶端必須傳送目的主機的域名，並以另一個 1 位元組的 0（NULL）作結尾。CONNECT 和 BIND 請求的時候，都要按照這種格式（以位元組為單位）：

使用 4a 協議的伺服器必須檢查請求包裡的 DSTIP 欄位，如果表示地址 0.0.0.x，x 是非零結尾，那麼伺服器就得讀取客戶端所發包中的域名欄位，然後伺服器就得解析這個域名，可以的話，對目的主機進行連線。

2.3 SOCKS5

SOCKS5 比 SOCKS4a 多了驗證、IPv6、UDP 支援。建立與 SOCKS5 伺服器的 TCP 連線後客戶端需要先發送請求來確認協議版本及認證方式，格式為（以位元組為單位）：

VER 是 SOCKS 版本，這裡應該是 0x05；
NMETHODS 是 METHODS 部分的長度；
METHODS 是客戶端支援的認證方式列表，每個方法佔 1 位元組。當前的定義是：
0x00 不需要認證
0x01
0x02 使用者名稱、密碼認證
0x03 - 0x7F 由 IANA 分配（保留）
0x03：握手挑戰認證協議
0x04：未分派
0x05：響應挑戰認證方法
0x06：傳輸層安全
0x07：NDS 認證
0x08：多認證框架
0x09：JSON 引數塊
0x0A–0x7F：未分派
0x80 - 0xFE 為私人方法保留
0xFF 無可接受的方法

伺服器從客戶端提供的方法中選擇一個並透過以下訊息通知客戶端（以位元組為單位）：

VER 是 SOCKS 版本，這裡應該是 0x05；
METHOD 是服務端選中的方法。如果返回 0xFF 表示沒有一個認證方法被選中，客戶端需要關閉連線。

之後客戶端和服務端根據選定的認證方式執行對應的認證。

認證結束後客戶端就可以傳送請求資訊。如果認證方法有特殊封裝要求，請求必須按照方法所定義的方式進行封裝。

SOCKS5 請求格式（以位元組為單位）：

VER 是 SOCKS 版本，這裡應該是 0x05；
CMD 是 SOCK 的命令碼：
0x01 表示 CONNECT 請求
0x02 表示 BIND 請求
0x03 表示 UDP 轉發
RSV 為保留欄位，值為 0x00；
ATYP 為 DST.ADDR 型別：
0x01 IPv4 地址，DST.ADDR 部分 4 位元組長度
0x03 域名，DST.ADDR 部分的第一個位元組為域名長度，DST.ADDR 剩餘的內容為域名，沒有 \0 結尾。
0x04 IPv6 地址，16 個位元組長度。
DST.ADDR 為目的地址；
DST.PORT 為網路位元組序表示的目的埠。

伺服器按以下格式回應客戶端的請求（以位元組為單位）：

VER 是 SOCKS 版本，這裡應該是 0x05；
REP 為應答欄位：
0x00 表示成功；
0x01 為普通的 SOCKS 伺服器連線失敗
0x02 為現有規則不允許連線
0x03 為網路不可達
0x04 為主機不可達
0x05 為連線被拒
0x06 為 TTL 超時
0x07 為不支援的命令
0x08 為不支援的地址型別
0x09 - 0xFF 未定義
RSV 為保留欄位，值為 0x00；
ATYP 為 BND.ADDR 型別：
0x01 IPv4 地址，DST.ADDR 部分 4 位元組長度
0x03 域名，DST.ADDR 部分第一個位元組為域名長度，DST.ADDR 剩餘的內容為域名，沒有 \0 結尾。
0x04 IPv6 地址，16 個位元組長度。
BND.ADDR 為伺服器繫結的地址
BND.PORT 為網路位元組序表示的伺服器繫結的埠

2.3.1 SOCKS5 使用者名稱密碼認證方式

在客戶端、服務端協商使用使用者名稱密碼認證後，客戶端發出使用者名稱密碼，格式為（以位元組為單位）：

鑑定協議版本目前為 0x01 。

伺服器鑑定後發出如下回應：

其中鑑定狀態 0x00 表示成功，0x01 表示失敗。

SOCKS 伺服器

部分 SOCKS 伺服器軟體：

Dante Socks Server，http://www.inet.no/dante
Java Socks Server，http://jsocks.sourceforge.net
Socks4 Server，https://archive.today/20130502024508/http://www.alhem.net/project/socks4
SS5 Socks Server，http://ss5.sourceforge.net
TcpToute2，https://github.com/GameXG/TcpRoute2
CCProxy，https://www.youngzsoft.net/ccproxy/

SOCKS 客戶端

一般情況下應用程式會內嵌對 SOCKS 協議的支援。但 socksify，proxifier 軟體可強制使不支援 SOCKS 的應用透過代理聯網。