Socks5协议详解|
0. 什么是 Socks5
根据 Wiki :
SOCKS 是一种网络传输协议,名字取自 SOCKetS,主要用于客户端与外网服务器之间通讯的中间传递。
1. Socks5 协议的基本流程
1.1. 代理 TCP 链接( CMD = CONNECT )
1.1.0. TCP 链接
客户端与服务器建立 TCP 连接
1.1.1. 客户端确认版本与验证方法
客户端发送握手包,包含以下内容:
VER | NMETHODS | METHODS |
1 Byte | 1 Byte | 1~255 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
NMETHODS 代表客户端支持的认证方式的数量
METHODS 代表客户端支持的认证方式
0x00 不需要认证
0x01 GSSAPI 认证
0x02 用户名密码认证
0x03~0x7F IANA 分配
0x80~0xFE 私人方法保留
0xFF 无可接受方法
1.1.2. 服务器确认协议版本与验证方法
服务器返回握手包,包含以下内容:
VER | METHOD |
1 Byte | 1 Byte |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
METHOD 代表服务器选择的认证方式,选择内容应当是客户端发送的 METHODS 中的一种,如果客户端发送的 METHODS 中没有服务器支持的认证方式,服务器会返回 0xFF
1.1.3. (可选)客户端发送用户名密码
如果服务器选择的认证方式是 0x02,那么客户端需要发送用户名密码包,包含以下内容:
VER | ULEN | UNAME | PLEN | PASSWD |
1 Byte | 1 Byte | N Bytes | 1 Byte | N Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
ULEN 代表用户名的长度
UNAME 代表用户名
PLEN 代表密码的长度
PASSWD 代表密码(明文)
1.1.4. (可选)服务器确认用户名密码
选择了用户名密码认证的服务器在收到用户名密码包后,会返回以下内容:
VER | STATUS |
1 Byte | 1 Byte |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
STATUS 代表认证状态,其中:
0x00 代表认证成功
0x01 代表认证失败
1.1.5. 客户端发送连接请求包
客户端发送连接请求包,包含以下内容:
VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
1 Byte | 1 Byte | 1 Byte | 1 Byte | N Bytes | 2 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
CMD 代表请求类型,其中:
0x01 代表 CONNECT
0x02 代表 BIND
0x03 代表 UDP ASSOCIATE
这里需要代理 TCP,所以 CMD=CONNECT,即为 0x01
RSV 保留字段,值为 0x00
ATYP 代表请求的地址类型,其中:
0x01 代表 IPv4
0x03 代表域名
0x04 代表 IPv6
DST.ADDR 代表请求的地址,
如果 ATYP 为 IPv4,那么 DST.ADDR 为 4 Bytes 的 IPv4 地址
如果 ATYP 为 域名,那么 DST.ADDR 为 1~255 Bytes 的域名
此时 DST.ADDR 的第一个字节代表域名的长度
如果 ATYP 为 IPv6,那么 DST.ADDR 为 16 Bytes 的 IPv6 地址
DST.PORT 代表请求的端口
1.1.6. 服务器确认连接请求包
服务器在收到连接请求包后,会返回以下内容:
VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
1 Byte | 1 Byte | 1 Byte | 1 Byte | N Bytes | 2 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
REP 代表响应状态,其中:
0x00 代表成功
0x01 代表普通 SOCKS 服务器连接失败
0x02 代表现有规则不允许连接
0x03 代表网络不可达
0x04 代表主机不可达
0x05 代表连接被拒绝
0x06 代表 TTL 过期
0x07 代表不支持的命令
0x08 代表不支持的地址类型
0x09~0xFF 保留
RSV 保留字段,值为 0x00
ATYP 代表绑定的地址类型,其中:
0x01 代表 IPv4
0x03 代表域名
0x04 代表 IPv6
BND.ADDR 代表绑定的地址,
如果 ATYP 为 IPv4,那么 BND.ADDR 为 4 Bytes 的 IPv4 地址
如果 ATYP 为 域名,那么 BND.ADDR 为 1~255 Bytes 的域名
此时 BND.ADDR 的第一个字节代表域名的长度
如果 ATYP 为 IPv6,那么 BND.ADDR 为 16 Bytes 的 IPv6 地址
BND.PORT 代表绑定的端口
1.1.7. 客户端与服务器通讯
此时客户端或服务端发送到任意数据包都将由中转服务器转发
1.2. 代理 UDP 链接( CMD = UDP ASSOCIATE )
1.2.0. TCP 链接
客户端与服务器建立 TCP 连接
1.2.1. 客户端确认版本与验证方法
客户端发送握手包,包含以下内容:
VER | NMETHODS | METHODS |
1 Byte | 1 Byte | 1~255 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
NMETHODS 代表客户端支持的认证方式的数量
METHODS 代表客户端支持的认证方式
0x00 不需要认证
0x01 GSSAPI 认证
0x02 用户名密码认证
0x03~0x7F IANA 分配
0x80~0xFE 私人方法保留
0xFF 无可接受方法
1.2.2. 服务器确认协议版本与验证方法
服务器返回握手包,包含以下内容:
VER | METHOD |
1 Byte | 1 Byte |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
METHOD 代表服务器选择的认证方式,选择内容应当是客户端发送的 METHODS 中的一种,如果客户端发送的 METHODS 中没有服务器支持的认证方式,服务器会返回 0xFF
1.2.3. (可选)客户端发送用户名密码
如果服务器选择的认证方式是 0x02,那么客户端需要发送用户名密码包,包含以下内容:
VER | ULEN | UNAME | PLEN | PASSWD |
1 Byte | 1 Byte | N Bytes | 1 Byte | N Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
ULEN 代表用户名的长度
UNAME 代表用户名
PLEN 代表密码的长度
PASSWD 代表密码(明文)
1.2.4. (可选)服务器确认用户名密码
选择了用户名密码认证的服务器在收到用户名密码包后,会返回以下内容:
VER | STATUS |
1 Byte | 1 Byte |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
STATUS 代表认证状态,其中:
0x00 代表认证成功
0x01 代表认证失败
1.2.5. 客户端发送转发请求包
客户端发送连接请求包,包含以下内容:
VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
1 Byte | 1 Byte | 1 Byte | 1 Byte | N Bytes | 2 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
CMD 代表请求类型,其中:
0x01 代表 CONNECT
0x02 代表 BIND
0x03 代表 UDP ASSOCIATE
这里需要代理 UDP,所以 CMD=UDP ASSOCIATE,即为 0x03
RSV 保留字段,值为 0x00
ATYP 代表请求的地址类型,其中:
0x01 代表 IPv4
0x03 代表域名
0x04 代表 IPv6
注意: 与 CONNECT 不同的是,DST.ADDR 不再代表请求的地址,而是代表客户端期望发送 UDP 数据包的 Socket,也就是说,DST.ADDR 代表客户端的地址,DST.PORT 代表客户端的端口(用于发送 UDP 数据包的端口)
如果 ATYP 为 IPv4,那么 DST.ADDR 为 4 Bytes 的 IPv4 地址
如果 ATYP 为 域名,那么 DST.ADDR 为 1~255 Bytes 的域名
此时 DST.ADDR 的第一个字节代表域名的长度
如果 ATYP 为 IPv6,那么 DST.ADDR 为 16 Bytes 的 IPv6 地址
1.2.6. 服务器确认转发请求包
服务器在收到连接请求包后,会返回以下内容:
VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
1 Byte | 1 Byte | 1 Byte | 1 Byte | N Bytes | 2 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
REP 代表响应状态,其中:
0x00 代表成功
0x01 代表普通 SOCKS 服务器连接失败
0x02 代表现有规则不允许连接
0x03 代表网络不可达
0x04 代表主机不可达
0x05 代表连接被拒绝
0x06 代表 TTL 过期
0x07 代表不支持的命令
0x08 代表不支持的地址类型
0x09~0xFF 保留
RSV 保留字段,值为 0x00
ATYP 代表绑定的地址类型,其中:
0x01 代表 IPv4
0x03 代表域名
0x04 代表 IPv6
注意: 与 CONNECT 不同的是,这里的 BND.ADDR 代表服务器监听的 UDP 的地址,BND.PORT 代表服务器监听的 UDP 的端口,也就是说,BND.ADDR 代表服务器的地址,BND.PORT 代表服务器的端口(用于接收 UDP 数据包的端口)
如果 ATYP 为 IPv4,那么 BND.ADDR 为 4 Bytes 的 IPv4 地址
如果 ATYP 为 域名,那么 BND.ADDR 为 1~255 Bytes 的域名
此时 BND.ADDR 的第一个字节代表域名的长度
如果 ATYP 为 IPv6,那么 BND.ADDR 为 16 Bytes 的 IPv6 地址
1.2.7. 客户端断开 TCP 链接
根据规定,此时应由客户端断开 TCP 链接
1.2.8 客户端向服务器发送 UDP 数据包
客户端向服务器发送 UDP 数据包,UDP 数据包封装格式如下:
RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
2 Bytes | 1 Byte | 1 Byte | N Bytes | 2 Bytes | N Bytes |
RSV 保留字段,值为 0x0000
FRAG 代表分段,以下为定义:
0x00 代表不分段
0x01-0x7F 用于分段
注意,当最高位为 1 时,代表结束分段,即 0x80-0xFF 用于结束分段
例:当最后一个包为 0x85 时,代表这是第 5 个分段,且这是最后一个分段
注:应用应当尽可能避免分段
ATYP 代表请求的地址类型,其中:
0x01 代表 IPv4
0x03 代表域名
0x04 代表 IPv6
DST.ADDR 代表请求的地址,
如果 ATYP 为 IPv4,那么 DST.ADDR 为 4 Bytes 的 IPv4 地址
如果 ATYP 为 域名,那么 DST.ADDR 为 1~255 Bytes 的域名
此时 DST.ADDR 的第一个字节代表域名的长度
如果 ATYP 为 IPv6,那么 DST.ADDR 为 16 Bytes 的 IPv6 地址
DST.PORT 代表请求的端口
DATA 代表数据
中转服务器收到数据后,会将数据转发给目标服务器,然后将目标服务器的响应转发给客户端。
中转服务器返回数据时同样遵守上述格式。
1.3. 绑定命令( CMD = BIND )
这个命令使用的很少,几乎大部分客户端都不支持,根据 RFC 文档,这个命令可以使用在 FTP 传输数据。(FTP 都几乎没有人在使用了,因此这个命令使用很少)
BIND 代表客户端请求中转服务器开放一个端口,用于外部连接,即"穿透"效果。
1.3.0. TCP 链接
客户端与服务器建立 TCP 连接
1.3.1. 客户端确认版本与验证方法
客户端发送握手包,包含以下内容:
VER | NMETHODS | METHODS |
1 Byte | 1 Byte | 1~255 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
NMETHODS 代表客户端支持的认证方式的数量
METHODS 代表客户端支持的认证方式
0x00 不需要认证
0x01 GSSAPI 认证
0x02 用户名密码认证
0x03~0x7F IANA 分配
0x80~0xFE 私人方法保留
0xFF 无可接受方法
1.3.2. 服务器确认协议版本与验证方法
服务器返回握手包,包含以下内容:
VER | METHOD |
1 Byte | 1 Byte |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
METHOD 代表服务器选择的认证方式,选择内容应当是客户端发送的 METHODS 中的一种,如果客户端发送的 METHODS 中没有服务器支持的认证方式,服务器会返回 0xFF
1.3.3. (可选)客户端发送用户名密码
如果服务器选择的认证方式是 0x02,那么客户端需要发送用户名密码包,包含以下内容:
VER | ULEN | UNAME | PLEN | PASSWD |
1 Byte | 1 Byte | N Bytes | 1 Byte | N Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
ULEN 代表用户名的长度
UNAME 代表用户名
PLEN 代表密码的长度
PASSWD 代表密码
1.3.4. (可选)服务器确认用户名密码
选择了用户名密码认证的服务器在收到用户名密码包后,会返回以下内容:
VER | STATUS |
1 Byte | 1 Byte |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
STATUS 代表认证状态,其中:
0x00 代表认证成功
0x01 代表认证失败
1.3.5. 客户端发送请求包
客户端发送连接请求包,包含以下内容:
VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
1 Byte | 1 Byte | 1 Byte | 1 Byte | N Bytes | 2 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
CMD 代表请求类型,其中:
0x01 代表 CONNECT
0x02 代表 BIND
0x03 代表 UDP ASSOCIATE
此处需要绑定,所以 CMD=BIND,即为 0x02
RSV 保留字段,值为 0x00
ATYP 代表请求的地址类型,其中:
0x01 代表 IPv4
0x03 代表域名
0x04 代表 IPv6
DST.ADDR 和 DST.PORT 代表可能的外部来源地址和端口(外部客户端/服务器尝试连接 Socks 服务器时外部客户端/服务器使用的地址与端口)。
如果 ATYP 为 IPv4,那么 DST.ADDR 为 4 Bytes 的 IPv4 地址
如果 ATYP 为 域名,那么 DST.ADDR 为 1~255 Bytes 的域名
此时 DST.ADDR 的第一个字节代表域名的长度
如果 ATYP 为 IPv6,那么 DST.ADDR 为 16 Bytes 的 IPv6 地址
1.3.6. 服务器确认绑定地址
服务器在收到连接请求包后,会返回以下内容:
VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
1 Byte | 1 Byte | 1 Byte | 1 Byte | N Bytes | 2 Bytes |
VER 代表 Socks 的版本,Socks5 服务器会返回 0x05
REP 代表响应状态,其中:
0x00 代表成功
0x01 代表普通 SOCKS 服务器连接失败
0x02 代表现有规则不允许连接
0x03 代表网络不可达
0x04 代表主机不可达
0x05 代表连接被拒绝
0x06 代表 TTL 过期
0x07 代表不支持的命令
0x08 代表不支持的地址类型
0x09~0xFF 保留
RSV 保留字段,值为 0x00
ATYP 代表绑定的地址类型,其中:
0x01 代表 IPv4
0x03 代表域名
0x04 代表 IPv6
BIND.ADDR 和 BIND.PORT 代表中转服务器绑定的地址和端口,即"穿透"后的地址和端口,共外部客户端/服务器连接。
如果 ATYP 为 IPv4,那么 BND.ADDR 为 4 Bytes 的 IPv4 地址
如果 ATYP 为 域名,那么 BND.ADDR 为 1~255 Bytes 的域名
此时 BND.ADDR 的第一个字节代表域名的长度
如果 ATYP 为 IPv6,那么 BND.ADDR 为 16 Bytes 的 IPv6 地址
1.3.7. 服务器通知外部链接包
当外部客户端/服务器连接中转服务器时,中转服务器会向客户端发送以下内容:
VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
1 Byte | 1 Byte | 1 Byte | 1 Byte | N Bytes | 2 Bytes |
详细定义同上,但是 BIND.ADDR 和 BIND.PORT 代表外部客户端/服务器的地址和端口。
1.3.8. 客户端与服务器通讯
此时客户端或服务端发送到任意数据包都将由中转服务器转发
2. 参考
评论
发表评论