Socks5代理协议非常简单,小巧,整个文档很短,应用支持度也非常不错。对于个人开发实现来说是个不错的选择。
Sock5 Proxy
Socks5支持3种指令,
- Connect
- BIND
- UDP ASSOCIATE
本文只讨论常用的1和3。
Socks5 Proxy TCP
时序图如下
Socks5 Proxy UDP
时序图如下
这里需要注意的是
- 由于UDP是无状态的,客户端发送Command之后,Proxy需要打开UDP端口,并将连接信息返回给Client
- TCP连接需要一直保持,否则UDP也将断开
- Proxy与Client和Remote的UDP通信可以只通过一个端口
Netty 实现
Netty Handler Pipeline图
整个流程图实际上是有两个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为例,时序图如下
这里需要注意的是
- 与Socks5想象中的拆开,有几点反直觉
- SS-Client并没有直接转发Command给SS-Server,而是使用了自己的一个简单格式。
- SS-Client向SS-Server发送Addressing之后也不用管是否能连接成功,直接返回结果给用户程序。1是加快速度,2是避免了每次SS-Server返回内容一致(连接成功)。
- 实际中Addressing与Request有时候会包粘连在一起发到SS-Server,需要额外处理。
- Client与Server之间需要加密或者混淆(目的都是混淆)。