searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

SOCKS5代理协议原理详解

2023-07-28 01:54:28
1017
0

SOCKS协议是一种网络代理协议,用于客户端与服务器之间的中间流量转发,目前协议的最新版本是SOCKS5。SOCKS协议支持对客户端TCP流量的转发,SOCKS5版本中还增加支持了对UDP流量的转发。SOCKS协议工作于OSI七层网络协议栈模型中的第五层(会话层)。SOCKS5代理服务器默认监听TCP 1080端口来接收客户端的TCP流量,对于UDP流量代理,SOCKS5代理服务器需额外使用一个临时的UDP端口来转发客户端的UDP流量。

关于SOCKS5协议的内容可参考IETF RFC1928官方文档。

1. SOCKS5代理的应用场景

(1)SOCKS5代理通常可用于访问某些无法直接访问的网站,以及帮助用户隐藏真实IP来访问可能存在安全隐患的内容。

通常我们访问网站的过程如下图所示,先访问本地配置的DNS服务器,解析域名获取目标服务器的IP地址,然后直接连接该IP地址,在连接中可能会出现连接超时、连接被拒绝等错误导致我们无法成功访问网站。

如果客户端到SOCKS5代理服务器,以及代理服务器到目标服务器都能连通,我们就能借助SOCKS5代理服务器作为中转,从而成功访问网站,如下图所示。由于实际上直接连接到目标服务器的是代理服务器而非我们的客户端,因此目标服务器得到的“客户端IP地址”为代理服务器的IP地址,而非我们的真实IP地址,从而实现了真实IP地址的隐藏。

但有时,直接访问网站失败的原因却在于DNS污染,即我们的客户端一开始就从本地DNS服务器获取到了错误的、不可访问的IP地址,这种情况下即使通过代理服务器也无法成功访问。SOCKS5代理协议还支持将目标访问地址设置成域名,让代理服务器解析并访问正确的IP地址,从而应对本地DNS污染的情况,如下图所示。

(2)SOCKS5代理还可用于开发VPN等全局网络流量代理工具。

由于SOCKS5代理的是TCP和UDP流量,与具体的应用层协议无关,因此SOCKS5可以实现对任何应用层协议流量(如HTTP(S)、FTP、DNS等协议流量)的透明代理,适合用来开发VPN等全局网络流量代理工具,免去用户手动配置代理的麻烦。

由于SOCKS5代理协议只是单纯转发TCP、UDP流量,不关心应用层协议的具体内容,也不会对应用层流量进行任何修改,因此SOCKS5协议无法保证本身不安全的应用层流量(例如明文的HTTP流量)的安全传输。要保证安全传输,还得依靠客户端与服务器双方在应用层协议中来保证安全。

2. SOCKS5代理的建立过程与协议格式

SOCKS5协议中的所有字段均采用网络字节序(大端序)编码。

(1)TCP代理的建立过程

对于客户端的每一条TCP连接,都需要按如下图所示的流程与SOCKS5代理服务器建立一条对应的SOCKS5连接进行代理。

整个代理建立过程分为3个阶段:握手协商请求与回复、命令请求与回复、应用层数据传输。

① 握手协商请求与回复

在1.1-握手协商请求中,协议格式与字段如下所示:

                   +----+----------+----------+
                   |VER | NMETHODS | METHODS  |
                   +----+----------+----------+
                   | 1  |    1     | 1 to 255 |
                   +----+----------+----------+
  • VER:1字节,版本号,固定为0x05,代表使用SOCKS5协议
  • NMETHODS:1字节,表示客户端支持的认证方法数
  • METHOD:认证方法编号列表,长度为NMETHODS的值所表示的字节数,因为NMETHODS只有1字节,合法取值范围为1-255,故该字段的长度也为1-255字节。列表内的每一个字节均表示客户端具体支持的认证方法编号,可取的编号值为:
    • 0x00:不需要认证
    • 0x01:GSSAPI
    • 0x02:用户名和密码
    • 0x03 - 0x7F:预留给IANA定义新的标准认证方法
    • 0x80 - 0xFE:预留给私有自定义的认证方法

