zoukankan      html  css  js  c++  java
  • SOCKS5 协议解析

     

    代理

    根据 HTTP 1.1 的定义,proxy 是:

    An intermediary program which acts as both a server and a client for the purpose of making requests on behalf of other clients. Requests are serviced internally or by passing them on, with possible translation, to other servers.

    代理就是中间人,一人分饰两角:客户端眼中的目标服务器,目标服务器眼中的客户端——这意味着他必须同时满足C/S 双方的规范。

    再细分,如果只是简单的 pipe C/S 两端数据,那他就是个“透明代理”;一旦他对请求或响应进行了修改,那就是“非透明代理”。

    但其实,SOCKS5 协议并不负责代理服务器的数据传输环节,此协议只是在C/S两端真实交互之间,建立起一条从客户端到代理服务器的授信连接。

    协议流程

    从流程上来说,SOCKS5  是一个C/S 交互的协议,交互大概分为这么几步:

    1.客户端发送认证协商

    2.代理服务器就认证协商进行回复

    3.客户端发送希望连接的目标信息

    4.代理服务器就连接信息进行确认或拒绝

    5.代理服务器连接目标并 pipe 到客户端

    协议细节

    1. 认证

    1.1 请求认证:
    版本号(1字节) 可供选认证方法(1字节) 选择的方法(1~255字节)
     固定为5 选了多少种 · X’00’ 不需要认证
    · X’01’ GSSAPI
    · X’02’ 用户名/密码
    · X’03’ -- X’7F’ 由IANA分配
    · X’80’ -- X’FE’ 为私人方法所保留的
    · X’FF’ 没有可以接受的方法
    1.2 响应认证:
    版本号(1字节) 确认认证的方法
     固定为5 认证方法列表的某项:
    · X’00’ 不需要认证
    · X’01’ GSSAPI
    · X’02’ 用户名/密码
    · X’03’ -- X’7F’ 由IANA分配
    · X’80’ -- X’FE’ 为私人方法所保留的
    · X’FF’ 没有可以接受的方法

    如果客户端不支持认证,那么握手会是这样子:

    1
    2
    请求: 0x05 0x01 0x00
    响应: 0x05 0x00
    

    如果客户端支持用户名/密码的认证方式

    1
    2
    请求: 0x05 0x02 0x00 0x02
    响应: 0x05 0x00
    

    如果客户端支持用户名/密码的认证方式,那么握手会是这样子:

    1
    2
    请求: 0x05 0x01 0x02
    响应: 0x05 0xff

     

    2. 请求信息

    2.1 发送目标信息:
    版本号(1字节) 命令(1字节) 保留(1字节) 请求类型(1字节) 地址(不定长) 端口(2字节)
     固定为5 0x01: CONNECT
    0x02: BIND
    0x03: UDP ASSOCIATE
    固定为 0x00 0x01: IP V4 地址
    0x03: 域名
    0x04: IP V6 地址
     如果请求
    类型是域名,
    第个1字节为
    域名的长度
     

    命令字段说明:

    • CONNECT:  用于客户端请求服务器进行代理
    • BIND:  用于客户端向服务器上报自己的反向连接监听地址(应用场景如 FTP 下载,客户端需要接受来自服务器的连接)
    • UDP ASSOCIATE:用于请求建立到 UDP 数据报中继的连接
    2.2 确认连接:
    版本号(1字节) 确认回应(1字节) 保留(1字节) 响应类型(1字节) 地址(不定长) 端口(2字节)
     固定为5 0x00: succeeded
    0x01: general SOCKS server failure
    0x02: connection not allowed by ruleset
    0x03: Network unreachable
    0x04: Host unreachable
    0x05: Connection refused
    0x06: TTL expired
    0x07: Command not supported
    0x08: Address type not supported
    0x09: to X’FF’ unassigned
    固定为 0x00 仅用于响应客
    户端BIND命令:
    0x01: IP V4 地址
    0x03: 域名
    0x04: IP V6 地址
     仅用于响应客
    户端BIND命令:
    如果请求
    类型是域名,
    第个1字节为
    域名的长度
    仅用于响应客
    户端BIND命令

    可以看出,在代理服务器确认回应为 0x00 时,此次 SOCKS5 协议协商部分顺利完成,宣告进入到数据传输阶段(也可以说,这之后发生的事已经与SOCKS5协议无关)。

    如果客户端要求请求 shadowsocks 代理 127.0.0.1:8000 的请求,那么客户端和 shadowsocks 之间的请求和响应是这样的:

    1
    2
    3
    4
    #    request: VER  CMD  RSV  ATYP DST.ADDR            DST.PORT
             请求: 0x05 0x01 0x00 0x01 0x7f 0x00 0x00 0x01 0x1f 0x40
    # response: VER REP RSV ATYP BND.ADDR BND.PORT 响应: 0x05 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x10 0x10

    这里 0x7f 0x00 0x00 0x01 0x1f 0x40 对应的是 127.0.0.1:8000

    需要注意的是,当请求中的 CMD == 0x01 时,绝大部分 SOCKS5 客户端的实现都会忽略 SOCKS5 服务器返回的 BND.ADDR 和 BND.PORT 字段,

    所以这里的 0x00 0x00 0x00 0x00 0x10 0x10 只是 shadowsocks 返回的一个无意义的地址和端口。

    出处:

    SOCKS5 协议解析

    SOCKS v5 协议 (RFC1928) 中文文档

     loggerhead:  shadowsocks 源码解析

  • 相关阅读:
    什么是 DLL?
    如何用vc创建和读取xml文件??
    VC中调用 Excel 的总结
    Excel.cpp和Excel.h
    SQL中也可以用格式字符串定制日期转字符串
    REVERT权限切换
    透明数据加密
    批量恢复数据库
    FILESTREAM
    eclipse Tomcat热启动maven install Jrebel
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/7502857.html
Copyright © 2011-2022 走看看