SOCKS是一种网络传输协议,为Socket Secure的缩写,主要用于客户端与外网服务器之间通讯的中间传递。
根据OSI模型,SOCKS是会话层的协议,位于表示层与传输层之间。SOCKS协议不提供加密。
Procedure for TCP-based clients
创建与SOCKS5服务器的TCP连接后客户端需要先发送请求来确认协议版本及认证方式,格式为(以字节为单位):
| VER | NMETHODS | METHODS |
|---|---|---|
| 1 | 1 | 1 to 255 |
- VER:协议版本(socks5中为0x05)
- NMETHODS: 支持认证的方法数量
- METHODS: 客户端支持的认证方式列表,每个方法占1字节。当前的定义是:
- 0x00 不需要认证
- 0x01 GSSAPI
- 0x02 用户名、密码认证
- 0x03 - 0x7F由IANA分配(保留)
- 0x80 - 0xFE为私人方法保留
- 0xFF 无可接受的方法
服务器从客户端提供的方法中选择一个并通过以下消息通知客户端:
| VER | METHOD |
|---|---|
| 1 | 1 |
- VER:协议版本(socks5中为0x05)
- METHOD:服务端选中的方法(若返回0xFF表示没有方法被选中,客户端需要关闭连接)
之后客户端和服务端根据选定的认证方式执行对应的认证。认证结束 后客户端就可以发送请求信息(如果认证方法有特殊封装要求,请求必须按照方法所定义的方式进行封装)。
Requests
SOCKS请求格式:
| VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|---|---|---|---|---|---|
| 1 | 1 | X'00' | 1 | Variable | 2 |
- VER:协议版本(socks5中为0x05)
- CMD:SOCK的命令码:
- CONNECT 0x01
- BIND 0x02
- UDP ASSOCIATE 0x03
CONNECT 用于 TCP 场景,BIND 主要用于 FTP 等罕见场景,UDP ASSOCIATE 用于 UDP 场景。
- RSV:保留字段,固定取值 0x00
- ATYP:地址类型:
- IP V4地址: 0x01
- 域名地址: 0x03
- IP V6地址: 0x04
- DST.ADDR:目的地址
- DST.PORT:目的端口
Replies
服务器按以下格式回应客户端的请求(以字节为单位):
| VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
|---|---|---|---|---|---|
| 1 | 1 | X'00' | 1 | Variable | 2 |
- VER:协议版本(socks5中为0x05)
- REP:应答状态码:
- 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~0xFF unassigned (未定义)
- RSV:保留字段,默认设置为0x00
- ATYP:地址类型:
- IP V4 address: 0x01
- DOMAINNAME: 0x03
- IP V6 address: 0x04
- BND.ADDR:服务器绑定的地址
- BND.PORT:服务器绑定的端口
Procedure for UDP-based clients
| RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
|---|---|---|---|---|---|
| 2 | 1 | 1 | Variable | 2 | Variable |
SOCKS5支持UDP,此部分略过。
SOCKS5 用户名密码认证方式
| VER | ULEN | UNAME | PLEN | PASSWD |
|---|---|---|---|---|
| 1 | 1 | 1 to 255 | 1 | 1 to 255 |
略
Go 实现 Proxy SOCKS5
main函数是程序的入口点。它创建了一个TCP监听器,监听在本地主机的1080端口上。然后,它接受客户端的连接,并将每个连接交给process函数处理。
process函数用于处理每个客户端连接。它首先进行身份验证(调用auth函数),然后建立与目标服务器的连接(调用connect函数)。
auth函数负责处理身份验证过程。它从客户端读取协议消息,并根据协议规范进行处理。
connect函数用于建立与目标服务器的连接。它解析客户端发送的请求,并与目标服务器建立连接。
效果: