网络协议之:一定要大写的SOCKS
文章目錄
- 簡介
- SOCKS的故事
- SOCKS的歷史
- SOCKS協議的具體內容
- SOCKS4
- SOCKS4a
- SOCKS5
- 總結
簡介
很久很久以前,人們還穿的是草鞋,草鞋雖然穿著舒服,但是不夠美觀。然后人們就發現,用動物的皮也可以做成鞋,于是出現了皮鞋。但是皮鞋穿著磨腳,于是人們又發明了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長得什么樣子的:
| 字節個數 | 1 | 1 | 2 | 4 | 可變 |
VER 占用1個字節,表示的是SOCKS協議的版本號,對于SOCKS4來說,這個值是0x04。
CMD 占用1個字節,表示的是要執行命令的代碼,有兩個選擇,其中0x01 表示建立一個TCP/IP 流連接,0x02表示建立一個TCP/IP端口綁定。
DSTPORT 占用2個字節,表示目標端口號。
DESTIP 占用4個字節,表示的是IPv4地址。
ID 占用字節不定,表示的是用戶ID。
對于請求數據,相應的返回數據如下:
| 字節個數 | 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的請求格式:
| 字節個數 | 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消息的格式:
| 字節個數 | 1 | 1 | 可變字節 |
VER 占用1個字節表示SOCKS的版本號,這里是0x05。
NAUTH 占用1個字節,表示支持的認證方法的個數。
AUTH 是可變字節,表示的是支持的認證方法。一個字節表示一個方法,支持的方法如下:
0x00: 沒有認證0x01: GSSAPI 0x02: 用戶名/密碼 (RFC 1929)0x03–0x7F: methods assigned by IANA0x03: Challenge-Handshake Authentication Protocol0x04: 未分配0x05: Challenge-Response Authentication Method0x06: Secure Sockets Layer0x07: NDS Authentication0x08: Multi-Authentication Framework0x09: JSON Parameter Block0x0A–0x7F: 未分配0x80–0xFE: 內部使用的保留方法對應的服務器端的響應如下:
| 字節個數 | 1 | 1 |
VER 占用1個字節,表示的是版本號。對于SOCKS5來說,它的值是0x05。
CAUTH 占用1個字節,表示選中的認證方法。如果沒有被選中,則設置為0xFF。
選好認證方法之后,接下來就是客戶端和服務器端的認證交互了,這里我們選擇最基本的用戶名和密碼0x02認證為例。
客戶端發送認證請求:
| 字節個數 | 1 | 1 | (1-255) | 1 | (1-255) |
VER 占用1個字節表示當前用戶名和密碼認證的版本。
IDLEN 占用1個字節,表示用戶名的長度。
ID 占用1到255個字節,表示用戶名。
PWLEN 占用1個字節,表示密碼的長度。
PW 就是密碼。
對應的服務器端的響應如下:
| 字節個數 | 1 | 1 |
VER 占用1個字節,表示版本號。
STATUS 占用1個字節,表示服務器的響應狀態。
接下來,客戶端就可以和服務器端發送建立連接消息了:
| 字節個數 | 1 | 1 | 1 | 可變字節 | 2 |
CMD 是連接可選的命令,0x01表示建立TCP/IP流連接,表示建立TCP/IP端口綁定,0x03表示連接一個UDP端口。
RSV 是保留字節,必須是0x00。
DSTADDR是SOCKS5的地址。地址的定義是這樣的:
| 字節個數 | 1 | 可變字節 |
TYPE 表示地址的類型,0x01是IPv4地址,0x03是域名,0x04是IPv6地址。
ADDR 表示的是地址,如果是IPv4,則使用4個字節,如果是域名,則第一個字節表示長度,后面字節表示域名。如果是IPv6地址,則使用16個字節。
對應的服務器端的響應如下:
| 字節個數 | 1 | 1 | 1 | 可變字節 | 2 |
總結
以上就是SOCKS4和SOCKS5的詳細協議內容。注意,SOCKS一定要大寫!
本文已收錄于 http://www.flydean.com/09-socks/
最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的网络协议之:一定要大写的SOCKS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 听说版本会说话,你相信吗?
- 下一篇: URL URI傻傻分不清楚,dart告诉