golang基于gVisor TCP/IP栈实现的tun2socks网络隧道插件库tun2socks的使用
Golang基于gVisor TCP/IP栈实现的tun2socks网络隧道插件库tun2socks的使用
特性
- 通用代理:透明地将任何应用程序的所有网络流量通过代理路由
- 多协议支持:支持HTTP/SOCKS4/SOCKS5/Shadowsocks代理,可选认证
- 跨平台:在Linux/macOS/Windows/FreeBSD/OpenBSD上运行,具有平台特定优化
- 网关模式:作为第3层网关,路由来自同一网络其他设备的流量
- 完整的IPv6兼容性:原生支持IPv6;无缝隧道IPv4 over IPv6和反之亦然
- 用户空间网络:利用gVisor网络栈提高性能和灵活性
基准测试
在各种使用场景下,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...)
}
注意事项
- 使用tun2socks需要管理员/root权限来创建TUN设备
- 在Windows上需要安装Wintun驱动程序
- 需要正确配置系统路由表以将流量定向到TUN设备
- 对于生产环境,建议添加适当的错误处理和重试逻辑
许可证
所有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协议握手和双向转发
// ...
}
关键组件说明
- TUN设备创建:创建虚拟网络接口
- gVisor网络栈:提供隔离的用户空间TCP/IP实现
- SOCKS转发:
- TCP连接通过SOCKS代理转发
- UDP数据包通过SOCKS5的UDP ASSOCIATE命令转发
高级功能
-
DNS处理:
func setupDNSForwarding(s *stack.Stack, dnsServer string) { // 拦截DNS请求并转发到指定服务器 // ... }
-
连接跟踪:
func enableConntrack(s *stack.Stack) { // 启用连接跟踪功能 // ... }
-
性能调优:
func tuneStack(s *stack.Stack) { // 调整TCP参数等 s.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpip.TCPReceiveBufferSizeRangeOption{1 << 20, 4 << 20}) // ... }
实际项目推荐
在实际项目中,可以考虑使用以下成熟实现:
- netstack-tun2socks:基于gVisor的完整实现
- go-tun2socks:支持多种后端包括gVisor
- sing-box:集成了tun2socks功能的全功能代理工具
注意事项
- 需要root权限创建TUN设备
- gVisor网络栈性能低于内核栈,但对安全性要求高的场景更合适
- 需要正确处理SOCKS协议的各种情况
- 注意处理UDP转发,这比TCP更复杂
希望这个示例能帮助你理解基于gVisor的tun2socks实现。实际使用时,你可能需要根据具体需求调整代码。