除了这个意译版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,
或者说出于什么考虑才需要刻意将这两个域置零。有现实例子存在吗。
shixudong@163.com
考虑这种情况:
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这里有笔误,写信询问mleech@bnr.ca、ietf-web@ietf.org去了。
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服务向客户端返回的文件列表都不一定是相同的。