除了这个意译版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
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也是这样).
- WebSocket协议中文版
WebSocket协议中文版 摘要 WebSocket协议实现在受控环境中运行不受信任代码的一个客户端到一个从该代码已经选择加入通信的远程主机之间的全双工通信.用于这个安全模型是通常由web浏览器使用 ...
- HTTP1.1协议中文版-RFC2616
转自:http://www.cnpaf.net/Class/HTTP/200811/23277.html 说明 本文档规定了互联网社区的标准组协议,并需要讨论和建议以便更加完善.请参考 “互联网官方协 ...
- RFC1939 POP3协议 中文版 (转载)
1.简介 对于在网络上的比较小的结点,支持消息传输系统(MTS)是不实际的.例如,一台工作站可能不具有充足的资源允许SMTP服务器和相当的本地邮件传送系统保持序驻留,并持续运行.同样的,将一台个人 ...
- MQTT-CN MQTT协议中文版
欢迎任何形式的转载,但请务必注明出处:http://www.cnblogs.com/liangjingyang 项目地址:https://github.com/liangjingyang/MQTT-C ...
- [转帖]socks5 协议简介
socks5 协议简介 http://zhihan.me/network/2017/09/24/socks5-protocol/ 什么是socks5 或许你没听说过socks5,但你一定听说过Shad ...
- HTTP协议和SOCKS5协议
HTTP协议和SOCKS5协议 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们平时上网的时候基本上是离不开浏览器的,尤其是搜索资料的时候,那么这个浏览器是如何工作的呢?用的又是 ...
- 使用 某款基于Socks5协议的代理软件 一段时间后 被封锁掉IP的一些技术思考
由于关键词比较敏感为了不被删除帖子所以文中某软件(上图所示软件)不用全称表示. 去年9月末在 在某国外网站 上弄了一个vpn,在上面安装了某软件,使用起来还是蛮不错的,平时查查英文论文,看看美剧还是比 ...
- Netty实现高性能IOT服务器(Groza)之手撕MQTT协议篇上
前言 诞生及优势 MQTT由Andy Stanford-Clark(IBM)和Arlen Nipper(Eurotech,现为Cirrus Link)于1999年开发,用于监测穿越沙漠的石油管道.目标 ...
- C#封装的websocket协议类
关于VB版之前已经写了,有需要可以进传送门<VB封装的WebSocket模块,拿来即用>,两个使用都差不多,这里简单概述一下: 连接完成后,没有握手就用Handshake()先完成握手之后 ...
随机推荐
- Spring Boot - Profile配置
Profile是什么 Profile我也找不出合适的中文来定义,简单来说,Profile就是Spring Boot可以对不同环境或者指令来读取不同的配置文件. Profile使用 假如有开发.测试.生 ...
- Python爬虫——反爬
反爬概述 网络爬虫,是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成. 但是当网络爬虫被滥用后,互联网上就出现太多同质的东西,原创得不到保护. 于是,很多网站开始反网络爬 ...
- 【sping揭秘】20、spring的orm
面向对象的操作方式,spring统一定义在org.springframework.jdbc.object以RdbmsOperation作为顶层抽象定义 Spring对各种ORM的集成 Spring的集 ...
- firefox设置每次访问时检查缓存
1.在firefox的地址栏上输入about:config回车2.找到browser.cache.check_doc_frequency选项,双击将3改成1保存即可. 选项每个值都是什么含义的.请看下 ...
- Python内置类型(5)--迭代器类型
指能够被内置函数next调用并不断返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值的对象称为迭代器(Iterator) 其实以上的说法只是侠义上的迭代器的定义,在pyt ...
- MapReduce对交易日志进行排序的Demo(MR的二次排序)
1.日志源文件 (各个列分别是: 账户,营业额,花费,日期) zhangsan@163.com 6000 0 2014-02-20 lisi@163.com 2000 0 2014-02-20 lis ...
- Spring boot CommandLineRunner接口使用例子
前言 Spring boot的CommandLineRunner接口主要用于实现在应用初始化后,去执行一段代码块逻辑,这段初始化代码在整个应用生命周期内只会执行一次. 如何使用CommandLineR ...
- TCP/IP 笔记 - 域名解析和域名系统
由于IP地址的烦琐导致的记忆和使用困难,互联网支持使用主机名称来识别包括客户机和服务器在内的主机.同时为了使用一系列协议,主机名称通过称为"名称解析"的过程转换成对应IP地址. 互 ...
- 深度学习论文翻译解析(二):An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition
论文标题:An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application ...
- 深度学习之PyTorch实战(1)——基础学习及搭建环境
最近在学习PyTorch框架,买了一本<深度学习之PyTorch实战计算机视觉>,从学习开始,小编会整理学习笔记,并博客记录,希望自己好好学完这本书,最后能熟练应用此框架. PyTorch ...