除了這個意譯版rfc1928外,其他人寫的好像也有錯誤,都是一知半解。
☆ RFC 1928意譯版(非直譯版)
http://www.ietf.org/rfc/rfc1928.txt
http://www.sczgroup.org/network/200503311423.txt
SOCKS協議位於傳輸層(TCP/UDP等)與應用層之間,因而顯然地位於網絡層(IP)之上。
諸如IP層報文轉發、ICMP協議等等都因太低層而與SOCKS協議無關。
SOCKS 4不支持認證、UDP協議以及遠程解析FQDN。SOCKS 5支持。
SOCKS Server缺省偵聽在1080/TCP口。這是SOCKS Client連接到SOCKS Server之後發
送的第一個報文:
+----+----------+----------+
|VER | NMETHODS | METHODS |
+----+----------+----------+
| 1 | 1 | 1 to 255 |
+----+----------+----------+
對於SOCKS 5,VER字段爲0x05,版本4對應0x04。NMETHODS字段指定METHODS域的字節
數。不知NMETHODS可以爲0否,看上圖所示,可取值[1,255]。METHODS字段有多少字
節(假設不重複),就意味着SOCKS Client支持多少種認證機制。
SOCKS Server從METHODS字段中選中一個字節(一種認證機制),並向SOCKS Client發
送響應報文:
+----+--------+
|VER | METHOD |
+----+--------+
| 1 | 1 |
+----+--------+
目前可用METHOD值有:
0x00 NO AUTHENTICATION REQUIRED(無需認證)
0x01 GSSAPI
0x02 USERNAME/PASSWORD(用戶名/口令認證機制)
0x03-0x7F IANA ASSIGNED
0x80-0xFE RESERVED FOR PRIVATE METHODS(私有認證機制)
0xFF NO ACCEPTABLE METHODS(完全不兼容)
如果SOCKS Server響應以0xFF,表示SOCKS Server與SOCKS Client完全不兼容,
SOCKS Client必須關閉TCP連接。認證機制協商完成後,SOCKS Client與
SOCKS Server進行認證機制相關的子協商,參看其它文檔。爲保持最廣泛兼容性,
SOCKS Client、SOCKS Server必須支持0x01,同時應該支持0x02。
認證機制相關的子協商完成後,SOCKS Client提交轉發請求:
+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
VER 對於版本5這裏是0x05
CMD 可取如下值:
0x01 CONNECT
0x02 BIND
0x03 UDP ASSOCIATE
RSV 保留字段,必須爲0x00
ATYP 用於指明DST.ADDR域的類型,可取如下值:
0x01 IPv4地址
0x03 FQDN(全稱域名)
0x04 IPv6地址
DST.ADDR CMD相關的地址信息,不要爲DST所迷惑
如果是IPv4地址,這裏是big-endian序的4字節數據
如果是FQDN,比如"www.nsfocus.net",這裏將是:
0F 77 77 77 2E 6E 73 66 6F 63 75 73 2E 6E 65 74
注意,沒有結尾的NUL字符,非ASCIZ串,第一字節是長度域
如果是IPv6地址,這裏是16字節數據。
DST.PORT CMD相關的端口信息,big-endian序的2字節數據
SOCKS Server評估來自SOCKS Client的轉發請求併發送響應報文:
+----+-----+-------+------+----------+----------+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
VER 對於版本5這裏是0x05
REP 可取如下值:
0x00 成功
0x01 一般性失敗
0x02 規則不允許轉發
0x03 網絡不可達
0x04 主機不可達
0x05 連接拒絕
0x06 TTL超時
0x07 不支持請求包中的CMD
0x08 不支持請求包中的ATYP
0x09-0xFF unassigned
RSV 保留字段,必須爲0x00
ATYP 用於指明BND.ADDR域的類型
BND.ADDR CMD相關的地址信息,不要爲BND所迷惑
BND.PORT CMD相關的端口信息,big-endian序的2字節數據
1) CONNECT命令
假設CMD爲CONNECT,SOCKS Client、SOCKS Server之間通信的相關四元組是:
SOCKSCLIENT.ADDR,SOCKSCLIENT.PORT,SOCKSSERVER.ADDR,SOCKSSERVER.PORT
一般SOCKSSERVER.PORT是1080/TCP。
CONNECT請求包中的DST.ADDR/DST.PORT指明轉發目的地。SOCKS Server可以靠
DST.ADDR、DST.PORT、SOCKSCLIENT.ADDR、SOCKSCLIENT.PORT進行評估,以決定建立
到轉發目的地的TCP連接還是拒絕轉發。
假設規則允許轉發並且成功建立到轉發目的地的TCP連接,相關四元組是:
BND.ADDR,BND.PORT,DST.ADDR,DST.PORT
此時SOCKS Server向SOCKS Client發送的CONNECT響應包中將指明BND.ADDR/BND.PORT。
注意,BND.ADDR可能不同於SOCKSSERVER.ADDR,SOCKS Server所在主機可能是多目(
multi-homed)主機。
假設拒絕轉發或未能成功建立到轉發目的地的TCP連接,CONNECT響應包中REP字段將
指明具體原因。
響應包中REP非零時表示失敗,SOCKS Server必須在發送響應包後不久(不超過10s)關
閉與SOCKS Client之間的TCP連接。
響應包中REP爲零時表示成功。之後SOCKS Client直接在當前TCP連接上發送待轉發數
據。
2) BIND命令
假設CMD爲BIND。這多用於FTP協議,FTP協議在某些情況下要求FTP Server主動建立
到FTP Client的連接,即FTP數據流。
FTP Client - SOCKS Client - SOCKS Server - FTP Server
a. FTP Client試圖建立FTP控制流。SOCKS Client向SOCKS Server發送CONNECT請求,
後者響應請求,最終FTP控制流建立。
CONNECT請求包中指明FTPSERVER.ADDR/FTPSERVER.PORT。
b. FTP Client試圖建立FTP數據流。SOCKS Client建立新的到SOCKS Server的TCP連
接,並在新的TCP連接上發送BIND請求。
BIND請求包中仍然指明FTPSERVER.ADDR/FTPSERVER.PORT。SOCKS Server應該據此
進行評估。
SOCKS Server收到BIND請求,創建新套接字,偵聽在AddrA/PortA上,並向SOCKS
Client發送第一個BIND響應包,包中BND.ADDR/BND.PORT即AddrA/PortA。
c. SOCKS Client收到第一個BIND響應包。FTP Client通過FTP控制流向FTP Server發
送PORT命令,通知FTP Server應該主動建立到AddrA/PortA的TCP連接。
d. FTP Server收到PORT命令,主動建立到AddrA/PortA的TCP連接,假設TCP連接相關
四元組是:
AddrB,PortB,AddrA,PortA
e. SOCKS Server收到來自FTP Server的TCP連接請求,向SOCKS Client發送第二個
BIND響應包,包中BND.ADDR/BND.PORT即AddrB/PortB。然後SOCKS Server開始轉
發FTP數據流。
下面是一些討論記錄:
scz
爲什麼需要發送第二個BIND響應包,指明AddrB/PortB的意義何在。
knightmare@apue
指明AddrB/PortB的意義在於,FTP Client出於安全考慮,會檢查FTP數據流的源IP、
源端口,比如FTP數據流的源端只允許是FTPSERVER.ADDR/20。
scz
knightmare的答案是正確的,但我的疑惑可能源於我對SOCKS協議的錯誤理解,以至
提出一個產生歧義的問題。事實上應該查看David Koblas的原始文檔以理解BIND請求
的全過程。前面關於FTP數據流的描述部分已做了修正,因此看不出提問的緣由了。
3) UDP ASSOCIATE命令
假設CMD爲UDP ASSOCIATE。此時DST.ADDR與DST.PORT指明發送UDP報文時的源IP、源
端口,而不是UDP轉發目的地,SOCKS Server可以據此進行評估以決定是否進行UDP轉
發。如果SOCKS Client發送UDP ASSOCIATE命令時無法提供DST.ADDR與DST.PORT,則
必須將這兩個域置零。
下面是一些討論記錄:
scz
什麼情況下SOCKS Client發送UDP ASSOCIATE命令,又無法提供DST.ADDR與DST.PORT,
或者說出於什麼考慮才需要刻意將這兩個域置零。有現實例子存在嗎。
[email protected]
考慮這種情況:
Application Client - SOCKS Client - NAT - SOCKS Server - Application Server
SOCKS Client在UDP ASSOCIATE命令中指明DST.ADDR/DST.PORT,SOCKS Server靠這些
信息決定是否轉發某個UDP報文。上圖中SOCKS Client與SOCKS Server之間有NAT,前
者無法預知UDP報文經過NAT後源IP、源端口會變成什麼樣,但肯定會變,因此前者無
法提前在UDP ASSOCIATE命令中指明DST.ADDR/DST.PORT,如果強行指定非零值,後者
會檢測到待轉發UDP報文的源IP、源端口與DST.ADDR/DST.PORT不匹配而拒絕轉發。針
對這種情況,RFC 1928建議SOCKS Client將DST.ADDR/DST.PORT置零,SOCKS Server
此時不再檢查待轉發UDP報文的源IP、源端口。
在一條TCP連接上SOCKS Client向SOCKS Server發送了UDP ASSOCIATE命令,後續UDP
轉發要求此TCP連接繼續維持,此TCP連接關閉時相應的UDP轉發也將中止。換句話說,
UDP轉發必然伴隨着一個TCP連接,這將消耗額外的資源。
SOCKS Server向SOCKS Client發送UDP ASSOCIATE響應包,BND.ADDR/BND.PORT指明
SOCKS Client應向哪裏發送待轉發UDP報文。
對於UDP轉發,SOCKS Client發送出去的UDP數據區如下:
+----+------+------+----------+----------+----------+
|RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
+----+------+------+----------+----------+----------+
| 2 | 1 | 1 | Variable | 2 | Variable |
+----+------+------+----------+----------+----------+
RSV 保留字段,必須爲0x0000
FRAG Current fragment number
0x00 這是一個非碎片的SOCKS UDP報文
0x01-0x7F SOCKS碎片序號
0x80-0xFF 最高位置1表示碎片序列結束,即這是最後一個SOCKS碎片
ATYP 用於指明DST.ADDR域的類型,可取如下值:
0x01 IPv4地址
0x03 FQDN(全稱域名)
0x04 IPv6地址
DST.ADDR 轉發目標地址
DST.PORT 轉發目標端口
DATA 原始UDP數據區
SOCKS Server靜靜地爲SOCKS Client進行UDP轉發,並不通知後者轉發完成還是被拒
絕。
FRAG用於支持SOCKS碎片。SOCKS碎片接收方一般實現有重組隊列與重組定時器。假設
重組定時器超時或者低序SOCKS碎片後於高序SOCKS碎片到達重組隊列,此時必須重置
重組隊列。重組定時器不得小於5秒。應該儘可能地避免出現SOCKS碎片。
是否支持SOCKS碎片是可選的,如果一個SOCKS實現不支持SOCKS碎片,則必須丟棄所
有接收到的SOCKS碎片,即那些FRAG字段非零的SOCKS UDP報文。
由於SOCKS實現在支持UDP轉發時會在原始UDP數據區前增加一個SOCKS協議相關的頭,
因此爲UDP數據區分配空間時要爲這個頭留足空間:
ATYP 頭佔用字節 原因
0x01 10 IPv4地址佔4字節,4+6=10
0x03 262 長度域是一個字節,因此最大0xFF,1+255+6=262
0x04 20 這裏我懷疑是筆誤,IPv6地址佔16字節,16+6=22
我懷疑RFC 1928這裏有筆誤,寫信詢問[email protected]、[email protected]去了。
SOCKS 4A是SOCKS 4協議的簡單擴展,允許客戶端對無法解析的目的主機,進行自行規定。
客戶端對DSTIP的頭三個字節設定爲NULL,最後一個字節爲非零;對應的IP地址就是0.0.0.x,其中x是非零,這當然不可能是目的主機的地址,這樣即使客戶端可以解析域名,對此也不會發生衝突。USERID以緊跟的NULL字節作結尾,客戶端必須發送目的主機的域名,並以另一個NULL字節作結尾。CONNECT和BIND請求的時候,都要按照這種格式(以字節爲單位):
+----+----+----+----+----+----+----+----+----+----+....+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP 0.0.0.x | USERID |NULL| HOSTNAME |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+----+----+....+----+
1 1 2 4 variable 1 variable 1
使用4a協議的服務器必須檢查請求包裏的DSTIP字段,如果表示地址0.0.0.x,x是非零結尾,那麼服務器就得讀取客戶端所發包中的域名字段,然後服務器就得解析這個域名,可以的話,對目的主機進行連接。
SOCKS協議最初由David Koblas設計,後經Ying-Da Lee改進成SOCKS 4協議。
SOCKS4協議主要是如下幾個RFC
http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol
http://www.rfc-editor.org/rfc/rfc1928.txt
http://www.smartftp.com/Products/SmartFTP/RFC/socks4a.protocol
SOCKS 4只支持TCP轉發。
請求報文格式如下:
+----+----+----+----+----+----+----+----+----+----+...+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+...+----+
1 1 2 4 variable 1
VN SOCKS協議版本號,應該是0x04
CD SOCKS命令,可取如下值:
0x01 CONNECT
0x02 BIND
DSTPORT CD相關的端口信息
DSTIP CD相關的地址信息
USERID 客戶方的USERID
NULL 0x00
響應報文格式如下:
+----+----+----+----+----+----+----+----+
| VN | CD | DSTPORT | DSTIP |
+----+----+----+----+----+----+----+----+
1 1 2 4
VN 應該爲0x00而不是0x04
CD 可取如下值:
0x5A 允許轉發
0x5B 拒絕轉發,一般性失敗
0x5C 拒絕轉發,SOCKS 4 Server無法連接到SOCS 4 Client所在主機的
IDENT服務
0x5D 拒絕轉發,請求報文中的USERID與IDENT服務返回值不相符
DSTPORT CD相關的端口信息
DSTIP CD相關的地址信息
1) CONNECT命令
對於CONNECT請求,DSTIP/DSTPORT指明轉發目的地。
SOCKS 4 Server根據源IP、DSTPORT、DSTIP、USERID以及可從SOCS 4 Client所在主
機的IDENT服務(RFC 1413)獲取的信息進行綜合評估,以決定建立相應連接還是拒絕
轉發。
假設CONNECT請求被允許,SOCKS 4 Server試圖建立到轉發目的地的TCP連接,然後向
SOCKS 4 Client發送響應報文,指明是否成功建立轉發連接。
如果CONNECT請求被拒絕,SOCKS 4 Server也向SOCKS 4 Client發送響應報文,隨後
立即關閉連接。
CONNECT響應包中只有VN、CD字段有意義,DSTPORT、DSTIP字段被忽略。如果CD等於
0x5A,表示成功建立轉發連接,之後SOCKS 4 Client直接在當前TCP連接上發送待轉
發數據。
2) BIND命令
FTP協議在某些情況下要求FTP Server主動建立到FTP Client的連接,即FTP數據流。
FTP Client - SOCKS 4 Client - SOCKS 4 Server - FTP Server
a. FTP Client試圖建立FTP控制流。SOCKS 4 Client向SOCKS 4 Server發送CONNECT
請求,後者響應請求,最終FTP控制流建立。
CONNECT請求包中指明FTPSERVER.ADDR/FTPSERVER.PORT。
b. FTP Client試圖建立FTP數據流。SOCKS 4 Client建立新的到SOCKS 4 Server的
TCP連接,並在新的TCP連接上發送BIND請求。
BIND請求包中仍然指明FTPSERVER.ADDR/FTPSERVER.PORT。
SOCKS 4 Server收到BIND請求,根據這兩個信息以及USERID對BIND請求進行評估。
創建新套接字,偵聽在AddrA/PortA上,並向SOCKS 4 Client發送第一個BIND響應
包。
BIND響應包中CD不等於0x5A時表示失敗,包中DSTPORT、DSTIP字段被忽略。
BIND響應包中CD等於0x5A時,包中DSTIP/DSTPORT對應AddrA/PortA。如果DSTIP等
於0(INADDR_ANY),SOCKS 4 Client應將其替換成SOCKS 4 Server的IP,當SOCKS
4 Server非多目(multi-homed)主機時就可能出現這種情況。
c. SOCKS 4 Client收到第一個BIND響應包。
FTP Client調用getsockname(不是getpeername)獲取AddrA/PortA,通過FTP控制
流向FTP Server發送PORT命令,通知FTP Server應該主動建立到AddrA/PortA的
TCP連接。
d. FTP Server收到PORT命令,主動建立到AddrA/PortA的TCP連接,假設TCP連接相關
四元組是:
AddrB,PortB,AddrA,PortA
e. SOCKS 4 Server收到來自FTP Server的TCP連接請求,檢查這條入連接的源IP(
AddrB)是否與FTPSERVER.ADDR匹配,然後向SOCKS 4 Client發送第二個BIND響應
包。
源IP不匹配時第二個BIND響應包中CD字段設爲0x5B,然後SOCKS 4 Server關閉這
條用於發送第二個BIND響應包的TCP連接,同時關閉與FTP Server之間的TCP連接,
但主TCP連接(與CONNECT請求相關的那條TCP連接)繼續保持中。
源IP匹配時CD字段設爲0x5A。然後SOCKS 4 Server開始轉發FTP數據流。
無論如何,第二個BIND響應包中DSTPORT、DSTIP字段被忽略。
對於CONNECT、BIND請求,SOCKS 4 Server有一個定時器(當前CSTC實現採用兩分鐘)。
假設定時器超時,而SOCKS 4 Server與Application Server之間的TCP連接(出連接或
入連接)仍未建立,SOCKS 4 Server將關閉與SOCKS 4 Client之間相應的TCP連接並放
棄相應的轉發。
SOCKS 5協議詳解
筆者在實際學習中,由於在有些軟件用到了socks5(如oicq,icq等),對其原理不甚瞭解,相信很多朋友對其也不是很瞭解,於是仔細研讀了一下rfc1928,覺得有必要譯出來供大家參考。
1.介紹:
防火牆的使用,有效的隔離了機構的內部網絡和外部網絡,這種類型的Internet架構變得越來越流行。這些防火牆系統大都充當着網絡之間的應用層網關的角色,通常提供經過控制的Telnet,FTP,和SMTP訪問。爲了推動全球信息的交流,更多的新的應用層協議的推出。這就有必要提供一個總的架構使這些協議能夠更明顯和更安全的穿過防火牆。也就有必要在實際上爲它們穿過防火牆提供一個更強的認證機制。這種需要源於客戶機-服務器聯繫在不同組織網絡之間的實現,而這種聯繫需要被控制和是很大程度上被認證的。
該協議被描述爲用來提供在TCP和UDP域下爲客戶機-服務器應用程序便利和安全的穿過防火牆的一個架構。該協議在概念上被描述爲一個介於應用層和傳輸層之間的"隔離層",但是這類服務並不提供網絡層網關服務,如ICMP報文的傳輸。
2.現狀:
SOCKS 4爲基於TCP的客戶機-服務器應用程序提供了一種不安全的穿越防火牆的機制,包括TELNET,FTP和當前最流行的信息發現協議如HTTP,WAIS和GOPHER.
新協議爲了包括UDP擴展了SOCKS 4,爲了包括對總體上更強的認證機制的支持擴展了協議架構,爲了包括域名和IPv6地址的支持擴展了地址集。
SOCKS協議執行最具代表性的是包括了在SOCKS庫中利用適當的封裝程序來對基於TCP的客戶程序進行重編譯和重鏈結。
注意:
除非特別提及,封裝在包格式中的十進制數表示的是通訊域的長度(用八位組octect表示)。一個給定的八位組必須具有指定的值,格式X'hh'被用來表示在該域中單個八位組的值。當單詞"變量Variable"被使用時,它指出了通訊域擁有一個可變長度,這個可變長度要麼由一個聯合的(一個或兩個八位組)長度域定義,要麼由一個數據類型域所定義。
3.基於TCP客戶機的程序
當一臺基於TCP的客戶機希望和目標主機建立連接時,而這臺目標主機只有經過防火牆才能到達(這種情況?一直持續到?它被執行時),它就必須在 SOCKS服務器端的適當的SOCKS端口打開一個TCP連結。SOCKS服務按常例來說定位於TCP端口1080。如果連接請求成功,客戶機爲即將使用的認證方式進行一種協商,對所選的方式進行認證,然後發送一個轉發請求。SOCKS服務器對該請求進行評估,並且決定是否建立所請求轉發的連接。
客戶機連接到服務器,發送一個版本標識/方法選擇報文:
+----+----------+----------+
|VER | NMETHODS | METHODS |
+----+----------+----------+
| 1 | 1 | 1 to 255 |
+----+----------+----------+
VER(版本)在這個協議版本中被設置爲X'05'。NMETHODS(方法選擇)中包含在METHODS(方法)中出現的方法標識八位組的數目。
服務器從METHODS給出的方法中選出一種,發送一個METHOD selection(方法選擇)報文:
+----+--------+
|VER | METHOD |
+----+--------+
| 1 | 1 |
+----+--------+
如果所選擇的METHOD的值是X'FF',則客戶機所列出的方法是沒有可以被接受的,客戶機就必須關閉連接。
當前被定義的METHOD的值有:
>> X'00' 無驗證需求
>> X'01' 通用安全服務應用程序接口(GSSAPI)
>> X'02' 用戶名/密碼(USERNAME/PASSWORD)
>> X'03' 至 X'7F' IANA 分配(IANA ASSIGNED)
>> X'80' 至 X'FE' 私人方法保留(RESERVED FOR PRIVATE METHODS)
>> X'FF' 無可接受方法(NO ACCEPTABLE METHODS)
***IANA是負責全球INTERNET上的IP地址進行編號分配的機構(譯者著)***
於是客戶機和服務器進入方法細節的子商議。方法選擇子商議另外描述於獨立的文檔中。
欲得到該協議新的METHOD支持的開發者可以和IANA聯繫以求得到METHOD號。已分配號碼的文檔需要參考METHOD號碼的當前列表和它們的通訊協議。
如果想順利的執行則必須支持GSSAPI和支持用戶名/密碼(USERNAME/PASSWORD)認證方法。
4.需求
一旦方法選擇子商議結束,客戶機就發送請求細節。如果商議方法包括了完整性檢查的目的和/或機密性封裝,則請求必然被封在方法選擇的封裝中。
SOCKS請求如下表所示:
+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
其中:
o VER protocol version:X'05'
o CMD
o CONNECT X'01'
o BIND X'02'
o UDP ASSOCIATE X'03'
o RSV RESERVED
o ATYP address type of following address
o IP V4 address: X'01'
o DOMAINNAME: X'03'
o IP V6 address: X'04'
o DST.ADDR desired destination address
o DST.PORT desired destination port in network octet order
5.地址
在地址域(DST.ADDR,BND.ADDR)中,ATYP域詳細說明了包含在該域內部的地址類型:
o X'01'
該地址是IPv4地址,長4個八位組。
o X'03'
該地址包含一個完全的域名。第一個八位組包含了後面名稱的八位組的數目,沒有中止的空八位組。
o X'04'
該地址是IPv6地址,長16個八位組。
6.迴應
到SOCKS服務器的連接一經建立,客戶機即發送SOCKS請求信息,並且完成認證商議。服務器評估請求,返回一個迴應如下表所示:
+----+-----+-------+------+----------+----------+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
其中:
o VER protocol version: X'05'
o REP Reply field:
o X'00' succeeded
o X'01' general SOCKS server failure
o X'02' connection not allowed by ruleset
o X'03' Network unreachable
o X'04' Host unreachable
o X'05' Connection refused
o X'06' TTL expired
o X'07' Command not supported
o X'08' Address type not supported
o X'09' to X'FF' unassigned
o RSV RESERVED
o ATYP address type of following address
o IP V4 address: X'01'
o DOMAINNAME: X'03'
o IP V6 address: X'04'
o BND.ADDR server bound address
o BND.PORT server bound port in network octet order
標誌RESERVED(RSV)的地方必須設置爲X'00'。
如果被選中的方法包括有認證目的封裝,完整性和/或機密性的檢查,則迴應就被封裝在方法選擇的封裝套中。
CONNECT
在CONNECT的迴應中,BND.PORT包括了服務器分配的連接到目標主機的端口號,同時BND.ADDR包含了關聯的IP地址。此處所提供的 BND.ADDR通常情況不同於客戶機連接到SOCKS服務器所用的IP地址,因爲這些服務器提供的經常都是多址的(muti-homed)。都期望 SOCKS主機能使用DST.ADDR和DST.PORT,連接請求評估中的客戶端源地址和端口。
BIND
BIND請求被用在那些需要客戶機接受到服務器連接的協議中。FTP就是一個衆所周知的例子,它通過使用命令和狀態報告建立最基本的客戶機-服務器連接,按照需要使用服務器-客戶端連接來傳輸數據。(例如:ls,get,put)
都期望在使用應用協議的客戶端在使用CONNECT建立首次連接之後僅僅使用BIND請求建立第二次連接。都期望SOCKS主機在評估BIND請求時能夠使用DST.ADDR和DST.PORT。
有兩次應答都是在BIND操作期間從SOCKS服務器發送到客戶端的。第一次是發送在服務器創建和綁定一個新的socket之後。BIND.PORT 域包含了SOCKS主機分配和偵聽一個接入連接的端口號。BND.ADDR域包含了關聯的IP地址。 客戶端具有代表性的是使用這些信息來通報應用程序連接到指定地址的服務器。第二次應答只是發生在預期的接入連接成功或者失敗之後。在第二次應答中,BND.PORT和BND.ADDR域包含了欲連接主機的地址和端口號。
UDP ASSOCIATE(連接?)
UDP 連接請求用來建立一個在UDP延遲過程中操作UDP數據報的連接。DST.ADDR和DST.PORT域包含了客戶機期望在這個連接上用來發送UDP數據報的地址和端口。服務器可以利用該信息來限制至這個連接的訪問。如果客戶端在UDP連接時不持有信息,則客戶端必須使用一個全零的端口號和地址。
當一個含有UDP連接請求到達的TCP連接中斷時,UDP連接中斷。
在UDP連接請求的迴應中,BND.PORT和BND.ADDR域指明瞭客戶端需要被髮送UDP請求消息的端口號/地址。
迴應過程
當一個迴應(REP值非X'00')指明失敗時,SOCKS主機必須在發送後馬上中斷該TCP連接。該過程時間必須爲在偵測到引起失敗的原因後不超過10秒。
如果迴應代碼(REP值爲X'00')時,則標誌成功,請求或是BIND或是CONNECT,客戶機現在就可以傳送數據了。如果所選擇的認證方法支持完整性、認證機制和/或機密性的封裝,則數據被方法選擇封裝包來進行封裝。類似,當數據從客戶機到達SOCKS主機時,主機必須使用恰當的認證方法來封裝數據。
sock5代理工作原理
出處:darkness fallen
時間:Wed, 26 Apr 2006 11:42:15 +0000
作者:hjma
地址:http://hjma.scgy.org/blog/bo-blog/read.php?3
內容:
sock5代理的工作程序是:
1。需要代理方向服務器發出請求信息。
2。代理方應答
3。需要代理方接到應答後發送向代理方發送目的ip和端口
4。代理方與目的連接
5。代理方將需要代理方發出的信息傳到目的方,將目的方發出的信息傳到需要代理方。代理完成
由於網上的信息傳輸都是運用tcp或udp進行的,所以使用socks5代理可以辦到網上所能辦到的一切,而且不輿目的方會查到你的ip,既安全又方便
sock5支持UDP和TCP,但兩種代理是有區別的,以下分類說明
如何用代理TCP協議
1。向服務器的1080端口建立tcp連接。
2。向服務器發送 05 01 00 (此爲16進制碼,以下同)
3。如果接到 05 00 則是可以代理
4。發送 05 01 00 01 + 目的地址(4字節) + 目的端口(2字節),目的地址和端口都是16進制碼(不是字符串)。
例202.103.190.27 - 7201
則發送的信息爲:05 01 00 01 CA 67 BE 1B 1C 21
(CA=202 67=103 BE=190 1B=27 1C21=7201)
5。接受服務器返回的自身地址和端口,連接完成
6。以後操作和直接與目的方進行TCP連接相同。
如何用代理UDP連接
1。向服務器的1080端口建立tcp連接
2。向服務器發送 05 01 00
3。如果接到 05 00 則是可以代理
4。發送 05 03 00 01 00 00 00 00 + 本地UDP端口(2字節)
5。服務器返回 05 00 00 01 +服務器地址+端口
7.需要申請方發送
00 00 00 01 +目的地址IP(4字節)+目的端口 +所要發送的信息
8。當有數據報返回時
向需要代理方發出00 00 00 01 +來源地址IP(4字節)+來源端口 +接受的信息
注:此爲不需要密碼的代理協議,只是socks5的一部分,完整協議請看RFC1928
附foxmail連接測試數據:
無sock5代理時TCP數據:
客戶端 服務器
SYN
ACKSYN
ACK
+OK X1 NT-POP3 Server iflytek.com (IMail 8.15 230122-9)..
USER hjma..
+OK send your password..
PASS xxxxxxx..
+OK maildrop locked and ready..
STAT..
+OK 0 0..
QUIT..
+OK POP3 Server saying Good-Bye..
ACKFIN
ACK
ACKFIN
ACK
使用sock5代理時TCP數據:
客戶端 sock5服務器
SYN
ACKSYN
ACK
05 01 00 00 00 00
05 00 00 00 00 00
05 01 00 03 0E 31 39 32 2E 31 36 38 2E 37 35 2E 31 31 34 00 6E (.....192.168.75.114.n)
05 00 00 01 C0 A8 4D 56 08 D4
ACK
+OK X1 NT-POP3 Server iflytek.com (IMail 8.15 228888-9)..
USER hjma..
+OK send your password..
PASS xxxxxxx..
+OK maildrop locked and ready..
STAT..
+OK 0 0..
QUIT..
+OK POP3 Server saying Good-Bye..
ACKFIN
ACK
ACKFIN
ACK
例202.103.190.27 - 7201
則發送的信息爲:05 01 00 01 CA 67 BE 1B 1C 21
(CA=202 67=103 BE=190 1B=27 1C21=7201)
1.客戶端發送到socks5代理至少三個字節的請求,第一個字節一定爲5,第二個字節爲使用多少種驗證,第三個字節爲驗證模式代碼.
例:如果要使用"USERNAME/PASSWORD",那麼這三個字節爲5 1 2
第一位爲5
第二位是使用模式,0x01代表TCP CONNECT,0x02代表TCP BIND,0x03代表UDP ASSOCIATE
第三位保留
第四位是地址使用模式:0x01代表IP V4地址;0x03代表域名;0x04代表IP V6地址(一般常見的只是0x01和0x03兩種模式,因爲很多軟件都不支持IP V6的)
第五位開始就是目標的地址和端口.
A.對於TCP CONNECT
將請求分析後,將目標地址和 目標端口從請求中解析出來(無論請求中帶的地址是否以域名方式發送過來,最終要將地址轉換爲IPV4的地址),然後使用connect()連接到目標地址中的目標端口中去,如果成功連接,那就向客戶端發送回10個字節的信息,第一字節爲5,第二字節爲0,第三字節爲0,第四字節爲1,其它字節都爲0.
B.對於UDP ASSOCIATE(這個複雜很多了)
將請求分析後,先保存好客戶端的連接信息(客戶端的IP和連接過來的源端口),然後本地創建一個UDP的socket,並將socket使用bind()綁入本地所有地址中的一個UDP端口中去,然後得到本地UDP綁定的IP和端口,創建一個10個字節的信息,返回給客戶端去.第一字節爲0x05,第二和第三字節都爲0,第四字節爲0x01(IPV4地址),第五位到第8位是UDP綁定的IP(以DWORD模式保存),第9位和第10位是UDP綁定的端口(以WORD模式保存).
A.對於TCP CONNECT
很簡單,從客戶中讀到的所有數據,馬上發送到遠程目標;從遠程目標中讀到的所有數據,馬上全部發送到客戶端
B.對於UDP ASSOCIATE(又是複雜),
有數據包時,首先將數據全部讀取,然後判斷數據是從客戶端還是遠程目標傳送過來的(在讀取時可以得到是從什麼地址和端口讀取到數據的,然後比較上面第6步時我們保存了下來的客戶端的連接信息),如果數據是從客戶端讀取過來的,我們要將UDP頭去掉.例如我們讀取到的Buffer,Buffer[3]是1時,UDP頭就是10個字節長度,如果Buffer[3]是3的話,UDP頭長度是7+Buffer[4].例如我們得到UDP頭是20位,我們接收到的Buffer是50位長度,那麼我們發送到目標的數據包長度是30位,前20位不發送,只發送後面的30位.如果數據是
從遠程目標發送來的,我們就要多發送多10位的UDP頭,這10位的UDP頭前三位都是0,第四位是0x01,第五到第八位是我們保存下來的客戶端的IP,第9和第十位是客戶端的端口.如果我們接收到的Buffer長度是50,那麼我們發送到客戶端的數據就要加上10位的UDP頭,也就是一共要發送60位字節長度的數據.
http://www.faqs.org/rfcs/rfc1928.html 是socks5代理的rfc,不過是寫得非常非常簡單的。我也有時會質疑rfc爲什麼都這麼簡單和模糊,爲什麼不可以寫詳細一點,或加上幾個簡單的例子。FTP服務的rfc甚至連列舉文件時,ftp服務向客戶發送回去的每一行信息的標準都沒有,所以大家可以看到幾乎每一個ftp服務向客戶端返回的文件列表都不一定是相同的。