Aione's blog

一起快乐摸鱼吧🐳

  1. 1. 1 使用场景
  2. 2. socks5流程
    1. 2.1. TCP部分
    2. 2.2. 协商
    3. 2.3. 认证
    4. 2.4. 请求
    5. 2.5. 返回
    6. 2.6. UDP部分

socks5在[rfc1928]有详细的说明。

这里只对socks5协议做简单解释,只是抽取了部分rfc中的内容进行翻译。

1 使用场景

socks5协议的设计初衷是在一个有防火墙的网络中,希望能通过某种方法来提高部分人的网络权限,让这部分人能够安全透明的访问外网。
大概是这样的

1
client<----->proxy<----->remote_server

不过国内大多数都是反着用的(笑

socks5流程

TCP部分

协商

客户端发送一条请求与socks服务器协商认证方法,请求结构如下。

VER NMETHODS METHODS
1 1 1 to 255

字段解释:

  • VER:socks的版本号,socks为X’05’,长度1字节
  • NMETHODS:认证方法数目,长度1字节
  • METHODS:认证方法,1到255字节

服务端从客户端提供的方法中选择一个并返回,返回结构如下。

VER METHOD
1 1

可选认证方法如下:

  • X’00’: NO AUTHENTICATION REQUIRED
  • X’01’: GSSAPI
  • X’02’: username/password
  • X’03’-X’7F’: IANA assigned
  • X’80’-X’FE’: RESERVED FOR PRIVATE METHODS
  • X’FF’: NO ACCEPTABLE METHODS

认证

认证部分的说明在[rfc1929]

如果客户端选择了username/password认证,那么客户端的请求是长这个样子的

VER ULEN UNAME PLEN PASSWD
1 1 1to255 1 1to255

字段解释:x

  • VER:子协议版本,这里为X’01’
  • ULEN: UNAME字段长度
  • UNAME: 用户名字节数据
  • PLEN: PASSWD字段长度
  • PASSWD: 密码字节数据

比较蠢的是,这东西都是明文传输的,这在rfc1929里也有提到

服务端返回

VER STATUS
1 1

字段解释:

  • VER: 同上
  • STAUTS: X’00’代表认证成功,其他都表示失败

    请求

    针对所依赖方法的子协商一旦完成,客户端就发送请求细节。如果协商过的方法包含了针对完整性检查或保密性目的的封装,这些请求必须被包装到所依赖的方法的封装中。SOCKS请求按下述格式进行组织
VER CMD RSV ATYP DST.ADDR DST.PORT
1 1 X’00’ 1 Variable 2

字段解释:

  • VER: 协议版本号,这里为X’05’
  • CMD:
    • CONNECT: X’01’
    • BIND: X’02’
    • UDP ASSOCIATE: X’03’
  • RSV: X’00’
  • ATYP: 地址类别(ipv4/ipv6/domainname/ipv9)
    • IPV4: X’01’
    • DOMAINNAME: X’03’
    • IPV6: X’04’
  • DST.ADDR: 目的地址
  • DST.PORT: 目的端口号

请求类型有下面几种:

  • CONNECT : 0X01, 建立代理连接。比较常见的请求,客服端请求服务器发起链接到目标主机,目标端口的代理。SOCKS 服务器将使用目标主机,目标端口, 客户端的源地址和端口号来评估 CONNECT 请求是否通过。成功之后后续流量都会被转发到目标主机的目标端口。
  • BIND : 0X02,BIND请求被用于要求客户端接受来自服务器连接的协议中。FTP是一个众所周知的例子,它针对命令和状态报告使用主要的“客户端到服务器”的连接,但是用来响应命令(如LS、GET、PUT命令)的数据传输可以使用一条“服务器到客户端”的连接。只有在完成了connnect操作之后才能进行bind操作,bind操作之后,代理服务器会有两次响应, 第一次响应是在创建socket监听完成之后,第二次是在目标机器连接到代理服务器上之后。.建立流程如下:
    • Client随BIND请求,发送其要绑定的地址和端口。
    • Server返回其创建的监听端口的地址和端口。
    • Server创建的监听端口有连接后,返回该连接的源地址和端口。
    • Server端将上述连接中的流量,发送给client的监听端口。
  • UDP ASSOCIATE : 0x03,用于在UDP中继处理中建立一条关联以处理UDP数据报。

    返回

    服务器返回格式如下:
VER REP RSV ATYP BND.ADDR BND.PORT
1 1 X’00’ 1 Variable 2

字段解释(与请求相同的部分不再赘述):

  • REP:
    • X’00’: succeeded
    • X’01’: general SOCKS server failure
    • X’02’: connection not allowed by ruleset
    • X’03’: Network unreachable
    • X’04’: Host unreachable
    • X’05’: Connection refused
    • X’06’: TTL expired
    • X’07’: Command not supported
    • X’08’: Address type not supported
    • X’09’-X’FF’: 未被分配

UDP部分

每个UDP数据包必须有如下请求头:

RSV FRAG ATYP DST.ADDR DST.PORT DATA
2 1 1 Variable 2 Variable

字段解释:

  • RSV: Reserved X’0000’
  • FRAG: Current fragment number
  • ATYP-DST.PORT: 同上
  • DATA: user data




参考[1]:Python编写socks5服务器
参考[2]:[rfc1929]
参考[3]:[rfc1928]

Author : Aione
本文使用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议
Link to this article : https://aione.me/2019/05/21/socks5/

This article was last updated on days ago, and the information described in the article may have changed.