Socks5代理分析
概述
项目中遇到了socks5代理环境下UDP不通的问题,在解决问题的过程中,也学习了socks5到底是如何通信的,下面就原理、客户端、服务器三个方面来详细说一下。
原理
使用场景
有一部分企业,出于安全考虑或者某些原因,员工的上网环境必须走代理,通常服务器会被配置成一个HTTP代理,但是HTTP是基于TCP的,走UDP的数据则不行,所以,像直播或者视频都不行,为了解决这些问题,我们可以将服务器配置成socks5代理,这样就能满足我们的需求。
首先,我们要知道什么是代理,其实代理就是帮你干活的。例如跑腿,你想到楼下的便利店买包烟,但是你的腿被别人打断了,不能下楼,这时,你叫了一个跑腿的,告诉他到楼下的便利店买包烟,他买完以后,又给你送到楼上,你就开始愉快的抽烟。这就是一个完整的代理过程。
认证
通常,socks5代理服务器都会配置在1080端口,他是基于TCP的,客户端要连接到代理服务器,首先要经过三次握手,之后需要和服务器进行认证,格式如下:
|
- VER 字段是当前协议的版本号,也就是5
- NMETHODS 字段是代表客户端支持的认证方式的个数
- METHODS 字段代表客户端支持的认证方式,每一位字节表示一种认证方式。
服务器在客户端发送的认证方式中选择一种进行匹配,返回数据如下:
|
- METHOD 即为服务器端匹配的结果,如果服务器返回的是OxFF,则表明客户端所支持的认证方式,服务器端都不支持。那么认证失败。
认证方式有如下几种:
|
下面通过WireShark分析socks5认证过程:
首先,客户端和服务器的三次握手建立连接,之后,客户端发送认证请求,我们可以看到,客户端发送的数据为:
- VER:05 即版本为5
- NMETHODS:02 即支持两种认证方式
- METHODS: 00 02 两种认证方式分别为 无须认证和用户名密码认证
服务器回的数据为:
- VER:05 即版本为5
- METHODS:00 即和客户端商议使用无须认证方式
当然,这里我配置的代理服务器没有使用用户名密码认证方式,假如需要此种方式的认证,客户端还需要发送用户名密码进行认证,有兴趣的同学可以试试。
连接
认证通过以后,客户端就需要告诉代理,需要它做什么,即需要给代理发命令,具体的格式如下:
|
- VER: 协议版本
- CMD: 命令,有三种命令:
|
- RSV: 保留字段,值为 0x00
- ATYP: 地址类型,取值为:
|
- DST.ADDR 目的地,取值随ATYP的类型不同而不同,如下:
|
- DST.PORT 目的地端口
服务器返回的数据如下:
|
- VER: 版本号
- REP: 服务器返回的结果
|
- RSV 保留字段
- ATYP: 地址类型
- BND.ADDR: 服务器地址
- BND.PORT: 服务器端口
CMD
CONNECT
CONNECT表示要和目的主机建立TCP连接,在服务器回应中,BND.ADDR包含了关联的IP地址。此处所提供的BND.ADDR通常情况下不同于客户端连接到socks5代理服务器的IP地址,因为有可能代理服务器是一个集群,当然我这里只是一个服务器,所以返回的和代理的IP一样,BND.PORT表示服务器分配的连接到目标主机的端口号,即代理服务器接下来会使用BND.PORT这个端口与目标主机进行TCP通信。
BIND
BIND请求被用在那些需要客户机接收到服务器连接的协议中。FTP就是一个众所周知的例子。在实际应用场景中,一般用不到,这里不再细说。
UDP ASSOCIATE
此命令表示需要进行UDP转发,BND.ADDR和CONNECT中的含义一样,而BND.PORT表示服务器提供给客户端的UDP转发端口,接下来客户端的所有UDP都需要往代理的此端口发送。
因为我这次遇到的主要是UDP转发的问题,那么接下就着重分析一下UDP ASSOCIATE。
UDP ASSOCIATE
当客户端发送UDP ASSOCIATE命名时,代理服务器会返回相应的断端口,如下:
服务器响应如下:
那么,客户端知道服务器地址以后,是如何发送到代理服务器呢?
一个UDP数据报如下:
|
- RSV 占两个字节 即 0x0000
- FRAG Current fragment number
- ATYP 目的地址类型
- DST.ADDR 目的地址
- DST.PORT 目的端口
- DATA 真正的数据
如此,客户端开始不断的发送UDP数据到代理服务器,代理服务器接收到数据后,又会如何呢?
我们可以看到,客户端与代理之间的数据要比代理与目的主机之间的数据大10个字节,而这10个字节正是socks5协议头。
完整的UDP转发流程为:
现在,大家是不是对socks5有了一个全面的认识呢!
配置
客户端
一般情况下,类似于QQ支持socks5代理配置,但是大部分应用并不支持socks5代理,这时候我们可以使用一些代理工具,这里使用SocksCap64这个工具,他会使你的应用支持socks5协议。但是它只支持Windows,在Mac下你可以在网络上搜索其他的全局代理软件。
服务器
服务器可以使用dante软件。
- 安装Dante
从源码安装
|
- 配置
dante的默认配置文件时/etc/sockd.conf。具体的配置为:
|
- 启动
|
注意:当Socks5协议不使用1080端口时,WireShark是识别不出Socks5代理的,WireShark会将Socks5协议直接识别成TCP或者UDP。这点要注意。
关于更详细的配置,请参考dante官网dante