golang基于gVisor TCP/IP栈实现的tun2socks网络隧道插件库tun2socks的使用

Golang基于gVisor TCP/IP栈实现的tun2socks网络隧道插件库tun2socks的使用

tun2socks

特性

  • 通用代理:透明地将任何应用程序的所有网络流量通过代理路由
  • 多协议支持:支持HTTP/SOCKS4/SOCKS5/Shadowsocks代理,可选认证
  • 跨平台:在Linux/macOS/Windows/FreeBSD/OpenBSD上运行,具有平台特定优化
  • 网关模式:作为第3层网关,路由来自同一网络其他设备的流量
  • 完整的IPv6兼容性:原生支持IPv6;无缝隧道IPv4 over IPv6和反之亦然
  • 用户空间网络:利用gVisor网络栈提高性能和灵活性

基准测试

benchmark

在各种使用场景下,tun2socks表现最佳。

使用示例

下面是一个完整的Golang示例,展示如何使用tun2socks库创建网络隧道:

package main

import (
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/xjasonlyu/tun2socks/v2/core/device"
	"github.com/xjasonlyu/tun2socks/v2/core/device/tun"
	"github.com/xjasonlyu/tun2socks/v2/core/option"
	"github.com/xjasonlyu/tun2socks/v2/proxy/proxy"
	"github.com/xjasonlyu/tun2socks/v2/tunnel"
)

func main() {
	// 1. 创建TUN设备
	tunDevice, err := tun.CreateTUN("tun0", 1500)
	if err != nil {
		log.Fatalf("Failed to create TUN device: %v", err)
	}

	// 2. 配置代理
	proxyURL := "socks5://127.0.0.1:1080" // 本地SOCKS5代理
	p, err := proxy.FromURL(proxyURL)
	if err != nil {
		log.Fatalf("Failed to parse proxy URL: %v", err)
	}

	// 3. 配置隧道选项
	opts := []option.Option{
		option.WithDevice(tunDevice),
		option.WithProxy(p),
		option.WithLogger(&myLogger{}), // 自定义日志记录器
	}

	// 4. 创建隧道
	t, err := tunnel.New(opts...)
	if err != nil {
		log.Fatalf("Failed to create tunnel: %v", err)
	}

	// 5. 启动隧道
	if err := t.Start(); err != nil {
		log.Fatalf("Failed to start tunnel: %v", err)
	}
	defer t.Stop()

	log.Println("tun2socks started successfully")

	// 6. 等待终止信号
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh

	log.Println("Shutting down tun2socks...")
}

// 自定义日志记录器实现
type myLogger struct{}

func (l *myLogger) Debug(format string, args ...interface{}) {
	log.Printf("[DEBUG] "+format, args...)
}

func (l *myLogger) Info(format string, args ...interface{}) {
	log.Printf("[INFO] "+format, args...)
}

func (l *myLogger) Warn(format string, args ...interface{}) {
	log.Printf("[WARN] "+format, args...)
}

func (l *myLogger) Error(format string, args ...interface{}) {
	log.Printf("[ERROR] "+format, args...)
}

更复杂的示例

下面是一个更完整的示例,包含更多配置选项:

package main

import (
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"

	"github.com/xjasonlyu/tun2socks/v2/core/device"
	"github.com/xjasonlyu/tun2socks/v2/core/device/tun"
	"github.com/xjasonlyu/tun2socks/v2/core/option"
	"github.com/xjasonlyu/tun2socks/v2/proxy/proxy"
	"github.com/xjasonlyu/tun2socks/v2/tunnel"
)

