最近通过自己实现一套scoks5代理,来理解socks5.
首先是对scoks5的了解.
官方原文 https://www.ietf.org/rfc/rfc1928.txt
简单的理解为:
- 支持tcp代理
- 支持UDP代理
- 支持域名代理解析
- 支持丰富的认证方式
具体实现步骤大致如下:
1.建立与SOCKS5服务器的TCP连接后客户端需要先发送请求来协商版本及认证方式,格式为(以字节为单位):
+----+----------+----------+ |VER | NMETHODS | METHODS | +----+----------+----------+ | 1 | 1 | 1 to 255 | +----+----------+----------+
VER是SOCKS版本,这里应该是0x05;
NMETHODS是METHODS部分的长度;
METHODS是客户端支持的认证方式列表,每个方法占1字节。当前的定义是:
- 0x00 不需要认证
- 0x01 GSSAPI
- 0x02 用户名、密码认证
- 0x03 – 0x7F由IANA分配(保留)
- 0x80 – 0xFE为私人方法保留
- 0xFF 无可接受的方法
2.服务器从客户端提供的方法中选择一个并通过以下消息通知客户端(以字节为单位):
+----+--------+ |VER | METHOD | +----+--------+ | 1 | 1 | +----+--------+
VER是SOCKS版本,这里应该是0x05;
METHOD是服务端选中的方法。如果返回0xFF表示没有一个认证方法被选中,客户端需要关闭连接。
之后客户端和服务端根据选定的认证方式执行对应的认证。
3.认证结束后客户端就可以发送请求信息。如果认证方法有特殊封装要求,请求必须按照方法所定义的方式进行封装。
SOCKS5请求格式(以字节为单位):
+----+-----+-------+------+----------+----------+ |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +----+-----+-------+------+----------+----------+
VER是SOCKS版本,这里应该是0x05;
CMD是SOCK的命令码:
- 0x01表示CONNECT请求
- 0x02表示BIND请求
- 0x03表示UDP转发
RSV 默认 0x00,保留
ATYP 后面的地址类型:
- 0x01 IPv4地址,DST ADDR部分4字节长度
- 0x03 域名,DST ADDR部分第一个字节为域名长度,DST ADDR剩余的内容为域名,没有\0结尾。
- 0x04 IPv6地址,16个字节长度。
DST.ADDR 目的地址
DST.PROT 目的端口
注意:如果为UDP 这里的目的地为地址与端口为 客户端的UDP信息。告诉代理服务器以后会以这个地址进行UDP信息交互。
4.服务器按以下格式回应客户端的请求(以字节为单位):
+----+-----+-------+------+----------+----------+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +----+-----+-------+------+----------+----------+
REP 应答字段
- 0x00 表示成功
- 0x01 普通SOCKS服务器连接失败
- 0x02 现有规则不允许连接
- 0x03 网络不可达
- 0x04 主机不可达
- 0x05 连接被拒
- 0x06 TTL超时
- 0x07 不支持的命令
- 0x08 不支持的地址类型
- 0x09 0xFF未定义
BND.ADDR 服务器绑定的地址
BND.PORT 以网络字节顺序表示的服务器绑定的端口
5.当为UDP模式时,客户端会向代理服务器发送如下请求报文(UDP服务).
+----+------+------+----------+----------+----------+ |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | +----+------+------+----------+----------+----------+ | 2 | 1 | 1 | Variable | 2 | Variable | +----+------+------+----------+----------+----------+
字段意思参考上面.
DATA 表示 需要转发的数据
这个时候需要代理服务器拿到数据进行转发.
当收到返回数据后,需要同此格式返回给客户端。也就是替换DATA部分即可。
TCP BIND只会用在FTP的Active模式中(就是数据连接是由FTP服务连接回FTP客户),并不常用.没研究。