这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
一、什么是socks5
1.概念
socks是一种网络传输协议,主要用于客户端与外网服务器之间通讯的中间传递(代理)。根据OSI七层模型来划分,SOCKS属于会话层协议,位于表示层与传输层之间。
2.应用场景
SOCKS5目前常被用于访问被GFW屏蔽的网络内容(数据跨境安全网关,阻断不符合中国政府要求的互联网内容传输),以及作为代理服务器为用户提供不同位置的IP,帮助用户隐藏真实IP访问一些可能存在安全隐患的网络内容。
生活中的例子: 学校内网的资源一般只能通过校园网网访问,若学生不在学校,也需要访问内网资源,就可以一般我们可以通过在公网上面的一个VPS(虚拟专用服务器)搭建一个socks代理服务器,并且在内网搭建一台服务器和VPS建立socks通道,然后就可以通过连接到VPS提供的代理端口来访问到学校的内部资源了。
二、原理
- 客户端向代理服务器发出请求信息,用以协商版本和认证方法。代理服务器将选择的认证方法发送给客户端。若为00,则不需要认证,本案例跳过认证。
- 认证通过后,客户端再向代理服务器发请求,包括协议的版本号、请求的类型(一般为connection,代表向某域名某端口建立tcp连接)。代理服务器向目标服务器连接,将目标服务器的返回的响应再返回给客户端
- 代理服务器作为客户端与目标服务器的中转站,转发请求和响应。
三、代码实现
实现简单的echo server
能返回输入信息
实现认证
客户端向代理服务器发的请求报文包含三个字段:VER(协议版本,socks5为0x05),NMETHODS(支持认证的方法数量),METHODS(NMTHODS个字节)。常用鉴权:00不需要鉴权,02用户名密码鉴权。
请求阶段
客户端向代理服务器发送报文:VER;CMD 0x01表示CONNECT请求;RSV 保留字段,值为0x00;ATYP 目标地址类型,DST.ADDR的数据对应这个字段的类型,0x01表示IPv4地址,DST.ADDR为4个字节,0x03表示域名;DST.ADDR是一个可变长度的域名;DST.PORT 目标端口,固定2个字节
代理服务器建立连接
在connect最后加上
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
_, _ = io.Copy(dest, reader)
cancel()
}()
go func() {
_, _ = io.Copy(conn, dest)
cancel()
}()
<-ctx.Done()
当两个协程任意一个error时结束