在1.2-握手协商回复中,协议格式与字段如下所示:

                         +----+--------+
                         |VER | METHOD |
                         +----+--------+
                         | 1  |   1    |
                         +----+--------+
  • VER:1字节,版本号,固定为0x05
  • METHOD:1字节,服务端从客户端的协商握手请求中选择的认证方式编号。如果所有认证方式都不能使用,该字段值为0xFF,客户端收到此回复后必须立即断开连接。

如果服务端选择的认证方法非0x00(不需要认证),则双方后续还需进入额外的阶段进行认证交互。

② 握手协商请求与回复

在2.1-命令请求中,协议格式与字段如下所示:

        +----+-----+-------+------+----------+----------+
        |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+
  • VER:1字节,版本号,固定为0x05
  • CMD:1字节,命令编号,取值为:
    • 0x01:CONNECT,用于TCP流量代理
    • 0x02:BIND,可用于代理客户端的某个监听端口来接受外部的主动连接。
    • 0x03:UDP ASSOCIATE,用于UDP流量代理对于TCP流量代理,该字段取值必须为0x01。
  • RSV:1字节,保留字段,必须为0x00。
  • ATYP、DST.ADDR、DST.PORT:在TCP流量代理中,表示要连接到的目标服务器地址。

在SOCKS5协议中,采用三个字段ATYP、XXX.ADDR、XXX.PORT来表示地址,目前支持IPv4、IPv6与域名三种类型的地址:

  • ATYP:1字节,表示地址类型:
    • 0x01:IPv4,此时XXX.ADDR为4字节的IPv4地址。
    • 0x04:IPv6,此时XXX.ADDR为16字节的IPv6地址。
    • 0x03:域名,此时XXX.ADDR中第一个字节表示域名字符串的长度,后面接域名字符串(不包括最后的\0终止符)。例如域名www.example.com的表示方法为:第一个字节值为15(0x0F),后面的15个字节内容为www.example.com。
  • XXX.PORT:2字节,端口号。

SOCKS5代理服务器在收到命令请求后,向指定的目标服务器地址发起TCP连接,无论连接成功与否,最终都需要给客户端发送命令回复消息。

在2.2-命令回复中,协议格式与字段如下所示:

        +----+-----+-------+------+----------+----------+
        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+
  • VER:1字节,版本号,固定为0x05。
  • REP:1字节,命令请求的结果码,取值有:
    • 0x00:成功
    • 0x01:通用的SOCKS服务失败的错误码
    • 0x02:规则中不允许连接
    • 0x03:网络不可达
    • 0x04:目标主机不可达
    • 0x05:连接被拒绝
    • 0x06:TTL过期
    • 0x07:命令请求不支持
    • 0x08:地址类型不支持
    • 0x09 - 0xFF:保留
  • RSV:1字节,保留字段,必须为0x00。
  • ATYP、BND.ADDR、BND.PORT:服务端绑定的地址,对于TCP流量代理无意义,忽略即可。

若REP字段值非0x00,均表示命令请求失败,此时客户端应立即断开连接。

③ 应用层数据传输

当命令请求成功后,客户端到目标服务器的代理通道就已经建立完成,双方可以自由传输数据了。后续SOCKS5代理服务器只是简单地转发上下行应用层的原始数据,客户端与SOCKS5代理服务器的数据交互也都是原始的应用层数据,没有额外的SOCKS协议头部。当客户端与SOCKS5代理服务器的连接断开后,SOCKS5代理服务器也会立即断开与目标服务器的连接;反之类似。

(2)UDP代理的建立过程

客户端每绑定一个本地UDP端口后,都需要按如下图所示的流程与SOCKS5代理服务器建立一条对应的SOCKS5连接,然后使用SOCKS5代理服务器临时分配的一个UDP代理服务器地址进行UDP报文的转发。

