shadowsocks 原理详解
source link: https://overtalk.site/2020/02/25/network-shadowsocks/index.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
shadowsocks 原理详解
- 这个东西用的人不少,知道原理的人却不多,本文主要分析Shadowsocks实现的技术原理。
Shadowsocks的架构
Shadowsocks(后文缩写为SS)由两部分组成,客户端和服务器端。常用的客户端有shadowsocks-win、ShadowsocksX-NG、shadowsocks-Qt5、shadowsocks-android…;常用的服务器端有Python版本,Go语言版本,C、C++……。客户端启动后会开启一个本地代理(SOCKS5 / HTTP Proxy),通过修改操作系统配置或者浏览器配置把访问请求转发给本地代理。当我们通过浏览器访问某个地址的时候,数据会被转发到本地代理,由本地代理加密后转发到服务器端,服务器端处理完请求后把数据加密后返回给客户端的本地代理,本地代理再次返回给浏览器。
要澄清两点:1. SS协议和Http Proxy、Socks5没有半毛钱关系,这两个协议是浏览器或者操作系统所支持的标准代理协议,SS的架构中只是用这两种协议作为“获取用户请求”的手段而已。2. SS协议中没有任何控制流,本地代理获取用户原始TCP/UDP数据包获取之后会直接取出Data部分,重新构造一个IP数据包(可能是TCP或者UDP,和用户原始请求是TCP还是UDP有关系。),目标地址和端口是服务器地址,数据包的Data部分是加密后的用户原始Data。
socks5 协议
- 请见 socks5 详解
- 该协议主要用于客户端流量代理到
ss-local
shadowsocks 协议
- 官方文档
- 用户实际请求的数据包。通过
ss-local
发送到ss-server
的格式十分简陋,由两部分组成:
[target address][payload]
ss-server
接收加密的数据流,解密并解析前导目标地址(target address
)。然后,将有效载荷数据转发给目标。ss-server
接收来自目标的回复,进行加密并将其转发回 ss-local。其中地址部分(
target address
)格式如下所示:
[1-byte type][variable-length host][2-byte port]
- 定义了以下地址类型:
- 0x01:主机是一个4字节的IPv4地址。
- 0x03:host是一个可变长度的字符串,从1字节长度开始,后跟最多255字节域名。
- 0x04:host是一个16字节的IPv6地址。
- 端口号是2字节的big-endian无符号整数。
- 本部分将从本地流量产生出发,详细介绍整个流量转发的过程,可以根据转发流量的协议分成两种:tcp/udp
- 在shadowsocks的golang版本源码中,
ss-server
在同一个端口监听tcp/udp
TCP 流量
- 本地
tcp包
首先通过socks5
协议发送到ss-local
ss-local
将本地的tcp包数据加上target addr
,封装成 shadowsocks 协议包,发给ss-server
的tcp端口ss-server
解包,与target addr
建立tcp连接,将数据包发送给target addr
ss-server
将target addr
回的数据包通过原tcp连接返回给ss-local
ss-local
通过socks5
返回数据包
- udp 的整个流程和 tcp 类似,但是不同的是 udp 不是面对连接的,需要维持一个
nat map
- 当
ss-server
收到udp包时,回记录发送者的addr,为此创建一个 udp socket,并记录到nat map
中 - 通过上述 udp socket 发送/接受数据,收到数据时,根据nat map将数据发送给对应的
ss-local
Gitalking ...
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK