最近研究了下socket5协议,它是一个tcp、udp的代理协议(socket4不支持udp),大部分软件都支持socket5代理。
一般来说要建立起一个代理的连接要经过三个阶段。
阶段一: 验证
客户端告诉代理服务器自已支持的验证方式,可以有多种验证方式。
1 2 3 4 5 6 7
+---------+-----------------+------------------+ |协议版本 | 支持的验证式数量 | 验证方式 | +---------+-----------------+------------------+ |1个字节 | 1个字节 | 1种式占一个字节 | +---------+-----------------+------------------+ |0x05 |0x02 |0x00,0x02 | +---------+-----------------+------------------+
上面例子,客户端告诉代理服务器自已支持两种验证方式。
0x00 无验证需求
0x01 通用安全服务应用程序接口(GSSAPI)
0x02 用户名/密码(USERNAME/PASSWORD)
0x03 至 X’7F’ IANA 分配(IANA ASSIGNED)
0x80 至 X’FE’ 私人方法保留(RESERVED FOR PRIVATE METHODS)
0xFF 无可接受方法(NO ACCEPTABLE METHODS)
代理服务器收到上面的报文,选择自已所能支持的验证方式,并返回相应的数所包
1 2 3 4 5 6 7
+----------+------------------+ |协议版本 | 支持的验证方式 | +----------+------------------+ |1个字节 | 1个字节 | +----------+------------------+ |0x05 | 0x00 | +----------+------------------+
上面例子,服务端告诉客户端不需要验证。 > 注:如果代服务器不支持客户凋端给出的所有验证方式则代理服务器返回的验证方式为
0xFF
,即表示无可验证的方式, 客户端收到该报文后必須要关闭当前连接。
除了无需验证,其它的验证方式还需要子协议来进行验证。这里我们用0x02
来举例,即用户/密码这种验证方式,这个也是用得最多的。
当客户端收到代理服务器支持
0x02
验证方式(用户密码验证),客户端要发送用户密码给代理服务器1 2 3 4 5 6 7
+--------+-----------+-------------------------+---------+-------------------------------+ |协议版本 | 用户名长度 |用户名 | 密码长度 | 密码 | +--------+-----------+-------------------------+---------+-------------------------------+ |1个字节 | 1个字节 |用户名字节数据 | 1个字节 | 密码字节数据 | +--------+-----------+-------------------------+---------+-------------------------------+ |0x01 | 0x05 |0x70,0x61,0x6b,0x6f,0x72 | 0x06 | 0x31,0x32,0x33,0x34,0x35,0x36| +--------+-----------+-------------------------+---------+-------------------------------+
上面的例子用户名为
pakor
对应的字节长度为5,密码为12345
对应的字节数为6。 > 注:这里的协议版本是子协议版本不是socket5的协议版本。 > 目前用户名/密码验证这个子议的版本是0x01
代理服务器接收到客户端的用户名和密码进行验证,然后返回验证状态。
1 2 3 4 5 6 7
+--------+-------+ |协议版本 |状态 | +--------+-------+ |1个字节 |1个字节 | +--------+-------+ |0x01 |0x00 | +--------+-------+
如果验证成功则返回装态
0x00
,否则返回任何非0x00
的值。客户端收到未成功验的状态必须关闭当前连接。
更多关于用户名/密码子协议信息请参看rfc1929
阶段二:建立代理连接
完成了校验过程接下来就是让代理服务器建立代理连接。
客户端发送要建立的的代理连接的地址及端口,地址可以是域名、IPv4、IPv6。
1 2 3 4 5 6 7
+----------+------------+---------+-----------+-----------------------+------------+ |协议版本号 | 请求的类型 |保留字段 | 地址类型 | 地址数据 | 地址端口 | +----------+------------+---------+-----------+-----------------------+------------+ |1个字节 | 1个字节 |1个字节 | 1个字节 | 变长 | 2个字节 | +----------+------------+---------+-----------+-----------------------+------------+ |0x05 | 0x01 |0x00 | 0x01 | 0x0a,0x00,0x01,0x0a | 0x00,0x50 | +----------+------------+---------+-----------+-----------------------+------------+
上面例子,客户端告诉代理服务器建立一个连接到
10.0.1.10
的80
端口。这里的保留字段是固定的0x00
。
地址类型有下面几种:- IPV4 :
0x01
- 域名 :
0x03
- IPV6 :
0x04
请求类型有下面几种:
- CONNECT :
0x01
, 建立代理连接 - BIND :
0x02
,告诉代理服务器监听目标机器的连接,也就是让代理服务器创建socket监听来自目标机器的连接。FTP这类需要服务端主动联接客户端的的应用场景。 - 1. 只有在完成了connnect操作之后才能进行bind操作
- 2. bind操作之后,代理服务器会有两次响应, 第一次响应是在创建socket监听完成之后,第二次是在目标机器连接到代理服务器上之后。
- UDP ASSOCIATE :
0x03
, udp 协议请求代理。
注:UDP ASSOCIATE 时这里请求的地址和端口是告诉代理服务器客户端要使用这个地址发送数据到代理服务器。 代理服务器可以用这个信息对访问进行一些限制。
- IPV4 :
代理服务器收到客户端的请求后,要创建到目标机器的连接或创建监听目标机器的socket,然后返回相应的信息
1 2 3 4 5 6 7
+----------+--------+---------+-----------+---------------------+------------+ |协议版本号 | 状态码 |保留字段 | 地址类型 | 绑定的地址 |顷绑定的端口 | +----------+--------+---------+-----------+---------------------+------------+ |1个字节 | 1个字节 |1个字节 | 1个字节 | 变长 |2个字节 | +----------+--------+---------+-----------+---------------------+------------+ |0x05 | 0x00 |0x00 | 0x01 | 0x0a,0x00,0x01,0x0a|0x00,0x50 | +----------+--------+---------+-----------+---------------------+------------+
上面的例子,代理服务器连接目标服务器
10.0.1.10
端口80
成功。
状态码有下面几种:X00
succeededX01
general SOCKS server failureX02
connection not allowed by rulesetX03
Network unreachableX04
Host unreachableX05
Connection refusedX06
TTL expiredX07
Command not supportedX08
Address type not supportedX09
to X’FF’ unassigned
绑定的地址和端口根据请求中的CMD的不同而不同
- CONNECT : 此时绑定的地址是指代理服务器连接到目标机器时的ip和端口
-
BIND : 这里会有两次响应
- 第一次响应中是指代理服务器创建监听socket时绑定的ip和端口
- 第二次响应中是指代理服务器监听的scoket收来自目标机器连接时的ip和端口
- UDP ASSOCIATE : 此时绑定地址指明了客户发送UDP消息至服务器的端口和地址
阶段三:数据包转发
到了这个阶段基本就是数据转发了,tcp就直接转发,udp还须要做点工作。
客户端发送给代理服务器和代理服务器返回给客户端的数据都需要包装下
1 2 3 4 5
+----+------+------+----------+----------+----------+ |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | +----+------+------+----------+----------+----------+ | 2 | 1 | 1 | Variable | 2 | Variable | +----+------+------+----------+----------+----------+
- RSV Reserved
0x00,0x00
- FRAG Current fragment number
- ATYP address type of following addresses:
- IP V4 address:
0x01
- DOMAINNAME:
0x03
- IP V6 address:
0x04
- IP V4 address:
- DST.ADDR desired destination address
- DST.PORT desired destination port
- DATA user data
详细文档参考rfc1928
- RSV Reserved
相关参考文档