轉載的socks4 socks5 rfc1928一大堆

除了這個意譯版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

 

 

 

sock代理分爲sock4代理和 sock5代理。sock4支持TCP(事實僅支持TCP),無需用戶名、密碼驗證;sock5支持TCP和UDP,根據代理服務器設置是否需要用戶名、密碼認證。TCP和UDP代理工作原理產不多,UDP代理網上多的是,google一下即可。這裏只講TCP代理工作原理。
sock代理工作原理大致如下:
1。需要代理方向服務器發出請求信息;
2。代理方應答;
3。需要代理方接到應答後發送向代理方發送目的ip和端口;
4。代理方與目的連接;
5。代理方將需要代理方發出的信息傳到目的方,將目的方發出的信息傳到需要代理方;
6。代理完成。
下面對sock4和sock5的代理工作原理流程分別詳細說明,並給出示例代碼。
sock4的TCP代理工作流程:
1。我們首先還是連接服務器,然後發送數據給服務器。由於是無用戶密碼驗證,我們需要發送9個字節的數據,展開寫爲 04 01 + 目標端口(2字節) + 目標IP(4字節) + 00,其中目標端口和目標IP就是我們真正要連接的服務器端口和服務器地址;
2。代理服務器返回8字節的數據,我們只要判斷第二字節是否爲90即可,若是90連接成功,否則失敗.剩下的操作和不存在代理服務器一樣,可直接用發送/接受數據。
sock5的TCP代理工作流程:
1。向服務器的代理端口建立tcp連接。一般爲1080;
2。向服務器發送 05 02 00 02(此爲16進制碼,以下同),讓代理服務器選擇認證方式 ;
05
02 這裏確認2種認證方式 無需認證和需要認證,只需要驗證一種方式,可以直接發送05 01 00查詢服務器是否支持無認證代理方式;
00 不需要認證;
02 需要認證;
3。如果接到 05 00 則是可以代理或則05 02需要認證,這裏只需要判斷第二字節就行;
如果需要認證,需要向服務器發送01 用戶名長度(2字節)用戶名 密碼長度(2字節)密碼,然後接收服務器返回數據,如果第二字節爲 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。接收代理服務器返回的數據,我們只要判斷第二字節是否爲00即表示代理連接完成;
6。以後操作和直接與目的方進行TCP連接相同。
   socks5代理和sock4代理都是很相似的(sock4代理網上應該有很多代碼,我也曾在這裏放過sock4代理的代理),不同的就是sock5代理除了支持UDP協議的數據外,還支持多種驗證模式.一般常用的只是無驗證模式(NO AUTHENTICATION )和用戶/密碼模式(USERNAME/PASSWORD),其它模式就算加上了,應用程序也不支持的(你可以看看oicq,msn,flashfxp等軟件,也都只是支持這兩種模式的).socks5代理一般是三種模式的支持,TCP CONNECT,TCP BIND和UDP ASSOCIATE,這裏最常用的是TCP CONNECT,因爲絕大部分TCP協議的軟件都是使用這種模式的,TCP BIND只會用在FTP的Active模式中(就是數據連接是由FTP服務連接回FTP客戶),並不常用,而且我測試過flashfxp和cuteftp,兩種都不支持TCP BIND的(就是說如果是用了代理的話,兩種軟件都不支持使用Active模式,一定要使用Passive模式和FTP服務進行數據交換),所以我們只簡單地討論一下TCP CONNECT和UDP ASSOCIATE兩種模式.
 Socks5代理的請求和返回信息.
