Reverst 是一个基于 QUIC 和 HTTP/3 构建的(负载平衡)反向隧道服务器和 Go 服务器-客户端库。
- Go Powered:使用quic-go以 Go 编写
- 兼容性:Goclient包建立在net/http标准库抽象之上
- 负载平衡:在同一隧道后面运行多个服务实例
- 性能卓越:基于 QUIC 和 HTTP/3 构建
Reverst 用于在受限网络(例如 NAT 网关后面)内公开公共互联网上的服务。隧道二进制文件旨在部署在公共互联网上。然后,客户端服务器拨出到隧道并在目标隧道组上注册自己。隧道组是一组负载平衡的客户端服务器,通过 reverst 隧道 HTTP 接口公开。
Reverst是一个创新的反向隧道解决方案,利用QUIC和HTTP/3协议的高速和安全性,可以在受限网络内部向公网公开服务。它的主要特点包括:
- 使用QUIC和HTTP/3协议,提供更快的连接建立和更高的吞吐量
- 支持多路复用,单个连接可传输多个流
- 支持连接迁移,可在网络环境变化时无缝切换网络
- 支持0-RTT连接恢复,提高重连效率
反向隧道服务器和客户端库
Reverst 是一个反向隧道服务器,允许通过 QUIC 和 HTTP/3 从 NAT 或防火墙后面的客户端机器到服务器建立安全隧道。它还提供了一个 Go 客户端库,用于从 Go 应用程序创建这些反向隧道。
负载均衡
reverst 服务器支持跨多个后端服务器平衡传入隧道连接的负载。这允许扩展服务器端来处理更多的客户端连接。
用 Go 编写
整个 reverst 项目,包括服务器和客户端库,都是用 Go 编写的,并建立在 quic-go 库之上以支持 QUIC。
其他项目:
1、GOST是一个功能丰富的Go反向代理和隧道工具。它支持多种代理和隧道协议,包括反向代理隧道。主要特点有:
- 支持反向代理隧道将内网服务暴露到公网
- 提供公共反向代理测试服务GOST.PLUS
- 支持串口重定向,实现串口远程通讯和数据监控
- 支持各种代理协议:HTTP(S)、SOCKS5、Shadowsocks等
2、Supershell是一个基于反向SSH隧道的C2远控平台,通过在目标主机建立反向SSH隧道获取完全交互式Shell。主要特点包括:
- 支持多平台架构Payload生成,集成压缩和免杀
- 支持全平台完全交互式Shell,可分享Shell
- 支持文件管理、内存注入、安装服务等功能
- 支持客户端监听实现内网渗透
综上所述,Go语言提供了多种优秀的反向隧道解决方案,可满足不同场景的需求,如公网暴露内网服务、远程控制、内网渗透等。
在Go中实现反向隧道思路
在Go中实现反向隧道的基本思路是:
- 客户端主动连接公网服务器,建立TCP连接。
- 服务端接受客户端连接,作为代理服务器。
- 客户端通过该TCP连接将内网服务数据传输给代理服务器。
- 代理服务器接收数据后,将其转发给需要访问的公网客户端。
具体实现步骤如下:
客户端- 使用net包建立与公网服务器的TCP连接。
- 启动本地HTTP服务,监听内网端口。
- 将本地HTTP服务接收到的请求数据通过之前建立的TCP连接发送给服务端。
// 建立与服务端的连接 conn, err := net.Dial("tcp", "服务器IP:端口") if err != nil { // 错误处理 }
// 启动本地HTTP服务 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 读取请求数据 data, err := ioutil.ReadAll(r.Body) if err != nil { // 错误处理 } // 通过TCP连接发送数据给服务端 conn.Write(data) })
// 监听本地端口 http.ListenAndServe(":8080", nil)
|
服务端
- 监听公网端口,接受客户端连接。
- 对每个连接,启动一个goroutine处理。
- 在goroutine中,从TCP连接读取客户端发来的数据。
- 将读取到的数据作为请求发送给需要访问的公网服务。
- 将公网服务的响应数据通过TCP连接返回给客户端。
// 监听端口 listener, err := net.Listen("tcp", ":8000") if err != nil { // 错误处理 }
// 循环接受连接 for { conn, err := listener.Accept() if err != nil { // 错误处理 continue } // 启动goroutine处理连接 go handleConn(conn) }
func handleConn(conn net.Conn) { defer conn.Close() // 读取客户端发来的数据 data := make([]byte, 1024) n, err := conn.Read(data) if err != nil { // 错误处理 return } // 将数据作为请求发送给公网服务 resp, err := http.Post("http://公网服务地址", "binary/data", bytes.NewReader(data[:n])) if err != nil { // 错误处理 return } defer resp.Body.Close() // 读取公网服务响应 body, err := ioutil.ReadAll(resp.Body) if err != nil { // 错误处理 return } // 将响应返回给客户端 conn.Write(body) }
|
在Go中实现内网穿透
客户端运行在内网中,主要职责是:
- 主动连接公网服务器,建立TCP连接作为隧道。
- 启动本地HTTP服务,监听需要穿透的内网端口。
- 将本地HTTP服务接收到的请求数据通过隧道TCP连接发送给服务端。
- 定期发送心跳包保持与服务端的连接。
- 如果与服务端连接断开,则重新连接。
// 建立与服务端的连接 conn, err := net.Dial("tcp", "服务器IP:端口") if err != nil { // 错误处理 }
// 启动本地HTTP服务 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 读取请求数据 data, err := ioutil.ReadAll(r.Body) if err != nil { // 错误处理 } // 通过TCP连接发送数据给服务端 conn.Write(data) })
// 监听本地端口 http.ListenAndServe(":8080", nil)
// 定期发送心跳包 go keepAlive(conn)
// 重连机制 go reconnect(conn)
|
服务端
服务端运行在公网服务器上,主要职责是:
- 监听公网端口,接受客户端连接。
- 对每个连接,启动一个goroutine处理。
- 在goroutine中,从TCP连接读取客户端发来的数据。
- 将读取到的数据作为请求发送给需要访问的公网服务。
- 将公网服务的响应数据通过TCP连接返回给客户端。
- 处理客户端断开连接的情况。
// 监听端口 listener, err := net.Listen("tcp", ":8000") if err != nil { // 错误处理 }
// 循环接受连接 for { conn, err := listener.Accept() if err != nil { // 错误处理 continue } // 启动goroutine处理连接 go handleConn(conn) }
func handleConn(conn net.Conn) { defer conn.Close() // 读取客户端发来的数据 data := make([]byte, 1024) n, err := conn.Read(data) if err != nil { // 错误处理 return } // 将数据作为请求发送给公网服务 resp, err := http.Post("http://公网服务地址", "binary/data", bytes.NewReader(data[:n])) if err != nil { // 错误处理 return } defer resp.Body.Close() // 读取公网服务响应 body, err := ioutil.ReadAll(resp.Body) if err != nil { // 错误处理 return } // 将响应返回给客户端 conn.Write(body) }
|