Socks4(a)\5协议

传统的网络是一个C\S架构,相当于直连接网络

image-20200618170723322

有一天,网络服务提供商为了限制使用者访问某些互联网服务,于是设置了一堵墙,只有符合规则的网络传输才允许通过。目前全球最大,最厉害的是GFW,但是也做不到完全限制墙外访问,于是有人就找了台墙外主机,作为代理,所有墙内请求都需经过该主机经转发后访问具体目标,这样就可以在墙外轻松享受服务。

image-20200618171313651

Socks协议至此衍生出来。

Socks是会话层的协议,位于表示层与传输层之间。目前有两个版本的协议。

Socks4(a)

主要有以下几个RFC标准:

http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol
http://www.rfc-editor.org/rfc/rfc1928.txt
http://www.smartftp.com/Products/SmartFTP/RFC/socks4a.protocol

流程

  1. 发送请求报文,报文结构如下所示,由五段组成,数字代表占用字节数

    • VER 版本号:固定是 0x04
    • CMD 说明此次需要执行什么操作
    • PORT 告诉代理我需要访问的墙外资源的端口
    • IP 告诉代理需要访问的墙外资源的IP
    • USERID 一个标识ID,用于代理验证合法性的请求,可选项
    • NULL 结束符占用一个字节

image-20200618171334213

  1. 服务端接收到请求,响应报文如下,其中PORTIP可填充0,在某些客户端中不能去掉这两项参数,长度需要为8字节。响应之后服务端与IP:PORT建立连接,并直接绑定到客户端到服务端的连接中,后续服务端将不参与其中。

image-20200618171354514

Socks4a的请求报文就不过多解释了,增加了域名解析的传参,是对Socks4的补充,如下所示:

image-20200618171419445

Socks5

主要有以下几个RFC标准:

https://tools.ietf.org/html/rfc1929

https://tools.ietf.org/html/rfc1961

https://tools.ietf.org/html/rfc3089

流程

  1. socks5的请求报文只有三个参数

    • VER是版本号,固定0x05
    • NMETHODS 是表示METHODS的长度
    • METHODS验证方法,因为NMETHODS最大值只能是255所以参数最大字节数是255

image-20200618171501454

  1. 服务端返回响应报文就很简单了

    • VER 是版本号固定 0x05
    • METHOD 服务端选择一个自己也支持的认证方案返回

image-20200619153538912

  1. 校验通过,客服端继续发起第二次请求报文

    • VER 版本号,固定0x05
    • CMD 需要服务端做出的操作指令
    • RSV 是保留位,值是 0x00
    • ATYP 是目标地址类型
    • ADDR 就是目标地址
    • PORT 两个字节代表端口号

image-20200619155855845

  1. 服务端接收到请求,返回响应报文,同时绑定连接
    • REP 响应状态码
    • RSV 保留位,值是 0x00
    • ATYP 是目标地址类型
    • ADDR 就是目标地址的值了,如果是IPv4,那么就是4 bytes,如果是IPv6那么就是16 bytes,如果是域名,那么第一个字节代表 接下来有多少个字节是表示目标地址
    • PORT 两个字节代表端口号

image-20200619160343681

Socks5 支持UDP转发,应用场景更加广阔。

不过,现在的Socks4\5代理协议已经不再建议在广域网使用了,GFW的强大超乎你的现象,SS和Socks已没有什么用武之地了。为了免疫GFW的特征提取,新的协议将会是新的加密性质进行传输,同时也更加符合现代网络的组织结构,socks只是本地一个转换配角。Vmess才是目前受到广泛使用协议。

[附] Go语言的一个简单socks4/5实现 https://github.com/diiyw/mep

image-20200618171635748