首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SOCKS5代理是怎样工作的

SOCKS5代理是怎样工作的

作者头像
YaoQi
发布2025-07-14 19:06:54
发布2025-07-14 19:06:54
40200
代码可运行
举报
运行总次数:0
代码可运行

SOCKS Protocol Version 5是对Version 4的扩展。主要增加了安全认证,UDP和IPv6的支持。

SOCKS5 协议在概念上属于应用层(application layer)和传输层(transport layer)之间的垫片层(shim-layer),或者说它属于会话层。所以它不能代理网络层的协议,比如ICMP等;能代理应用层基于TCP,UDP的协议,比如 HTTP、SSH、FTP等。

应用程序使用SOCKS5代理,需要重新编写程序,支持将直接和目标服务器建立的连接文件描述符,替换成通过SOCKS5建立的连接文件描述符。

下文先描述下SOCKS5协议内容,然后举几个例子,期望能对读者有帮助。

SOCKS5协议内容

代理服务器侦听TCP 1080端口(SOCKS默认端口), 客户端向其建立连接。之后的通信要符合协议规定。

首先,客户端发送版本/模式选择消息,告诉代理服务器自己支持的认证模式:

图片
图片
  1. VER:协议版本号,SOCKS5固定为0x05; NMETHODS是后边METHONS的数量; METHODS部分,一个字节代表一个模式,模式见下文; 然后,代理服务器端回复,选中的数据传输模式:

VER:版本号,SOCKS5固定为0x05; METHOD就一个,服务器选择的之后要用的模式:            0x00 不需要验证            0x01 通用安全服务应用程序接口(GSSAPI)             0x02 用户名密码验证            0x03 至 0x7f 互联网数字分配机构(IANA)定义的方式            0x80 至 0xfe 保留给私有方式使用的            0xff 没有可用的模式 之后,客户端使用刚才协商的模式进行验证身份等,并且有些模式可能 需要对数据进行特定的封装,之后的交互可能是经过特定封装的。 具体验证封装细节此处省略。 然后,客户端向服务器发代理请求: (之后表格中的数字默认是字节数,或者固定值,或者长度可变)

VER:版本号,SOCKS5固定0x05 CMD:后文会详细介绍三者的示例      连接(CONNECT) 0x01   主动连接目标服务器     绑定(BIND) 0x02  绑定一个地址,目标服务器反向连接过来(FTP的主动模式)     UDP关联(UDP ASSOCIATE) 0x03 RSV:保留字段(RESERVED) ATYP:地址类型选择       IPv4: 0x01,长度4字节       域名: 0x03,长度由ADDR的第一个字节指定       IPv6: 0x04,长度16字节 DST.ADDR:  期望的地址,长度由ATYPE类型决定,详见下文 DST.PORT:期望的端口,详见下文

DST.ADDR和DST.PORT根据CMD的不同有不同的意义:

对于CONNECT命令,它们代表要连接的目标服务器的地址和端口;

对于BIND命令,代理服务器侦听一个地址,等待目标服务器连接过来(FTP的主动模式),ADDR和PORT是指定目标服务器连接过来时使用的地址和端口,代理服务器校验使用。

对于UDP关联命令,这两个值是指客户端即将使用的和代理服务器通信的地址和端口。也是代理服务器校验用,不需要校验可以填0。

有点绕,下文的具体示例会有所体现。

再之后,代理服务器返回对应的连接建立情况:

图片
图片
代码语言:javascript
代码运行次数:0
运行
复制
VER:版本号,SOCKS5固定为 0x05
REP:  响应内容:
             o  0x00 成功
             o  0x01 普通的SOCKS服务失败
             o  0x02 连接不被规则允许
             o  0x03 网络不可达
             o  0x04 主机不可达
             o  0x05 连接被拒绝
             o  0x06 连接超时
             o  0x07 命令不支持
             o  0x08 地址类型不支持
             o  0x09 至 0xff 未定义
RSV:保留字段 固定 0x00ATYP:地址类型选择
      IPv4: 0x01,长度4字节
      域名: 0x03,长度由ADDR的第一个字节指定
      IPv6: 0x04,长度16字节
代码语言:javascript
代码运行次数:0
运行
复制
BND.ADDR:代理服务器绑定的地址
BND.PORT:代理服务器绑定的端口

同样,BND.ADDR和BND.PORT的意义也依赖请求的CMD命令:

对于CONNECT命令,这俩代表了代理服务器连接目标服务器使用的本地地址;

对于BIND命令,代理服务器会返回两条消息,第一条消息,告诉客户端我侦听好地址了,侦听的地址是什么。第二条消息,告诉客户端目标服务器连上来了,它的地址是什么。

对于UDP关联命令,告诉客户端代理服务器侦听的UDP端口是什么,之后客户端向此地址发送代理请求。

对于TCP代理,之后只需要在对应连接上传数据就行了。

但如果是UDP代理,那么客户端还需要封装特定的UDP格式,主要就是UDP没有连接概念,每个数据包的代理都要带上一个UDP代理头,表明目标服务器的地址。

图片
图片

RSV 保留位 固定0x0000

FRAG    分段编号

ATYP    地址类型,和上文一样:

          IPv4: 0x01,长度4字节

          域名: 0x03,长度由ADDR的第一个字节指定

          IPv6: 0x04,长度16字节

DST.ADDR     目标服务器地址

DST.PORT      目标服务器端口

DATA    用户数据

当目标服务器返回数据时,代理服务器是否会加上UDP头我不太清楚,有文章说也会带,客户端还要剥离这个头才能取得数据,我觉得不带更好,后边示例先按返回数据不封装代理头描述。

TCP代理示例:

图片
图片

FTP代理示例:

被动模式下,两个连接都是客户端连接服务器,所以直接使用两次TCP代理模式即可。

下边是主动模式下,使用BIND命令反向连接:

首先建立发送命令的连接:

图片
图片

建立反向连接,发送数据:

UDP代理示例:

UDP代理,首先也是和代理服务器建立TCP连接,沟通建立UDP通道。之后在UDP通道代理UDP数据,这个TCP连接如果被关闭,UDP通道也会被关闭。如果代理服务器支持,可以用一个TCP连接,创建多个UDP通道。

下边就是UDP数据包的代理过程

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 漫跑的小兔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档