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方法）。

**版本分支**

**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服務器馬上與客戶端斷開連接；如果請求被允許，代理服務器就充當客戶端與目的主機之間進行雙向傳遞，對客戶端而言，就如同直接在與目的主機相連。

**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是非零結尾，那麼服務器就得讀取客戶端所發包中的域名字段，然後服務器就得解析這個域名，可以的話，對目的主機進行連接。

**SOCKS5**
SOCKS5比SOCKS4a多了驗證、IPv6、UDP支持。建立與SOCKS5服務器的TCP連接後客戶端需要先發送請求來確認協議版本及認證方式，格式為（以字節為單位）：- VER是SOCKS版本，這裡應該是0x05；- NMETHODS是METHODS部分的長度；- METHODS是客戶端支持的認證方式列表，每個方法佔1字節。當前的定義是：- 0x00  不需要認證- 0x01  GSSAPI- 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為網絡字節序表示的服務器綁定的端口

**SOCKS5 用戶名密碼認證方式**
在客戶端、服務端協商使用用戶名密碼認證後，客戶端發出用戶名密碼，格式為（以字節為單位）：
鑑定協議版本目前為 0x01 。
服務器鑑定後發出如下回應：
其中鑑定狀態 0x00 表示成功，0x01 表示失敗。

**SOCKS服務器**
部分SOCKS服務器軟件：- Dante Socks Server，http://www.inet.no/dante date=20051107205113 - Java Socks Server，http://jsocks.sourceforge.net date=20051027171703 - Socks4 Server，https://archive.today/20130502024508/ http://www.alhem.net/project/socks4 date=2013-05-02  - SS5 Socks Server，http://ss5.sourceforge.net date=20190804205828 - TcpToute2，https://github.com/GameXG/TcpRoute2 date=20170315042123 - CCProxy，https://www.youngzsoft.net/ccproxy/ date=20220424120927 

**SOCKS客戶端**
一般情況下應用程序會內嵌對SOCKS協議的支持。但socksify，proxifier軟件可強制使不支持SOCKS的應用通過代理聯網。

**註釋**

**參考文獻**

**參見**
SocksCap
*Shadowsocks

**外部鏈接**
 RFC 3089 - A SOCKS-based IPv6/IPv4 Gateway Mechanism- RFC 1961 - GSS-API Authentication Method for SOCKS Version 5 - RFC 1929 - Username/Password Authentication for SOCKS V5- RFC 1928 - SOCKS Protocol Version 5- Ying-Da Lee， SOCKS 4A: A Simple Extension to SOCKS 4 Protocol（SOCKS 4A：SOCKS 4協議的一個簡單擴展）- Michel Arboi， Vulnerability - Too long hostname kills the SOCKS4A serverdate=20070927000935 （易受攻擊性：域名過長導致SOCKS4A服務器死機）-  SOCKS: A protocol for TCP proxy across firewalls, SOCKS Protocol Version 4 (NEC)date=20131210021655  SOCKS:一個用於穿越防火牆的TCP代理協議，SOCKS協議版本4（NEC）