本文由TZWSOHO通過收集網絡資料整理而成(百度百科和英文維基百科),文中某些地方可能由于筆者本人技術水準有限而造成翻譯上甚至是個人了解上的錯漏,歡迎路過本文的各路英雄斧正。另若有需要轉載時請高擡貴手标明出處,萬分感謝!
SOCKS v5的原理與SOCKS v4/v4a的原理大緻相同,但增加了對UDP協定的支援、安全驗證機制及IPv6的支援。用戶端通過SOCKS v5代理伺服器與外部建立連接配接的流程如下:
1、 用戶端嘗試連接配接代理伺服器;
2、 用戶端選擇一種認證的方法,并發送認證資訊的方法代碼至代理伺服器;
3、 若代理伺服器不接受此認證方法,則拒絕用戶端的請求;
4、 若代理伺服器接受了此認證方法,則用戶端可根據方法的規定與代理伺服器進行一些資訊通訊,如發送使用者名及密碼等;
5、 認證成功後,用戶端将發送一個類似于SOCKS v4的請求資料包給代理伺服器;
6、 代理伺服器發送一個類似于SOCKS v4規定的回複資料包給用戶端;
7、 若以上操作均成功進行,則此時用戶端可以與目标主機通過代理伺服器進行互相通訊。
用戶端認證請求資料包格式
字段名 | VER | NMETHODS | 認證方式1 | …… | 認證方式n |
字段值 | 5 | 認證方式數目n | 0-254 | 0-254 | 0-254 |
字段大小 (位元組) | 1 | 1 | 1 | 1 | 1 |
代理伺服器應答認證資料包格式
字段名 | VER | 代理接受的認證方式 |
字段值 | 5 | 0-254(或傳回255代表不支援此認證方式) |
字段大小(位元組) | 1 | 1 |
已定義的認證方式代号:
0x00:無驗證
0x01:通過GSSAPI驗證
0x02:通過正常的“使用者名/密碼”對驗證
0x03-0x7F:通過IANA(網際網路位址編碼配置設定機構Internet Assigned Numbers Authority)進行驗證
0x80-0xFE:可以由使用者自行定義
0xFF:不接受的認證方式
其中目前的GSSAPI認證方法一般有以下幾種:Kerberos,NTLM,Distributed Computing Environment (DCE),SESAME,SPKM,LIPKEY。
“使用者名/密碼”對認證資料包格式
字段名 | VER | ULEN | USERNAME | PLEN | PASSWD |
字段值 | 1 | 使用者名長度 | 使用者名 | 密碼長度 | 密碼 |
字段大小 (位元組) | 1 | 1 | 可變 | 1 | 可變 |
代理伺服器應答“使用者名/密碼”對認證資料包格式
字段名 | VER | STATUS |
字段值 | 1 | 0 - 成功 非零 - 失敗 |
字段大小(位元組) | 1 | 1 |
注意:若認證失敗,則代理伺服器應馬上關閉與用戶端的連接配接。
認證成功後,用戶端可向代理伺服器發送連接配接請求,格式大緻與v4版一樣,但v5版增加了UDP和IPv6的支援,并且支援域名解析。
用戶端“CONNECT/BIND/UDP關聯”請求資料包格式
字段名 | VER | CMD | RSV | ATYP | DSTADDR | DSTPORT |
字段值 | 5 | 1 - CONNECT 2 - BIND 3 - UDP關聯 | 0(保留) | 1 - IPv4 3 - 域名 4 - IPv6 | IP/域名 | 通訊端口 |
字段大小(位元組) | 1 | 1 | 1 | 1 | 可變 | 2 |
注意:若DSTADDR為域名,則該字段的第一位元組代表域名名稱的長度,域名名稱最後無NULL作為終止符。
代理伺服器應答請求資料包格式
字段名 | VER | REP | RSV | ATYP | BNDADDR | BNDPORT |
字段值 | 5 | 應答代号 | 0(保留) | 1 - IPv4 3 - 域名 4 - IPv6 | 綁定的 位址 | 綁定的 端口 |
字段大小(位元組) | 1 | 1 | 1 | 1 | 可變 | 2 |
其中REP字段的值及其表示意義如下(注:RFC英文原文及本人翻譯):
0x00: succeeded 成功
0x01: general SOCKS server failure 正常SOCKS伺服器失敗
0x02: connection not allowed by ruleset 規則集不允許此連接配接
0x03: Network unreachable 網絡不可達
0x04: Host unreachable 主機不可達
0x05: Connection refused 連接配接被拒絕
0x06: TTL expired TTL期限已失效
0x07: Command not supported 指令不支援
0x08: Address type not supported 位址類型不支援
0x09 - 0xFF unassigned 未定義
1、 CONNECT
在對一個CONNECT指令的應答中,BND.PORT包含了伺服器配置設定的用來連到目标機的端口号,BND.ADDR則是相應的IP位址。由于SOCKS伺服器通常有多個IP,應答中的BND.ADDR常和用戶端連到SOCKS伺服器的那個IP不同。
SOCKS伺服器可以利用DST.ADDR和DST.PORT,以及用戶端源位址和端口來對一個CONNECT請求進行分析。
2、 BIND
BIND請求通常被用在那些要求用戶端接受來自伺服器的連接配接的協定上。FTP是一個典型的例子。它建立一個從用戶端到伺服器端的連接配接來執行指令以及接收狀态的報告,而使用另一個從伺服器到用戶端的連接配接來接收傳輸資料的要求(如LS,GET,PUT)。
建議隻有在一個應用協定的用戶端在使用CONNECT指令建立主連接配接後才可以使用BIND指令建立第二個連接配接。建議SOCKS伺服器使用DST.ADDR和DST.PORT來評價BIND請求。
在一個BIND請求的操作過程中,SOCKS伺服器要發送兩個應答給用戶端。當伺服器建立并綁定一個新的套接口時發送第一個應答。BND.PORT字段包含SOCKS伺服器用來監聽進入的連接配接的端口号,BAND.ADDR字段包含了對應的IP位址。用戶端通常使用這些資訊來告訴(通過主連接配接或控制連接配接)應用伺服器連接配接的彙接點。第二個應答僅發生在所期望到來的連接配接成功或失敗之後。在第二個應答中,BND.PORT和BND.ADDR字段包含了連上來的主機的IP位址和端口号。
3、 UDP關聯
UDP 關聯請求通常是要求建立一個UDP轉發程序來控制到來的UDP資料報。DST.ADDR和DST.PORT字段包含用戶端所希望的用來發送UDP資料報的IP位址和端口号。伺服器可以使用這個資訊來限制進入的連接配接。如果用戶端在發送這個請求時沒有位址和端口資訊,用戶端必須用全0來填充。
當與UDP相應的TCP連接配接中斷時,該UDP連接配接也必須中斷。
應答UDP 關聯請求時,BND.PORT和BND.ADDR字段指明了客戶發送UDP消息至伺服器的端口和位址。
4、 應答處理
當一個應答(REP值不等于00)指明出錯時,SOCKS伺服器必須在發送完應答消息後一小段時間内終止TCP連接配接。這段時間應該在發現錯誤後少于10秒。
如果一個應答(REP值等于00)指明成功,并且請求是一個BIND或CONNECT時,用戶端就可以開始發送資料了。如果協商的認證方法中有以完整性、認證和/或安全性為目的的封裝,這些請求必須按照該方法所定義的方式進行封裝。類似的,當以客戶機為目的地的資料到達SOCKS伺服器時,SOCKS伺服器必須用正在使用的方法對這些資料進行封裝。