SOCKS5 简介
防火墙可以把内部网独立出来,防火墙作为一个应用层的网关,通常会支持 TELNET,FTP,SMTP的访问,从而需要有一个协议能够支持安全地穿透防火墙来访问这几个协议,SOCKS5应运而生。
SOCKS5 协议由 RFC1928 定义,是SOCKS4 的扩展,提供了更多验证身份的方式,并且添加了对 IPv6 和 UDP 的支持,后者可以用于 DNS lookups。
流程简介
开始的握手包括:
- 客户端连接并发送一个 “问候”消息,包括一列支持的验证方法。
- 服务端选择其中一种方法(如果没有可以接受的方法则发送失败应答)。
- 几条消息已经传输于客户端与服务端之间,取决于选择的验证方法。
- 客户端发送一个连接请求,类似SOCKS4。
- 服务端应答,类似SOCKS4。
支持的验证方法如下,以数字表示:
- 0x00:无验证。
- 0x01:GSSAP。
- 0x02:账户/密码。
- 0x03-0x7F:由 IANA 颂发的方法。
- 0x80-0xFE:保留方法(私用)。
1,客户端发送的“问候”消息的字段描述如下:
+----+----------+----------+
|VER | NMETHODS | METHODS |
+----+----------+----------+
| 1 | 1 | 1 to 255 |
+----+----------+----------+
- 字段1:SOCKS版本号,1个字节(必须是0x05)。
- 字段2:支持的验证方式的个数,1个字节。
- 字段3:验证方式,变长,每种方式占1个字节。
2,服务端选择后的通信:
+----+--------+
|VER | METHOD |
+----+--------+
| 1 | 1 |
+----+--------+
- 字段1:SOCKS版本号,1个字节(必须是0x05)。
- 字段2:选择的验证方式,1个字节,如果不接受任何方式则返回 0xFF。
随后的验证是根据验证方式来定的,基本用户名/密码的验证方式(0x02)在 RFC1929 中描述。
对于用户名/密码的验证方式,客户端的验证请求是:
- 字段1:版本号,1个字节(必须是0x01)。
- 字段2:用户名长度,1个字节。
- 字段3:用户名。
- 字段4:密码长度,1个字节。
- 字段5:密码。
服务端返回验证结果:
- 字段1:版本号,1个字节。
- 字段2:状态码,1个字节。
- 0x00:成功。
- 任何其他值:失败,连接关闭。
客户端的连接请求是:
+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
- 字段1:SOCKS版本号,1个字节(必须是0x05)。
- 字段2:控制码,1个字节。
- 0x01:建立 TCP/IP stream 连接。
- 0x02:建立 TCP/IP 端口连接。
- 0x03:关联一个 UDP 端口。
- 字段3:保留。必须是0x00。
- 字段4:地址类型,1个字节。
- 0x01:IPv4 地址。
- 0x03:域名。
- 0x04:IPv6地址。
- 字段5:目标地址:
- 4字节的IPv4地址。
- 1个字节表示名称长度,紧接着域名。
- 16个字节的IPv6地址。
- 字段6:端口号(network byte order),2个字节。
服务端响应:
+----+-----+-------+------+----------+----------+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
- 字段1:SOCKS版本号,1个字节(必须是0x05)。
- 字段2:状态码,1个字节:
- 0x00:请求批准。
- 0x01:一般性失败。
- 0x02:规则不允许连接。
- 0x03:网络不可用。
- 0x04:找不到主机。
- 0x05:目标主机拒绝连接。
- 0x06:TTL 超时。
- 0x07:不支持的控制/协议错误。
- 0x08:地址类型不支持。
- 字段3:保留值,必须是0x00。
- 字段4:地址类型,1个字节。
- 0x01:IPv4 地址。
- 0x03:域名。
- 0x04:IPv6地址。
- 字段5:目标地址:
- 4字节的IPv4地址。
- 1个字节表示名称长度,紧接着域名。
- 16个字节的IPv6地址。
- 字段6:端口号(network byte order),2个字节。
UDP 关联
- UDP关联请求用于在UDP relay 到处理 UDP 数据报的过程中建立一个关联关系,DST.ADDR 和 DST.PORT中包括了客户端想要用于发送UDP数据报的地址和端口。服务端可能用这些信息有限地处理这个关联关系。
- 如果客户端在 UDP关联时没有指定这些信息,那么客户端必须用一个全部为0的端口号和地址。
- UDP关联会在这个UDP关联的TCP连接中止时随之中止。
参考:
https://en.wikipedia.org/wiki/SOCKS#SOCKS5
https://tools.ietf.org/html/rfc1928