用golang写socks5代理服务器1-本地代理

myml · · 7043 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

用go语言来实现socks5代理服务器,后面会加入ssh远程代理,用户验证,均衡负载一些吧

首先监听8080端口,循环接收tcp连接


	server, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Panic(err)
	}
	defer server.Close()
	log.Println("开始接受连接")
	for {
		client, err := server.Accept()
		if err != nil {
			log.Println(err)
			return
		}
		log.Println("一个新连接")
		go socks5Proxy(client)
	}

socks5Proxy函数用来实现sock5代理

先介绍一下sock5代理协议

具体可看 https://www.zybuluo.com/zwh8800/note/347444

client:0x05 0x02 0x00 0x02 或 0x05 0x01 0x00  (主要是用户验证方面,咱们忽略,直接返回0x05 0x00)

server:0x05 0x00 

client:0x05 0x01 0x00 0x01 ... 或 0x05 0x01 0x00 0x03 ...  (0x01后面跟的是ip+port ,0x02是ip6+port, 0x03跟的是domainName+port,因为是二进制,要用到binary包解码,然后就可以直接用net.Dial进行连接,go会自动转换到域名到ip,所以可以直接用)

server:0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 (当服务端确定能进行代理返回确定)

 

然后就是两个io.Copy来进行代理转发就行了,下面是代码

 
func socks5Proxy(conn net.Conn) {
	defer conn.Close()

	var b [1024]byte

	n, err := conn.Read(b[:])
	if err != nil {
		log.Println(err)
		return
	}
	log.Printf("% x", b[:n])

	conn.Write([]byte{0x05, 0x00})

	n, err = conn.Read(b[:])
	if err != nil {
		log.Println(err)
		return
	}
	log.Printf("% x", b[:n])

	var addr string
	switch b[3] {
	case 0x01:
		sip := sockIP{}
		if err := binary.Read(bytes.NewReader(b[4:n]), binary.BigEndian, &sip); err != nil {
			log.Println("请求解析错误")
			return
		}
		addr = sip.toAddr()
	case 0x03:
		host := string(b[5 : n-2])
		var port uint16
		err = binary.Read(bytes.NewReader(b[n-2:n]), binary.BigEndian, &port)
		if err != nil {
			log.Println(err)
			return
		}
		addr = fmt.Sprintf("%s:%d", host, port)
	}

	server, err := net.Dial("tcp", addr)
	if err != nil {
		log.Println(err)
		return
	}
	conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
	go io.Copy(server, conn)
	io.Copy(conn, server)
}

 


有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:myml

查看原文:用golang写socks5代理服务器1-本地代理

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

7043 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传