Socks5代理协议非常简单,小巧,整个文档很短,应用支持度也非常不错。对于个人开发实现来说是个不错的选择。

Sock5 Proxy

Socks5支持3种指令,

  1. Connect
  2. BIND
  3. UDP ASSOCIATE

本文只讨论常用的1和3。

Socks5 Proxy TCP

时序图如下

Sock5 proxy tcp 时序图

Socks5 Proxy UDP

时序图如下

Sock5 proxy udp 时序图

这里需要注意的是

  1. 由于UDP是无状态的,客户端发送Command之后,Proxy需要打开UDP端口,并将连接信息返回给Client
  2. TCP连接需要一直保持,否则UDP也将断开
  3. Proxy与Client和Remote的UDP通信可以只通过一个端口

Netty 实现

Netty Handler Pipeline图

netty-socks5-proxy

整个流程图实际上是有两个Pipeline

  • Client->Proxy,尾端的InboundHandler是BridgeHandler(C2R),持有Proxy->Remote的Channel,一旦收到Client发来的消息,立马发送给Proxy->Remote的Pipeline。
  • Proxy->Remote,尾端的InboundHandler是BridgeHandler(R2C),持有Client-Proxy的Channel,一旦收到Remote的消息,立马发送给Client-Proxy的Pipeline。

示意图是TCP的,如果是UDP,则不需要2d操作。

GitHub地址

https://github.com/XGFan/Socks5-Proxy

Shadowsocks

Shadowsocks算得上是GoAgent之后最活跃(或者最佳)的穿越防火墙的工具,其实现基本就是把Socks5 Proxy拆分为两部分,也比较简单。

仅仅以TCP为例,时序图如下

shadowsocks

这里需要注意的是

  • 与Socks5想象中的拆开,有几点反直觉

    • SS-Client并没有直接转发Command给SS-Server,而是使用了自己的一个简单格式
    • SS-Client向SS-Server发送Addressing之后也不用管是否能连接成功,直接返回结果给用户程序。1是加快速度,2是避免了每次SS-Server返回内容一致(连接成功)。
  • 实际中Addressing与Request有时候会包粘连在一起发到SS-Server,需要额外处理。
  • Client与Server之间需要加密或者混淆(目的都是混淆)。

GitHub地址 TODO