1.客戶端發送到socks5代理至少三個字節的請求,第一個字節一定爲5,第二個字節爲使用多少種驗證,第三個字節爲驗證模式代碼.
例:如果要使用"USERNAME/PASSWORD",那麼這三個字節爲5 1 2
2.Sock5代理接到上面請求後,如果是支持"USERNAME/PASSORD"的驗證模式,就會返回兩個字節,第一字節爲5,第二字節爲2.
3.客戶端然後就向socks5代理髮送驗證信息,信息第一字節不需要理會,第二字節爲驗證用戶名的長度,第三字節開始是用戶名和密碼信息.
4.socks5代理驗證用戶名和密碼成功後,向客戶端返回兩個字節,5和0,如果驗證失敗,返回0x05和0xff.
5.客戶端開始向sock5代理髮送第一個向遠程目標進行操作的請求,請求模式如下:
第一位爲5
第二位是使用模式,0x01代表TCP CONNECT,0x02代表TCP BIND,0x03代表UDP ASSOCIATE
第三位保留
第四位是地址使用模式:0x01代表IP V4地址;0x03代表域名;0x04代表IP V6地址(一般常見的只是0x01和0x03兩種模式,因爲很多軟件都不支持IP V6的)
第五位開始就是目標的地址和端口.
6.socks代理開始處理這個請求,對於TCP CONNECT和UDP ASSOCIATE模式有不同的處理.
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模式保存).
7.最後是數據的傳送了,TCP CONNECT和UDP ASSOCIATE模式又有所不同
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位字節長度的數據.
支持驗證,支持TCP CONNECT和UDP ASSOCIATE模式的sock5代理的基本編寫就是這樣。
http://www.faqs.org/rfcs/rfc1928.html 是socks5代理的rfc,不過是寫得非常非常簡單的。我也有時會質疑rfc爲什麼都這麼簡單和模糊,爲什麼不可以寫詳細一點,或加上幾個簡單的例子。FTP服務的rfc甚至連列舉文件時,ftp服務向客戶發送回去的每一行信息的標準都沒有,所以大家可以看到幾乎每一個ftp服務向客戶端返回的文件列表都不一定是相同的。
有一點需要補充的,那就是socks5代理的超時。在剛連接和驗證那段期間可以設置超時,例如用戶連接後30秒都沒有驗證的,就將那連接關閉。但驗證後,就不可以設置超時了(或者是可以設置的,但我實在不知道如何做)。不可以設置超時的原因有兩個:
1.對於UDP的連接,因爲UDP是無連接的,你很難確定用戶是否還是連接着,還會繼續發送數據過來的。有人說可以定時發送數據過去。這是一種辦法,但是要考慮到,因爲你不知道用戶是使用什麼軟件在發送UDP數據過來,你亂髮數據過去,很大可能是被客戶軟件認爲是不合法的數據而過濾掉,如果sock5代理因爲發過去的數據被過濾了而認爲客戶 是斷開了,那麼極容易就將沒有斷開的用戶也踢下去了,而且現在的oicq還會使用使用兩個連接,一個是UDP連接,另一個是TCP連接,UDP連接只是登陸上服務器時使用,TCP連接卻是進行數據傳輸的,而UDP連接卻是一直都不會有數據傳輸的了,如果socks5代理因爲UDP連接長時間沒有數據傳輸而將那個UDP連接關閉的話,oicq也會因爲這樣而掉線(你關閉了UDP連接,oicq以爲代理是不可用了,自己會將TCP連接斷開)
2.對於TCP連接,設置超時是很簡單,但只是對於一般只是使用一個連接進行數據通訊的軟件有效,對於FTP是完全失效。當FTP客戶掛socks5代理時,當有數據傳輸,例如列文件,下載文件或上傳文件時,就會需要兩個TCP連接,一個是接收FTP客戶或接收FTP服務器返回的信息的,另一個是進行數據交換的,如果在進行長時間的數據交換時,例如上傳文件或下載文件,有可能是要進行幾小時或更長的數據交換,接收FTP客戶命令或接收FTP服務器返回信息的那個TCP連接,是一直都沒有數據通過的,如果設置了超時,例如1小時沒有數據通過就斷開連接的話,你就會將那個TCP連接關閉了,如果你關閉了那個TCP連接的話,FTP客戶端也會馬上將數據交換的那個TCP連接馬上關閉(因爲FTP客戶端會認爲自己被斷開了)。
就因爲這兩點,我自己認爲無法設置超時.也測試過幾個socks5代理軟件,也是沒有在驗證後做超時的處理的。因爲TCP連接正常斷開還是非正常的斷開,socks5代理都可以輕易檢查到,但UDP連接就很難檢查,所以在測試中都有發現一些不正常斷開的UDP連接還是一直沒被socks5代理關閉到(ccproxy,wingate,還有大家可能最熟悉的skserver也是這樣).
發佈了31 篇原創文章 · 獲贊 10 · 訪問量 65萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章