func main() {
	// 配置TUN设备
	tunName := "tun0"
	mtu := 1500
	address := "10.0.0.1/24" // TUN设备IP地址
	gateway := "10.0.0.1"     // 网关地址

	// 创建TUN设备
	tunDevice, err := tun.CreateTUN(tunName, mtu)
	if err != nil {
		log.Fatalf("Failed to create TUN device: %v", err)
	}

	// 设置TUN设备IP地址
	if err := setTUNAddress(tunName, address, gateway, mtu); err != nil {
		log.Fatalf("Failed to set TUN address: %v", err)
	}

	// 配置SOCKS5代理
	proxyURL := "socks5://user:password@127.0.0.1:1080" // 带认证的SOCKS5代理
	p, err := proxy.FromURL(proxyURL)
	if err != nil {
		log.Fatalf("Failed to parse proxy URL: %v", err)
	}

	// 高级配置选项
	opts := []option.Option{
		option.WithDevice(tunDevice),
		option.WithProxy(p),
		option.WithMTU(uint32(mtu)),
		option.WithTCPModerateReceiveBuffer(true),
		option.WithTCPBufferSize(4*1024*1024, 4*1024*1024), // 4MB TCP缓冲区
		option.WithUDPBufferSize(1*1024*1024),              // 1MB UDP缓冲区
		option.WithUDPTimeout(30),                          // 30秒UDP超时
		option.WithLogger(&myLogger{}),
	}

	// 创建并启动隧道
	t, err := tunnel.New(opts...)
	if err != nil {
		log.Fatalf("Failed to create tunnel: %v", err)
	}

	if err := t.Start(); err != nil {
		log.Fatalf("Failed to start tunnel: %v", err)
	}
	defer t.Stop()

	log.Printf("tun2socks started on %s with proxy %s", tunName, proxyURL)

	// 等待终止信号
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh

	log.Println("Shutting down tun2socks...")
}

// 设置TUN设备IP地址和路由
func setTUNAddress(name, addr, gateway string, mtu int) error {
	// 这里应该包含平台特定的代码来配置TUN设备
	// 例如在Linux上使用ip命令:
	// ip addr add <addr> dev <name>
	// ip link set <name> up
	// ip route add default via <gateway> dev <name> mtu <mtu>
	return nil
}

// 自定义日志记录器实现
type myLogger struct{}

func (l *myLogger) Debug(format string, args ...interface{}) {
	log.Printf("[DEBUG] "+format, args...)
}

func (l *myLogger) Info(format string, args ...interface{}) {
	log.Printf("[INFO] "+format, args...)
}

func (l *myLogger) Warn(format string, args ...interface{}) {
	log.Printf("[WARN] "+format, args...)
}

func (l *myLogger) Error(format string, args ...interface{}) {
	log.Printf("[ERROR] "+format, args...)
}

注意事项

  1. 使用tun2socks需要管理员/root权限来创建TUN设备
  2. 在Windows上需要安装Wintun驱动程序
  3. 需要正确配置系统路由表以将流量定向到TUN设备
  4. 对于生产环境,建议添加适当的错误处理和重试逻辑

许可证

所有v2.6.0及更高版本均可在MIT许可证条款下使用。


更多关于golang基于gVisor TCP/IP栈实现的tun2socks网络隧道插件库tun2socks的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于gVisor TCP/IP栈实现的tun2socks网络隧道插件库tun2socks的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


基于gVisor TCP/IP栈的tun2socks实现

tun2socks是一种将TUN设备流量通过SOCKS代理转发的技术,而基于gVisor TCP/IP栈的实现提供了更安全、隔离的网络栈环境。下面我将介绍如何使用这种实现。

基本概念

  • TUN设备:虚拟网络设备,工作在IP层
  • SOCKS代理:中间代理服务器,通常有SOCKS5和SOCKS4两种版本
  • gVisor:Google开发的用户空间网络栈,提供更好的隔离性

使用示例

以下是使用基于gVisor的tun2socks的基本代码示例:

package main

import (
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"

	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
	"gvisor.dev/gvisor/pkg/waiter"
)

