Golang实现socks5 proxy服务
平时难免有一些访问“外网”的需要,或者网络爬虫需要一些代理,也有方式能够购买一些代理ip,但如果想很简单的部署一个稳定的代理ip,那么这里提供一个参考,使用Golang实现的sock5代理服务。
可以参考https://github.com/innerpeace-forever/socks_proxy
基于README的说明,可以完成编译和部署
Installation
在linux服务器上,将源代码clone到$GOPATH/src/目录下,并执行编译。如果是云服务器,记得在安全组中开放网络端口。
git clone https://github.com/innerpeace-forever/socks_proxy.git
mv socks_proxy $GOPATH/src/
cd $GOPATH/src/socks_proxy
sh -x build/build.sh
# 如果运行可以直接
# sh -x build/deploy.sh
Configuration
除了基本的日志配置外(可以不用动),最主要的是配置端口。在conf/conf.toml上
[Other.Service]
Port = 8080
代码说明
原理其实比较简单,几个关键步骤如下。代码是从git中截取的散乱片段,如果要直接使用,可以从https://github.com/innerpeace-forever/socks_proxy 直接clone、编译和运行。
- 建立tcp服务端口(用于客户端发起socks5的代理请求)
l, err := net.Listen("tcp", address)
if err != nil {
seelog.Infof("Listen[%v] Failed! ERR:%v", address, err)
return err
}
for {
client, err := l.Accept()
if err != nil {
seelog.Errorf("Accept Failed! Error:%v", err)
continue
}
go handleClientRequest(client)
if waitStopSignalNonBlock() {
break
}
}
- 解析socks5的头部协议,并且发起目标网站的tcp连接
if b[0] == 0x05 {
// Just process Socks5 protocol
// Without authentication
client.Write([]byte{0x05, 0x00})
n, err = client.Read(b[:])
if err != nil || n < 4 {
seelog.Errorf("handleClientRequest Read Failed! Error%:%v", err)
return
}
var host, port string
switch b[3] {
case 0x01: //IP V4
host = net.IPv4(b[4], b[5], b[6], b[7]).String()
case 0x03: //Domain
host = string(b[5 : n-2]) //b[4]表示域名的长度
case 0x04: //IP V6
host = net.IP{b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]}.String()
}
port = strconv.Itoa(int(b[n-2])<<8 | int(b[n-1]))
server, err := net.Dial("tcp", net.JoinHostPort(host, port))
if err != nil {
seelog.Errorf("handleClientRequest Dial(%s, %s) Failed! Error:%v", host, port, err)
return
}
seelog.Infof("New Connection, Dial(%s:%s).", host, port)
defer server.Close()
client.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) //响应客户端连接成功
}
- 双向的转发
go io.Copy(server, client)
io.Copy(client, server)