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. 参考

评论

此博客中的热门博文

gemini转发国内的部署教程

深度解析:Xray 核心技术 REALITY、Vision、xhttp 与 anytls 的协同工作原理

移动 IP 技术:如何在不同网络间无缝切换?