func main() {
	// 1. 创建TUN设备
	tunDev, err := createTUN("tun0")
	if err != nil {
		log.Fatalf("Failed to create TUN device: %v", err)
	}
	defer tunDev.Close()

	// 2. 配置IP地址
	if err := configureTUN(tunDev, "10.0.0.1/24"); err != nil {
		log.Fatalf("Failed to configure TUN: %v", err)
	}

	// 3. 创建gVisor网络栈
	s := createStack()

	// 4. 设置SOCKS代理转发
	socksAddr := "127.0.0.1:1080"
	setupTCPForwarding(s, socksAddr)
	setupUDPForwarding(s, socksAddr)

	// 5. 启动TUN设备到网络栈的转发
	go forwardTUNToStack(tunDev, s)
	go forwardStackToTUN(s, tunDev)

	// 等待退出信号
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh
	log.Println("Shutting down...")
}

func createStack() *stack.Stack {
	// 创建gVisor网络栈
	s := stack.New(stack.Options{
		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
		TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol},
	})

	// 添加网络接口
	nicID := tcpip.NICID(1)
	if err := s.CreateNIC(nicID, loopback.New()); err != nil {
		log.Fatalf("CreateNIC error: %v", err)
	}

	// 添加IP地址
	addr := tcpip.Address(net.ParseIP("10.0.0.1").To4())
	if err := s.AddAddress(nicID, ipv4.ProtocolNumber, addr); err != nil {
		log.Fatalf("AddAddress error: %v", err)
	}

	// 设置路由
	s.SetRouteTable([]tcpip.Route{
		{
			Destination: tcpip.Address(net.ParseIP("0.0.0.0").To4()),
			Mask:       tcpip.AddressMask(net.ParseIP("0.0.0.0").To4()),
			Gateway:    "",
			NIC:        nicID,
		},
	})

	return s
}

func setupTCPForwarding(s *stack.Stack, socksAddr string) {
	tcpForwarder := tcp.NewForwarder(s, 0, 10, func(r *tcp.ForwarderRequest) {
		var wq waiter.Queue
		ep, err := r.CreateEndpoint(&wq)
		if err != nil {
			log.Printf("CreateEndpoint error: %v", err)
			r.Complete(true)
			return
		}
		r.Complete(false)

		// 将连接通过SOCKS代理转发
		go handleTCPConn(gonet.NewTCPConn(&wq, ep), socksAddr)
	})
	s.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
}

func handleTCPConn(conn net.Conn, socksAddr string) {
	defer conn.Close()

	// 连接到SOCKS代理
	socksConn, err := net.Dial("tcp", socksAddr)
	if err != nil {
		log.Printf("Failed to connect to SOCKS: %v", err)
		return
	}
	defer socksConn.Close()

	// 实现SOCKS握手和流量转发
	// 这里需要实现SOCKS5协议握手和双向转发
	// ...
}

关键组件说明

  1. TUN设备创建:创建虚拟网络接口
  2. gVisor网络栈:提供隔离的用户空间TCP/IP实现
  3. SOCKS转发
    • TCP连接通过SOCKS代理转发
    • UDP数据包通过SOCKS5的UDP ASSOCIATE命令转发

高级功能

  1. DNS处理

    func setupDNSForwarding(s *stack.Stack, dnsServer string) {
        // 拦截DNS请求并转发到指定服务器
        // ...
    }
    
  2. 连接跟踪

    func enableConntrack(s *stack.Stack) {
        // 启用连接跟踪功能
        // ...
    }
    
  3. 性能调优

    func tuneStack(s *stack.Stack) {
        // 调整TCP参数等
        s.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpip.TCPReceiveBufferSizeRangeOption{1 << 20, 4 << 20})
        // ...
    }
    

实际项目推荐

在实际项目中,可以考虑使用以下成熟实现:

  1. netstack-tun2socks:基于gVisor的完整实现
  2. go-tun2socks:支持多种后端包括gVisor
  3. sing-box:集成了tun2socks功能的全功能代理工具

注意事项

  1. 需要root权限创建TUN设备
  2. gVisor网络栈性能低于内核栈,但对安全性要求高的场景更合适
  3. 需要正确处理SOCKS协议的各种情况
  4. 注意处理UDP转发,这比TCP更复杂

希望这个示例能帮助你理解基于gVisor的tun2socks实现。实际使用时,你可能需要根据具体需求调整代码。

回到顶部