与TCP代理的建立过程类似,UDP代理的建立过程也分为3个阶段,且前2个阶段与TCP代理基本一致,不同点有:

  • 在2.1-命令请求中,CMD字段的值为0x03(UDP ASSOCIATE),目标服务器地址可以是无意义的地址(如0.0.0.0:0),也可以是后续要访问的实际地址。目标服务器地址在这里仅作为代理服务器是否接受请求的依据。
  • 代理服务器在接收到命令请求后,需要分配一个对应的临时UDP代理服务器,这可以通过在代理服务器上随机绑定一个UDP端口实现。
  • 在2.2-命令回复中,绑定地址即为临时UDP代理服务器的地址。

在命令请求成功后,客户端就可以通过临时UDP代理服务器将UDP报文转发给任意目标服务器;同理,UDP代理服务器也可以从任意服务器接收UDP报文并转发给客户端。由于UDP代理需要支持多个目标服务器流量的转发,因此客户端与UDP代理服务器的报文交互中,除了原始的应用层报文内容外,还含有额外的SOCKS5头部,头部格式如下:

      +----+------+------+----------+----------+----------+
      |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
      +----+------+------+----------+----------+----------+
      | 2  |  1   |  1   | Variable |    2     | Variable |
      +----+------+------+----------+----------+----------+
  • RSV:2字节,保留字段,必须都为0x00。
  • FRAG:1字节,报文的分段序列号,0表示不支持分段;1-127表示具体的分段序列号,最高比特位置1(即>127)时表示该分段为整个报文的最后一段。类似于IPv4协议,SOCKS5协议允许对UDP报文进行分段传输,由报文接收方根据序列号重组成完整的报文。分段为可选功能,若客户端或UDP代理服务器未实现此功能都会导致报文直接被丢弃,因此,为保证通用性,应尽可能避免分段。
  • ATYP、DST.ADDR、DST.PORT:对于上行报文为目标服务器地址、对于下行报文为源服务器地址。
  • DATA:整个报文的剩余部分,即原始的应用层报文内容。

在整个UDP报文的代理传输过程中,客户端需要注意保持与SOCKS5代理服务器的连接,当连接断开时,临时分配的UDP代理服务器也会被立即释放,无法再转发任何UDP报文。

0条评论
0 / 1000
s****u
2文章数
0粉丝数
s****u
2 文章 | 0 粉丝
s****u
2文章数
0粉丝数
s****u
2 文章 | 0 粉丝
原创

SOCKS5代理协议原理详解

2023-07-28 01:54:28
1017
0

SOCKS协议是一种网络代理协议,用于客户端与服务器之间的中间流量转发,目前协议的最新版本是SOCKS5。SOCKS协议支持对客户端TCP流量的转发,SOCKS5版本中还增加支持了对UDP流量的转发。SOCKS协议工作于OSI七层网络协议栈模型中的第五层(会话层)。SOCKS5代理服务器默认监听TCP 1080端口来接收客户端的TCP流量,对于UDP流量代理,SOCKS5代理服务器需额外使用一个临时的UDP端口来转发客户端的UDP流量。

关于SOCKS5协议的内容可参考IETF RFC1928官方文档。

1. SOCKS5代理的应用场景

(1)SOCKS5代理通常可用于访问某些无法直接访问的网站,以及帮助用户隐藏真实IP来访问可能存在安全隐患的内容。

通常我们访问网站的过程如下图所示,先访问本地配置的DNS服务器,解析域名获取目标服务器的IP地址,然后直接连接该IP地址,在连接中可能会出现连接超时、连接被拒绝等错误导致我们无法成功访问网站。

如果客户端到SOCKS5代理服务器,以及代理服务器到目标服务器都能连通,我们就能借助SOCKS5代理服务器作为中转,从而成功访问网站,如下图所示。由于实际上直接连接到目标服务器的是代理服务器而非我们的客户端,因此目标服务器得到的“客户端IP地址”为代理服务器的IP地址,而非我们的真实IP地址,从而实现了真实IP地址的隐藏。

但有时,直接访问网站失败的原因却在于DNS污染,即我们的客户端一开始就从本地DNS服务器获取到了错误的、不可访问的IP地址,这种情况下即使通过代理服务器也无法成功访问。SOCKS5代理协议还支持将目标访问地址设置成域名,让代理服务器解析并访问正确的IP地址,从而应对本地DNS污染的情况,如下图所示。

