前两天,使用Golang实现了一个简单的HTTP Proxy,具体实现参见 一个简单的Golang实现的HTTP Proxy,这次使用Golang实现一个Socks5的简单代理。Socks5和HTTP并没有太大的不同,他们都可以完全给予TCP协议,只是请求的信息结构不同,所以这次我们不能像上次HTTP Proxy一样,解析请求和应答,要按照Socks的协议方式解析。
Socks协议版本
Socks协议分为Socks4和Socks5两个版本,他们最明显的区别是Socks5同时支持TCP和UDP两个协议,而SOcks4只支持TCP。目前大部分使用的是Socks5,我们这里只简单的介绍Socks5协议。
Socks5协议之授权认证
要想实现Socks5之间的连接会话,必须要懂Socks5协议的实现细节和规范。这就好比我们都用普通话对话一样,彼此说的都明白,也可以给对方听得懂的回应。Socks5的客户端和服务端交流也一样,他们的语言就是Socks5协议。因为Socks5支持TCP和UDP两种,这里只介绍TCP这一种,UDP大同小异。
首先客户端会给服务端发送验证信息,这个是建立连接的前提。比如客户端:hi,哥们,借个火。服务端要认识它就说:好,给;如果不认识就说:你哪根葱啊!!客户端请求的暗号很简单:
VER | NMETHODS | METHODS |
---|---|---|
1 | 1 | 1 to 255 |
1. 第一个字段VER代表Socks的版本,Socks5默认为0x05,其固定长度为1个字节
2. 第二个字段NMETHODS表示第三个字段METHODS的长度,它的长度也是1个字节
3. 第三个METHODS表示客户端支持的验证方式,可以有多种,他的尝试是1-255个字节。
目前支持的验证方式一共有:
- X’00’ NO AUTHENTICATION REQUIRED(不需要验证)
- X’01’ GSSAPI
- X’02’ USERNAME/PASSWORD(用户名密码)
- X’03’ to X’7F’ IANA ASSIGNED
- X’80’ to X’FE’ RESERVED FOR PRIVATE METHODS
- X’FF’ NO ACCEPTABLE METHODS(都不支持,没法连接了)
以上的都是十六进制常量,比如X’00’表示十六进制0x00。
服务端收到客户端的验证信息之后,就要回应客户端,服务端需要客户端提供哪种验证方式的信息。服务端的回应同样非常简洁。
VER | METHOD |
---|---|
1 | 1 |
1. 第一个字段VER代表Socks的版本,Socks5默认为0x05,其值长度为1个字节
2. 第二个字段METHOD代表需要服务端需要客户端按照此验证方式提供验证信息,其值长度为1个字节,选择为上面的六种验证方式。
举例说明,比如服务端不需要验证的话,可以这么回应客户端:
VER | METHOD |
---|---|
0x05 | 0x00 |
这就代表服务端说:哥们,我没啥要求,你来吧,我们使用Go实现代码如下:
var b [1024]byte
n, err := client.Read(b[:])
if err != nil {
log.Println(err)
return
}
if b[0] == 0x05 { //只处理Socks5协议