SOCKS是一种 网络传输协议 ,主要用于客户端与外网服务器之间通讯的中间传递。SOCKS是”SOCKetS”的缩写。
根据 OSI模型 ,SOCKS是会话层的协议,位于 表示层与 传输层之间。负责维护网络数据传输过程中,机器之间的通信连接。
SOCKS协议设计的初衷是帮助客户端更安全的访问防火墙外的资源。
当防火墙后的客户端要访问外部的服务器时,需要先跟SOCKS代理服务器连接。SOCKS代理服务器控制客户端访问外网的资格,并将符合条件的客户端的请求发往外部的服务器。
SOCKS5是SOCKS协议的第5版, 与前一个版本SOCKS4a相比,SOCKS5增加了对鉴定、IPv6和UDP支持。
SOCKS5代理原理示意图:

1.SOCKS5 Client发送SOCKS5请求到SOCK5 Server
2.SOCKS5 Server解析SOCKS5请求,提取出HTTP请求并转发到Google.com
3.Google.com 返回HTTP响应到SOCKS5 Server
4.SOCKS5 SERVER把HTTP响应封装到SOCK5响应里,返回给SOCKS5 Client
在一般的科学上网场景下,SOCKS5 Client通常是电脑或手机,SOCKS5 Server通常是一台在国外的VPS。
基于TCP的客户端使用SOCKS5流程:
1.握手
当TCP客户端想要建立到墙外目标服务器的连接,它必须先打开一个到SOCKS服务器的TCP连接,SOCKS服务位于TCP 1080端口上。
连接成功后,客户端会进入认证方法协商,当后续发送代理请求时,就使用协商好的认证方法进行认证。
如果没有特别说明,后续表格中的十进制数字表示相应字段占用的字节长度,X’hh’表示某个字段里的字节值,Variable表示某个字段的长度是可变的,具体的长度由相关的长度字段指定。
TCP客户端发送到SOCKS5服务器的握手请求:
+——+—————+—————+
|VER | NMETHODS | METHODS |
+——+—————+—————+
| 1 | 1 | 1~255 |
+——+—————+—————+
- VER:版本,由于是使用SOCKS5,这个值固定是X’05’,也就是5,该字段长度1个字节;
- NMETHODS:指定METHODS字段占用的字节数,该字段长度1个字节;
- METHODS:客户端支持的认证方式列表,每一个字节代表了一种认证方式,该字段长度在1~255字节之间。
目前客户端支持的认证方式有:
- 0x00:NO AUTHENTICATION REQUIRED(不需要验证)
- 0x01:GSSAPI
- 0x02:USERNAME/PASSWORD(用户名密码)
- 0x03: to X’7F’ IANA ASSIGNED
- 0x80: to X’FE’ RESERVED FOR PRIVATE METHODS
- 0xFF: NO ACCEPTABLE METHODS(都不支持,无法连接)
SOCKS服务器收到TCP客户端的握手请求后,需要检查服务器是否支持客户端的认证方式,并做出响应:
+——+————+
|VER | METHOD |
+——+————+
| 1 | 1 |
+——+————+
- VER:版本,由于是使用SOCKS5,这个值固定是X’05’,也就是5,该字段长度1个字节;
- METHOD:服务端要求客户端按此认证方式提供认证信息,可为上面提到的认证方式之一,该字段长度为1个字节。
2.连接请求
客户端与SOCKS5服务器端完成连接握手之后,客户端会开始发送连接请求:
+——+——+———+———+—————+————+
| VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT|
+——+——+———+———+—————+————+
| 1 | 1 | X’00’| 1 | Variable | 2 |
+——+——+———+———+—————+————+
- VER:版本,由于是使用SOCKS5,这个值固定是X’05’,也就是5,该字段长度1个字节;
- CMD:客户端请求的命令类型,字段长度为1个字节,有3种可选类型;
- 0x01:连接(CONNECT);
- 0x02:绑定(BIND);
- 0x03:UDP关联(UDP ASSOCIATE);
- RSV:保留字段,字段长度为1个字节;
- ATYP:请求的远程服务器地址类型,字段长度为1个字节,有3种可选类型:
- 0x01:IPV4地址
- 0x03:域名
- 0x04:IPV6地址
- DST.ADDR:远程服务器的地址,该字段长度不定,根据ATYP值决定:
- ATYP=X’01’:DST.ADDR字段值为1个IPV4地址,该字段长度为4个字节
- ATYP=X‘03’:DST.ADDR字段值包含1个域名,该字段的第1个字节表示了域名占用的字节数
- ATYP=X‘04’:DST.ADDR字段值为1个IPV6地址,该字段长度为16个字节
- DST.PORT:远程服务器的端口,使用网络字节序,该字段长度为2个字节,可以表示0~65535之间的所有端口。
SOCKS5服务器在收到客户端的请求之后,会对请求进行解析,并连接目标服务器,并返回结果给客户端:
+——+——+———+———+—————+—————+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+——+——+———+———+—————+—————+
| 1 | 1 | 1 | 1 | Variable | 2 |
+——+——+———+———+—————+—————+
- VER:版本,由于是使用SOCKS5,这个值固定是X’05’,也就是5,该字段长度1个字节;
- REP代表响应状态码,值长度也是1个字节,有以下几种类型
- 0x00:成功
- 0x01:通用SOCKS服务器失败
- 0x02:规则集不允许连接
- 0x03:网络不可达
- 0x04:主机不可达
- 0x05:连接被拒绝
- 0x06:TTL过期
- 0x07:不支持的命令
- 0x08:不支持的地址类型
- 0x09:到0xFF都未分配
- RSV:保留字,默认值未X’00’,该字段长度为1个字节
- ATYP:请求的远程服务器地址类型,该字段长度1个字节,有3种可选类型
- 0x01:IPV4地址
- 0x03:域名
- 0x04:IPV6地址
- BND.ADDR:绑定地址,该字段长度不定(具体长度规则参考上面的DST.ADDR)。
- BND.PORT: 绑定端口,该字段长度2个字节
绝大多数SOCKS5客户端会忽略上述返回的BND.ADDR和BND.PORT字段
3.代理
一旦客户端与SOCKS5服务器完成握手和连接之后,SOCKS5对后续的请求只会做简单的转发。
基于UDP的客户端使用SOCKS5流程:
1.代理
UDP客户端必须使用上述TCP流程中UDP关联请求返回的BND.PORT端口
每个客户端发送的UDP请求头如下:
+——+———+———+—————+—————+—————+
|RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
+——+———+———+—————+—————+—————+
| 2 | 1 | 1 | Variable | 2 | Variable |
+——+———+———+—————+—————+—————+
- RSV:保留字段,默认值X’0000’,字段长度为2个字节
- FRAG:当前的段号
- ATYP:请求的远程服务器地址类型,该字段长度1个字节,有3种可选类型
- X’01’:IPV4地址
- X’03’:域名
- X’04’:IPV6地址
- BND.ADDR:SOCKS服务端绑定地址
- BND.PORT:SOCKS服务端绑定端口,按网络字节序
- DATA:用户数据
由上面的“SOCKS5代理原理示意图”及协议说明可知,SOCKS5协议是明文在互联网上进行的,链路上的网关、路由器通过对数据包进行分析,很容易被识别。所以,科学上网神器Shadowsocks横空出世。
Shadowsocks原理:
Shadowsocks的创新在于将SOCKS5通信放在本地进行,本地与代理服务器之间采用密文传输,有效降低了数据包被识别的概率。
示意图如下:

一个完整的Shaowsocks代理流程示例:
# 握手阶段
client -> ss: 0x05 0x01 0x00
ss -> client: 0x05 0x00
# 建立连接
client -> ss: 0x05 0x01 0x00 0x03 0x0a b'google.com' 0x00 0x50
ss -> client: 0x05 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x10 0x10
# 传输阶段
client -> ss -> remote
remote -> ss -> client
......
Socks5协议标准相关参考文档:
https://www.rfc-editor.org/rfc/rfc1928.txt
https://www.singchia.com/2018/03/21/RFC1928-Socks-Protocol-Version-5/
http://peachey.blog/2017/12/28/py-shadowsocks/
http://wuhaolin.cn/2017/11/03/%E4%BD%A0%E4%B9%9F%E8%83%BD%E5%86%99%E4%B8%AA%20Shadowsocks/
https://loggerhead.me/posts/shadowsocks-yuan-ma-fen-xi-xie-yi-yu-jie-gou.html