实战:150行Go实现高性能socks5代理

光说不练假把式,不如上手试试,这篇来写个有点卵用的东西。


- TCP Server -

用 Go 实现一个 TCP Server 实在是太简单了,什么 c10k problem、select、poll、epoll、kqueue、iocp、libevent,通通不需要(但为了通过面试你还是得去看呀),只需要这样两步:

  • 监听端口 1080(socks5的默认端口)

  • 每收到一个请求,启动一个 goroutine 来处理它

搭起这样一个架子,实现一个 Hello world,大约需要 30 行代码:

func main() {
  server, err := net.Listen("tcp", ":1080")
  if err != nil {
    fmt.Printf("Listen failed: %v\n", err)
    return
  }


  for {
    client, err := server.Accept()
    if err != nil {
      fmt.Printf("Accept failed: %v", err)
      continue
    }
    go process(client)
  }
}


func process(client net.Conn) {
  remoteAddr := client.RemoteAddr().String()
  fmt.Printf("Connection from %s\n", remoteAddr)
  client.Write([]byte("Hello world!\n"))
  client.Close()
}

- SOCKS5 -

socks5 是 SOCKS Protocol Version 5 的缩写,其规范定义于 RFC 1928[1],感兴趣的同学可以自己去翻一翻。

它是个二进制协议,不那么直观,不过实际上非常简单,主要分成三个步骤:

  • 认证

  • 建立连接

  • 转发数据

我们只需 16 行就能把 socks5 的架子搭起来:

func process(client net.Conn) {
  if err := Socks5Auth(client); err != nil {
    fmt.Println("auth error:", err)
    client.Close()
    return
  }


  target, err := Socks5Connect(client)
  if err != nil {
    fmt.Println("connect error:", err)
    client.Close()
    return
  }


  Socks5Forward(client, target)
}

这样一看是不是特别简单?

然后你只要把 Socks5Auth、Socks5Connect 和 Socks5Forward 给补上,一个完整的 socks5 代理就完成啦!是不是就像画一匹马一样简单?

全文完 (不是)


- Socks5Auth -

言归正传,socks5 协议规定,客户端需要先开口:

RFC 1928,首行是字段名,次行是字节数

解释一下:

VER 本次请求的协议版本号,取固定值 0x05(表示socks 5)
NMETHODS 客户端支持的认证方式数量,可取值 1~255
METHODS 可用的认证方式列表

我们用如下代码来读取客户端的发言:


  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值