(2)SOCKS5代理还可用于开发VPN等全局网络流量代理工具。

由于SOCKS5代理的是TCP和UDP流量,与具体的应用层协议无关,因此SOCKS5可以实现对任何应用层协议流量(如HTTP(S)、FTP、DNS等协议流量)的透明代理,适合用来开发VPN等全局网络流量代理工具,免去用户手动配置代理的麻烦。

由于SOCKS5代理协议只是单纯转发TCP、UDP流量,不关心应用层协议的具体内容,也不会对应用层流量进行任何修改,因此SOCKS5协议无法保证本身不安全的应用层流量(例如明文的HTTP流量)的安全传输。要保证安全传输,还得依靠客户端与服务器双方在应用层协议中来保证安全。

2. SOCKS5代理的建立过程与协议格式

SOCKS5协议中的所有字段均采用网络字节序(大端序)编码。

(1)TCP代理的建立过程

对于客户端的每一条TCP连接,都需要按如下图所示的流程与SOCKS5代理服务器建立一条对应的SOCKS5连接进行代理。

整个代理建立过程分为3个阶段:握手协商请求与回复、命令请求与回复、应用层数据传输。

① 握手协商请求与回复

在1.1-握手协商请求中,协议格式与字段如下所示:

                   +----+----------+----------+
                   |VER | NMETHODS | METHODS  |
                   +----+----------+----------+
                   | 1  |    1     | 1 to 255 |
                   +----+----------+----------+
  • VER:1字节,版本号,固定为0x05,代表使用SOCKS5协议
  • NMETHODS:1字节,表示客户端支持的认证方法数
  • METHOD:认证方法编号列表,长度为NMETHODS的值所表示的字节数,因为NMETHODS只有1字节,合法取值范围为1-255,故该字段的长度也为1-255字节。列表内的每一个字节均表示客户端具体支持的认证方法编号,可取的编号值为:
    • 0x00:不需要认证
    • 0x01:GSSAPI
    • 0x02:用户名和密码
    • 0x03 - 0x7F:预留给IANA定义新的标准认证方法
    • 0x80 - 0xFE:预留给私有自定义的认证方法

在1.2-握手协商回复中,协议格式与字段如下所示:

                         +----+--------+
                         |VER | METHOD |
                         +----+--------+
                         | 1  |   1    |
                         +----+--------+
  • VER:1字节,版本号,固定为0x05
  • METHOD:1字节,服务端从客户端的协商握手请求中选择的认证方式编号。如果所有认证方式都不能使用,该字段值为0xFF,客户端收到此回复后必须立即断开连接。

如果服务端选择的认证方法非0x00(不需要认证),则双方后续还需进入额外的阶段进行认证交互。

② 握手协商请求与回复

在2.1-命令请求中,协议格式与字段如下所示:

        +----+-----+-------+------+----------+----------+
        |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+
  • VER:1字节,版本号,固定为0x05
  • CMD:1字节,命令编号,取值为:
    • 0x01:CONNECT,用于TCP流量代理
    • 0x02:BIND,可用于代理客户端的某个监听端口来接受外部的主动连接。
    • 0x03:UDP ASSOCIATE,用于UDP流量代理对于TCP流量代理,该字段取值必须为0x01。
  • RSV:1字节,保留字段,必须为0x00。
  • ATYP、DST.ADDR、DST.PORT:在TCP流量代理中,表示要连接到的目标服务器地址。

在SOCKS5协议中,采用三个字段ATYP、XXX.ADDR、XXX.PORT来表示地址,目前支持IPv4、IPv6与域名三种类型的地址:

  • ATYP:1字节,表示地址类型:
    • 0x01:IPv4,此时XXX.ADDR为4字节的IPv4地址。
    • 0x04:IPv6,此时XXX.ADDR为16字节的IPv6地址。
    • 0x03:域名,此时XXX.ADDR中第一个字节表示域名字符串的长度,后面接域名字符串(不包括最后的\0终止符)。例如域名www.example.com的表示方法为:第一个字节值为15(0x0F),后面的15个字节内容为www.example.com。
  • XXX.PORT:2字节,端口号。

SOCKS5代理服务器在收到命令请求后,向指定的目标服务器地址发起TCP连接,无论连接成功与否,最终都需要给客户端发送命令回复消息。

在2.2-命令回复中,协议格式与字段如下所示:

        +----+-----+-------+------+----------+----------+
        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+
  • VER:1字节,版本号,固定为0x05。
  • REP:1字节,命令请求的结果码,取值有:
    • 0x00:成功
    • 0x01:通用的SOCKS服务失败的错误码
    • 0x02:规则中不允许连接
    • 0x03:网络不可达
    • 0x04:目标主机不可达
    • 0x05:连接被拒绝
    • 0x06:TTL过期
    • 0x07:命令请求不支持
    • 0x08:地址类型不支持
    • 0x09 - 0xFF:保留
  • RSV:1字节,保留字段,必须为0x00。
  • ATYP、BND.ADDR、BND.PORT:服务端绑定的地址,对于TCP流量代理无意义,忽略即可。

若REP字段值非0x00,均表示命令请求失败,此时客户端应立即断开连接。

③ 应用层数据传输

当命令请求成功后,客户端到目标服务器的代理通道就已经建立完成,双方可以自由传输数据了。后续SOCKS5代理服务器只是简单地转发上下行应用层的原始数据,客户端与SOCKS5代理服务器的数据交互也都是原始的应用层数据,没有额外的SOCKS协议头部。当客户端与SOCKS5代理服务器的连接断开后,SOCKS5代理服务器也会立即断开与目标服务器的连接;反之类似。

(2)UDP代理的建立过程

客户端每绑定一个本地UDP端口后,都需要按如下图所示的流程与SOCKS5代理服务器建立一条对应的SOCKS5连接,然后使用SOCKS5代理服务器临时分配的一个UDP代理服务器地址进行UDP报文的转发。

与TCP代理的建立过程类似,UDP代理的建立过程也分为3个阶段,且前2个阶段与TCP代理基本一致,不同点有:

  • 在2.1-命令请求中,CMD字段的值为0x03(UDP ASSOCIATE),目标服务器地址可以是无意义的地址(如0.0.0.0:0),也可以是后续要访问的实际地址。目标服务器地址在这里仅作为代理服务器是否接受请求的依据。
  • 代理服务器在接收到命令请求后,需要分配一个对应的临时UDP代理服务器,这可以通过在代理服务器上随机绑定一个UDP端口实现。
  • 在2.2-命令回复中,绑定地址即为临时UDP代理服务器的地址。

在命令请求成功后,客户端就可以通过临时UDP代理服务器将UDP报文转发给任意目标服务器;同理,UDP代理服务器也可以从任意服务器接收UDP报文并转发给客户端。由于UDP代理需要支持多个目标服务器流量的转发,因此客户端与UDP代理服务器的报文交互中,除了原始的应用层报文内容外,还含有额外的SOCKS5头部,头部格式如下:

      +----+------+------+----------+----------+----------+
      |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
      +----+------+------+----------+----------+----------+
      | 2  |  1   |  1   | Variable |    2     | Variable |
      +----+------+------+----------+----------+----------+
  • RSV:2字节,保留字段,必须都为0x00。
  • FRAG:1字节,报文的分段序列号,0表示不支持分段;1-127表示具体的分段序列号,最高比特位置1(即>127)时表示该分段为整个报文的最后一段。类似于IPv4协议,SOCKS5协议允许对UDP报文进行分段传输,由报文接收方根据序列号重组成完整的报文。分段为可选功能,若客户端或UDP代理服务器未实现此功能都会导致报文直接被丢弃,因此,为保证通用性,应尽可能避免分段。
  • ATYP、DST.ADDR、DST.PORT:对于上行报文为目标服务器地址、对于下行报文为源服务器地址。
  • DATA:整个报文的剩余部分,即原始的应用层报文内容。

在整个UDP报文的代理传输过程中,客户端需要注意保持与SOCKS5代理服务器的连接,当连接断开时,临时分配的UDP代理服务器也会被立即释放,无法再转发任何UDP报文。

文章来自个人专栏
网络协议与编程
1 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0