go-tunnel/README.md

37 KiB
Raw Blame History

端口转发和内网穿透系统

一个高性能、生产级别的 TCP 端口转发和内网穿透系统,使用 Go 语言编写。采用自定义隧道协议实现透明代理,支持多路复用和自动重连。

功能特性

  • 透明隧道协议: 基于自定义应用层协议的透明代理,外部完全不可见
  • 多路复用: 单个隧道连接支持多个并发TCP会话
  • 端口转发: 支持配置化的 TCP 端口范围管理和转发
  • 内网穿透: 支持通过隧道连接实现内网服务穿透
  • 持久化存储: 使用 SQLite 数据库持久化端口映射配置
  • 动态管理: 通过 HTTP API 动态创建和删除端口映射
  • 自动恢复: 服务器启动时自动恢复已保存的端口映射
  • 连接池管理: 高效的连接池和并发管理
  • 优雅关闭: 支持优雅关闭和信号处理
  • 自动重连: 客户端支持断线自动重连
  • 生产级代码: 完善的错误处理、日志记录和性能优化

系统架构

整体架构图

graph TB
    subgraph "外部网络"
        Client[外部客户端]
        Internet[互联网]
    end
    
    subgraph "公网服务器"
        Server[转发服务器]
        API[HTTP API]
        DB[(SQLite数据库)]
        Forwarder[端口转发器]
        TunnelServer[隧道服务器]
    end
    
    subgraph "内网环境"
        TunnelClient[隧道客户端]
        LocalService[本地服务]
    end
    
    Client -->|TCP连接| Server
    Server --> Forwarder
    Server --> TunnelServer
    API --> DB
    API --> Forwarder
    API --> TunnelServer
    
    TunnelServer <-->|隧道协议| TunnelClient
    TunnelClient --> LocalService
    
    style Server fill:#e1f5fe
    style TunnelServer fill:#f3e5f5
    style TunnelClient fill:#f3e5f5
    style LocalService fill:#e8f5e8

隧道协议设计

我们的隧道协议采用自定义应用层协议,格式如下:

| 版本(1B) | 类型(1B) | 长度(4B) | 数据 |

协议特点:

  • 版本: 0x01 (当前版本)
  • 类型: 消息类型 (连接请求/响应/数据/关闭/心跳)
  • 长度: 数据部分长度 (大端序)
  • 数据: 消息载荷

消息类型

graph LR
    subgraph "隧道协议消息类型"
        ConnReq[0x01<br/>连接请求]
        ConnResp[0x02<br/>连接响应]
        Data[0x03<br/>数据传输]
        Close[0x04<br/>关闭连接]
        KeepAlive[0x05<br/>心跳]
    end
    
    ConnReq --> ConnResp
    ConnResp --> Data
    Data --> Close
    KeepAlive --> KeepAlive
    
    style ConnReq fill:#ffcdd2
    style ConnResp fill:#dcedc8
    style Data fill:#bbdefb
    style Close fill:#ffcc80
    style KeepAlive fill:#d1c4e9

工作流程详解

1. 直接端口转发模式

当目标服务可以直接访问时,使用直接转发模式:

sequenceDiagram
    participant C as 外部客户端
    participant S as 转发服务器
    participant T as 目标服务

    Note over C,T: 直接端口转发模式

    C->>S: TCP SYN (端口10001)
    S->>S: 查找端口映射
    S->>T: 建立连接 (192.168.1.100:22)
    T-->>S: 连接确认
    S-->>C: TCP SYN-ACK
    
    loop 数据传输
        C->>S: 数据包
        S->>T: 转发数据
        T-->>S: 响应数据
        S-->>C: 转发响应
    end
    
    C->>S: 关闭连接
    S->>T: 关闭连接

2. 隧道穿透模式 (核心特性)

当目标服务在内网时,使用隧道穿透模式。这是本系统的核心创新点:

sequenceDiagram
    participant C as 外部客户端
    participant S as 转发服务器
    participant TS as 隧道服务器
    participant TC as 隧道客户端
    participant L as 本地服务

    Note over C,L: 隧道穿透模式 - 透明代理

    rect rgb(255, 245, 245)
    Note over TS,TC: 1. 隧道连接建立
    TC->>TS: 连接隧道服务器
    TS-->>TC: 接受连接
    end

    rect rgb(245, 255, 245)
    Note over C,L: 2. 外部客户端请求处理
    C->>S: TCP SYN (端口10022)
    S->>S: 检查端口映射
    Note over S: 发现需要使用隧道
    S->>TS: 请求转发连接
    end

    rect rgb(245, 245, 255)
    Note over TS,L: 3. 隧道协议交互
    TS->>TC: ConnectRequest(ID=1, Port=22)
    Note over TC: 协议格式: |0x01|0x01|0x00000006|ID+Port|
    TC->>L: 尝试连接本地服务
    L-->>TC: 连接成功/失败
    TC->>TS: ConnectResponse(ID=1, Status=Success)
    Note over TS: 协议格式: |0x01|0x02|0x00000005|ID+Status|
    TS-->>S: 连接建立完成
    end

    rect rgb(255, 255, 245)
    Note over C,L: 4. 透明数据转发
    S-->>C: TCP SYN-ACK (对外部客户端响应)
    
    loop 数据传输 (对外部完全透明)
        C->>S: 应用数据
        S->>TS: 转发到隧道
        TS->>TC: Data(ID=1, 数据)
        Note over TS: 协议格式: |0x01|0x03|长度|ID+数据|
        TC->>L: 转发到本地服务
        L-->>TC: 本地服务响应
        TC->>TS: Data(ID=1, 响应数据)
        TS->>S: 从隧道返回
        S-->>C: 返回给外部客户端
    end
    end

    rect rgb(250, 250, 250)
    Note over C,L: 5. 连接关闭
    C->>S: 关闭连接
    S->>TS: 通知关闭
    TS->>TC: Close(ID=1)
    Note over TC: 协议格式: |0x01|0x04|0x00000004|ID|
    TC->>L: 关闭本地连接
    end

3. 多路复用演示

单个隧道连接支持多个并发会话:

sequenceDiagram
    participant C1 as 客户端1
    participant C2 as 客户端2
    participant S as 转发服务器
    participant T as 隧道连接
    participant TC as 隧道客户端
    participant L1 as 本地服务1
    participant L2 as 本地服务2

    Note over C1,L2: 隧道多路复用

    rect rgb(255, 245, 245)
    Note over C1,L1: 连接1 - SSH服务
    C1->>S: 连接端口10022
    S->>T: ConnectRequest(ID=1, Port=22)
    T->>TC: 转发请求
    TC->>L1: 连接SSH服务
    L1-->>TC: 连接成功
    TC->>T: ConnectResponse(ID=1, Success)
    T->>S: 确认
    S-->>C1: 建立连接
    end

    rect rgb(245, 255, 245)
    Note over C2,L2: 连接2 - HTTP服务 (同时进行)
    C2->>S: 连接端口10080
    S->>T: ConnectRequest(ID=2, Port=80)
    T->>TC: 转发请求 (同一隧道)
    TC->>L2: 连接HTTP服务
    L2-->>TC: 连接成功
    TC->>T: ConnectResponse(ID=2, Success)
    T->>S: 确认
    S-->>C2: 建立连接
    end

    Note over C1,L2: 两个连接同时传输数据

    par 连接1数据传输
        C1->>S: SSH数据
        S->>T: Data(ID=1, SSH数据)
        T->>TC: 转发
        TC->>L1: 发送到SSH
    and 连接2数据传输
        C2->>S: HTTP请求
        S->>T: Data(ID=2, HTTP数据)
        T->>TC: 转发 (同一隧道)
        TC->>L2: 发送到HTTP
    end

4. 系统组件交互

graph TB
    subgraph "服务器端组件"
        Main[main.go]
        Config[config.go]
        API[api.go]
        DB[database.go]
        Forwarder[forwarder.go]
        TunnelServer[tunnel/server.go]
    end
    
    subgraph "客户端组件"
        ClientMain[client/main.go]
        TunnelClient[tunnel/client.go]
    end
    
    subgraph "外部接口"
        HTTP[HTTP API]
        TCP[TCP端口]
        TunnelPort[隧道端口]
    end

    Main --> Config
    Main --> API
    Main --> TunnelServer
    API --> DB
    API --> Forwarder
    Forwarder --> TCP
    TunnelServer --> TunnelPort
    
    HTTP --> API
    TunnelPort <--> TunnelClient
    ClientMain --> TunnelClient
    
    style Main fill:#e3f2fd
    style TunnelServer fill:#f3e5f5
    style TunnelClient fill:#f3e5f5
    style API fill:#e8f5e8

5. 错误处理和重连机制

stateDiagram-v2
    [*] --> 初始化
    初始化 --> 连接中 : 启动连接
    连接中 --> 已连接 : 连接成功
    连接中 --> 重连等待 : 连接失败
    已连接 --> 传输中 : 开始传输
    传输中 --> 已连接 : 传输完成
    传输中 --> 重连等待 : 连接断开
    重连等待 --> 连接中 : 重连尝试
    已连接 --> [*] : 正常关闭
    
    state 重连等待 {
        [*] --> 等待5秒
        等待5秒 --> 重试连接
        重试连接 --> [*]
    }

项目结构

go-tunnel/
├── README.md                # 项目文档
├── config.yaml              # 配置文件
├── src/                     # 源代码目录
│   ├── go.mod              # Go 模块文件
│   ├── Makefile            # 构建脚本
│   ├── server/             # 服务器端
│   │   ├── main.go         # 服务器主程序
│   │   ├── config/         # 配置管理
│   │   │   ├── config.go
│   │   │   └── config_test.go
│   │   ├── db/             # 数据库管理
│   │   │   ├── database.go
│   │   │   └── database_test.go
│   │   ├── forwarder/      # 端口转发
│   │   │   ├── forwarder.go
│   │   │   └── forwarder_test.go
│   │   ├── tunnel/         # 隧道服务器
│   │   │   ├── tunnel.go   # 新隧道协议实现
│   │   │   └── tunnel_test.go
│   │   └── api/            # HTTP API
│   │       ├── api.go
│   │       └── api_test.go
│   ├── client/             # 客户端
│   │   ├── main.go         # 客户端主程序
│   │   └── tunnel/         # 隧道客户端
│   │       ├── client.go   # 新隧道协议实现
│   │       └── client_test.go
│   └── test/               # 集成测试
│       ├── integration_test.go
│       ├── run_tests.sh
│       └── README.md
└── bin/                    # 编译输出目录
    ├── server
    └── client

核心技术特点

1. 透明代理机制

flowchart TD
    A[外部TCP连接请求] --> B{检查端口映射}
    B -->|直接转发| C[建立目标连接]
    B -->|隧道模式| D[发送隧道请求]
    D --> E[等待客户端确认]
    E -->|成功| F[建立隧道会话]
    E -->|失败| G[拒绝连接]
    F --> H[开始透明转发]
    C --> H
    G --> I[关闭客户端连接]
    H --> J[数据传输]
    
    style D fill:#e1f5fe
    style F fill:#e8f5e8
    style H fill:#fff3e0

2. 协议栈对比

graph LR
    subgraph "传统方案"
        A1[应用数据] --> A2[TCP] --> A3[IP] --> A4[以太网]
    end
    
    subgraph "我们的隧道协议"
        B1[应用数据] --> B2[隧道协议] --> B3[TCP] --> B4[IP] --> B5[以太网]
    end
    
    subgraph "隧道协议详细"
        C1[版本] --> C2[类型] --> C3[长度] --> C4[数据]
    end
    
    style B2 fill:#e3f2fd
    style C1 fill:#ffebee
    style C2 fill:#e8f5e8
    style C3 fill:#fff3e0
    style C4 fill:#f3e5f5

3. 连接状态管理

服务器端维护两种连接状态:

graph TB
    subgraph "服务器状态管理"
        Pending[待处理连接<br/>PendingConnection]
        Active[活跃连接<br/>ActiveConnection]
        
        Pending --> |客户端确认| Active
        Pending --> |超时/失败| Closed[关闭]
        Active --> |正常关闭| Closed
        Active --> |异常断开| Closed
    end
    
    subgraph "连接生命周期"
        Create[创建] --> Wait[等待确认]
        Wait --> Establish[建立]
        Establish --> Transfer[传输]
        Transfer --> Close[关闭]
    end
    
    style Pending fill:#fff3e0
    style Active fill:#e8f5e8
    style Closed fill:#ffebee

协议详细规范

隧道协议消息格式

字段 大小 描述
版本 1字节 协议版本当前为0x01
类型 1字节 消息类型
长度 4字节 数据部分长度(大端序)
数据 变长 消息载荷

消息类型详解

1. 连接请求 (0x01)

数据格式: [连接ID(4字节)] + [目标端口(2字节)]
示例: 00 00 00 01 00 16  (连接ID=1, 端口=22)

2. 连接响应 (0x02)

数据格式: [连接ID(4字节)] + [状态(1字节)]
状态码: 0x00=成功, 0x01=失败
示例: 00 00 00 01 00  (连接ID=1, 状态=成功)

3. 数据传输 (0x03)

数据格式: [连接ID(4字节)] + [实际数据]
示例: 00 00 00 01 + [SSH数据包]

4. 关闭连接 (0x04)

数据格式: [连接ID(4字节)]
示例: 00 00 00 01  (关闭连接ID=1)

5. 心跳 (0x05)

数据格式: 无数据
用途: 保持连接活跃,检测连接状态

TCP请求处理流程

flowchart TD
    Start[TCP SYN到达] --> Check{检查端口映射}
    Check -->|未找到| Reject[拒绝连接]
    Check -->|直接转发| Direct[建立目标连接]
    Check -->|隧道模式| Tunnel{隧道是否连接}
    
    Tunnel -->|未连接| Reject
    Tunnel -->|已连接| CreateReq[创建连接请求]
    
    CreateReq --> SendReq[发送ConnectRequest]
    SendReq --> WaitResp[等待ConnectResponse]
    WaitResp -->|超时| Timeout[连接超时]
    WaitResp -->|失败| Failed[连接失败]
    WaitResp -->|成功| Success[连接成功]
    
    Direct --> DataForward[数据转发]
    Success --> DataForward
    DataForward --> Monitor[监控连接状态]
    Monitor -->|断开| Cleanup[清理资源]
    
    Timeout --> Reject
    Failed --> Reject
    Reject --> End[结束]
    Cleanup --> End
    
    style CreateReq fill:#e3f2fd
    style SendReq fill:#e1f5fe
    style WaitResp fill:#f3e5f5
    style Success fill:#e8f5e8
    style DataForward fill:#fff3e0

快速开始

1. 环境要求

  • Go 1.19+
  • Linux/macOS/Windows
  • 网络端口访问权限

2. 安装和编译

# 克隆项目
git clone <repository-url>
cd go-tunnel

# 进入源代码目录
cd src

# 安装依赖
go mod download

# 编译项目
make clean
make

# 或者分别编译
make server    # 编译服务器
make client    # 编译客户端

3. 配置服务器

编辑 config.yaml 文件:

# 端口范围配置
port_range:
  from: 10000      # 起始端口
  end: 10100       # 结束端口

# 内网穿透配置
tunnel:
  enabled: true        # 是否启用内网穿透
  listen_port: 9000    # 隧道监听端口

# HTTP API 配置
api:
  listen_port: 8080    # API服务端口

# 数据库配置
database:
  path: "./data/mappings.db"  # 数据库文件路径

4. 启动服务器

# 使用默认配置启动
cd bin
./server

# 或指定配置文件
./server -config ../config.yaml

# 查看帮助
./server -help

5. 启动客户端(内网穿透模式)

# 连接到服务器
cd bin
./client -server <服务器IP>:9000

# 例如
./client -server 1.2.3.4:9000

# 查看帮助
./client -help

6. 运行测试

# 运行所有测试
make test

# 运行特定组件测试
go test ./server/tunnel -v
go test ./client/tunnel -v

# 运行集成测试
./test/run_tests.sh

使用示例

示例1: SSH内网穿透

sequenceDiagram
    participant User as 用户
    participant Server as 公网服务器
    participant Client as 内网客户端
    participant SSH as SSH服务器

    Note over User,SSH: SSH内网穿透示例
    
    User->>Server: 创建端口映射
    Note over Server: POST /api/mapping/create<br/>{"port": 10022}
    
    Client->>Server: 建立隧道连接
    Server-->>Client: 隧道连接确认
    
    User->>Server: SSH连接 (port 10022)
    Server->>Client: 隧道协议: ConnectRequest(ID=1, Port=22)
    Client->>SSH: 连接本地SSH服务
    SSH-->>Client: 连接成功
    Client->>Server: 隧道协议: ConnectResponse(ID=1, Success)
    Server-->>User: SSH连接建立
    
    loop SSH会话
        User->>Server: SSH命令
        Server->>Client: 隧道协议: Data(ID=1, SSH数据)
        Client->>SSH: 转发SSH命令
        SSH-->>Client: 命令输出
        Client->>Server: 隧道协议: Data(ID=1, 输出数据)
        Server-->>User: 返回命令输出
    end

操作步骤:

# 1. 在公网服务器启动服务
./server -config config.yaml

# 2. 创建SSH端口映射
curl -X POST http://server:8080/api/mapping/create \
  -H "Content-Type: application/json" \
  -d '{"port": 10022}'

# 3. 在内网机器启动客户端
./client -server server:9000

# 4. 用户通过公网服务器连接内网SSH
ssh user@server -p 10022

示例2: Web服务穿透

# 1. 创建HTTP服务映射
curl -X POST http://server:8080/api/mapping/create \
  -H "Content-Type: application/json" \
  -d '{"port": 10080}'

# 2. 用户访问内网Web服务
curl http://server:10080
# 实际访问的是内网机器的80端口服务

示例3: 数据库穿透

# 1. 创建MySQL映射
curl -X POST http://server:8080/api/mapping/create \
  -H "Content-Type: application/json" \
  -d '{"port": 13306}'

# 2. 连接内网数据库
mysql -h server -P 13306 -u username -p

HTTP API 参考

API概览

graph LR
    subgraph "HTTP API端点"
        Health[GET /health]
        Create[POST /api/mapping/create]
        Remove[POST /api/mapping/remove]
        List[GET /api/mapping/list]
    end
    
    subgraph "功能"
        Health --> HealthCheck[健康检查]
        Create --> CreateMapping[创建端口映射]
        Remove --> RemoveMapping[删除端口映射]
        List --> ListMappings[列出所有映射]
    end
    
    style Health fill:#e8f5e8
    style Create fill:#e3f2fd
    style Remove fill:#ffebee
    style List fill:#fff3e0

创建端口映射

请求:

curl -X POST http://localhost:8080/api/mapping/create \
  -H "Content-Type: application/json" \
  -d '{
    "port": 10001,
    "target_ip": "192.168.1.100"
  }'

响应:

{
  "success": true,
  "message": "端口映射创建成功",
  "data": {
    "port": 10001,
    "target_ip": "192.168.1.100",
    "use_tunnel": false
  }
}

删除端口映射

请求:

curl -X POST http://localhost:8080/api/mapping/remove \
  -H "Content-Type: application/json" \
  -d '{
    "port": 10001
  }'

响应:

{
  "success": true,
  "message": "端口映射删除成功",
  "data": {
    "port": 10001
  }
}

列出所有映射

请求:

curl http://localhost:8080/api/mapping/list

响应:

{
  "success": true,
  "message": "获取映射列表成功",
  "data": {
    "mappings": [
      {
        "id": 1,
        "source_port": 10001,
        "target_ip": "192.168.1.100",
        "target_port": 10001,
        "created_at": "2024-01-01 12:00:00"
      }
    ],
    "count": 1,
    "use_tunnel": false
  }
}

健康检查

请求:

curl http://localhost:8080/health

响应:

{
  "status": "ok",
  "tunnel_enabled": true,
  "tunnel_connected": true
}

使用场景

场景 1: 直接端口转发(无隧道)

适用于服务器可以直接访问目标服务的情况。

  1. 配置 tunnel.enabled: false
  2. 启动服务器
  3. 创建映射时指定 target_ip
curl -X POST http://localhost:8080/api/mapping/create \
  -H "Content-Type: application/json" \
  -d '{
    "port": 10022,
    "target_ip": "192.168.1.100"
  }'

场景 2: 内网穿透(隧道模式)

适用于目标服务在内网,服务器无法直接访问的情况。

  1. 配置 tunnel.enabled: true
  2. 启动服务器
  3. 在内网机器上启动客户端
  4. 创建映射(无需指定 target_ip
curl -X POST http://localhost:8080/api/mapping/create \
  -H "Content-Type: application/json" \
  -d '{
    "port": 10022
  }'

性能优化与监控

系统性能架构

graph TB
    subgraph "性能优化层次"
        App[应用层优化]
        Protocol[协议层优化]
        Network[网络层优化]
        System[系统层优化]
    end
    
    subgraph "应用层优化"
        ConnPool[连接池管理]
        Buffer[缓冲区优化]
        Goroutine[协程池]
        Memory[内存复用]
    end
    
    subgraph "协议层优化"
        Multiplex[多路复用]
        Compression[数据压缩]
        KeepAlive[连接保活]
        BatchSend[批量发送]
    end
    
    subgraph "监控指标"
        Metrics[性能指标]
        Logs[日志记录]
        Health[健康检查]
        Alert[告警机制]
    end
    
    App --> ConnPool
    App --> Buffer
    Protocol --> Multiplex
    Protocol --> KeepAlive
    
    ConnPool --> Metrics
    Buffer --> Metrics
    Multiplex --> Logs
    
    style App fill:#e3f2fd
    style Protocol fill:#e8f5e8
    style Metrics fill:#fff3e0

连接池配置

数据库连接池在 db/database.go 中配置:

// 数据库连接池优化
db.SetMaxOpenConns(25)        // 最大打开连接数
db.SetMaxIdleConns(5)         // 最大空闲连接数
db.SetConnMaxLifetime(300*time.Second)  // 连接最大生存时间

缓冲区大小优化

数据转发缓冲区配置:

// 不同场景的缓冲区配置
const (
    SmallBuffer  = 4 * 1024   // 4KB  - 适用于控制消息
    MediumBuffer = 32 * 1024  // 32KB - 适用于一般数据传输
    LargeBuffer  = 64 * 1024  // 64KB - 适用于大文件传输
)

并发控制架构

graph TB
    subgraph "并发控制"
        MainGoroutine[主协程]
        TunnelGoroutine[隧道协程]
        ForwarderGoroutine[转发协程]
        ConnGoroutines[连接协程池]
    end
    
    subgraph "同步机制"
        WaitGroup[WaitGroup]
        Context[Context取消]
        Channel[Channel通信]
        Mutex[互斥锁]
    end
    
    MainGoroutine --> TunnelGoroutine
    MainGoroutine --> ForwarderGoroutine
    ForwarderGoroutine --> ConnGoroutines
    
    TunnelGoroutine -.-> WaitGroup
    ForwarderGoroutine -.-> Context
    ConnGoroutines -.-> Channel
    
    style MainGoroutine fill:#e3f2fd
    style TunnelGoroutine fill:#f3e5f5
    style ForwarderGoroutine fill:#e8f5e8
    style ConnGoroutines fill:#fff3e0

监控指标

关键性能指标 (KPI)

graph LR
    subgraph "连接指标"
        TotalConn[总连接数]
        ActiveConn[活跃连接数]
        ConnRate[连接建立速率]
        ConnDuration[连接持续时间]
    end
    
    subgraph "传输指标"
        Throughput[吞吐量]
        Latency[延迟]
        PacketLoss[丢包率]
        ErrorRate[错误率]
    end
    
    subgraph "资源指标"
        CPUUsage[CPU使用率]
        MemoryUsage[内存使用量]
        GoroutineCount[协程数量]
        FileDescriptor[文件描述符]
    end
    
    TotalConn --> Dashboard[监控面板]
    Throughput --> Dashboard
    CPUUsage --> Dashboard
    
    style Dashboard fill:#e3f2fd

建议监控以下指标:

类别 指标 说明 阈值建议
连接 活跃端口映射数量 当前转发的端口数 < 1000
连接 并发连接数 同时处理的连接数 < 10000
性能 数据传输速率 MB/s 根据网络带宽
性能 连接建立延迟 毫秒 < 100ms
资源 内存使用量 MB < 512MB
资源 CPU使用率 % < 80%
隧道 隧道连接状态 布尔值 = true
隧道 心跳响应时间 毫秒 < 1000ms

部署架构建议

生产环境部署

graph TB
    subgraph "互联网"
        Users[用户]
        Internet[Internet]
    end
    
    subgraph "DMZ区域"
        LB[负载均衡器]
        Firewall[防火墙]
    end
    
    subgraph "应用服务器区域"
        Server1[转发服务器1]
        Server2[转发服务器2]
        Database[(数据库)]
        Monitor[监控系统]
    end
    
    subgraph "内网环境"
        Client1[隧道客户端1]
        Client2[隧道客户端2]
        Services[内网服务]
    end
    
    Users --> Internet
    Internet --> Firewall
    Firewall --> LB
    LB --> Server1
    LB --> Server2
    Server1 --> Database
    Server2 --> Database
    Monitor --> Server1
    Monitor --> Server2
    
    Server1 <--> Client1
    Server2 <--> Client2
    Client1 --> Services
    Client2 --> Services
    
    style LB fill:#e3f2fd
    style Server1 fill:#e8f5e8
    style Server2 fill:#e8f5e8
    style Database fill:#fff3e0
    style Monitor fill:#f3e5f5

Docker部署

Dockerfile示例

# 服务器端Dockerfile
FROM golang:1.21-alpine AS builder

WORKDIR /app
COPY src/ .
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o server ./server

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/server .
COPY config.yaml .

EXPOSE 8080 9000
CMD ["./server", "-config", "config.yaml"]

Docker Compose配置

version: '3.8'

services:
  go-tunnel-server:
    build: .
    ports:
      - "8080:8080"    # API端口
      - "9000:9000"    # 隧道端口
      - "10000-10100:10000-10100"  # 转发端口范围
    volumes:
      - ./config.yaml:/root/config.yaml
      - ./data:/root/data
    environment:
      - GO_ENV=production
    restart: unless-stopped
    
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

安全建议

安全架构

graph TB
    subgraph "安全层次"
        Network[网络安全]
        Transport[传输安全]
        Application[应用安全]
        Access[访问控制]
    end
    
    subgraph "网络安全"
        Firewall[防火墙规则]
        VPN[VPN接入]
        IPWhitelist[IP白名单]
    end
    
    subgraph "传输安全"
        TLS[TLS加密]
        CertValidation[证书验证]
        MTLS[双向TLS]
    end
    
    subgraph "应用安全"
        Authentication[身份认证]
        Authorization[权限控制]
        RateLimit[速率限制]
        Logging[安全日志]
    end
    
    Network --> Firewall
    Transport --> TLS
    Application --> Authentication
    
    style Network fill:#ffebee
    style Transport fill:#e8f5e8
    style Application fill:#e3f2fd

1. 网络安全配置

防火墙规则示例

# iptables 规则示例
# 允许API端口仅内网
iptables -A INPUT -p tcp --dport 8080 -s 192.168.0.0/16 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP

# 允许隧道端口(公网)
iptables -A INPUT -p tcp --dport 9000 -j ACCEPT

# 允许转发端口范围(公网)
iptables -A INPUT -p tcp --dport 10000:10100 -j ACCEPT

# 默认拒绝
iptables -A INPUT -j DROP

端口安全配置

# config.yaml 安全配置
security:
  # API访问控制
  api:
    enable_auth: true
    allowed_ips:
      - "192.168.1.0/24"
      - "10.0.0.0/8"
    
  # 隧道安全
  tunnel:
    enable_tls: true
    cert_file: "/etc/ssl/server.crt"
    key_file: "/etc/ssl/server.key"
    client_ca: "/etc/ssl/ca.crt"
    
  # 端口范围限制
  port_range:
    blacklist:
      - 22    # SSH
      - 3389  # RDP
      - 5432  # PostgreSQL

2. 传输安全

TLS配置示例

// 服务器端TLS配置
func createTLSConfig() *tls.Config {
    cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
    if err != nil {
        log.Fatal(err)
    }
    
    caCert, err := ioutil.ReadFile("ca.crt")
    if err != nil {
        log.Fatal(err)
    }
    
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)
    
    return &tls.Config{
        Certificates: []tls.Certificate{cert},
        ClientAuth:   tls.RequireAndVerifyClientCert,
        ClientCAs:    caCertPool,
        MinVersion:   tls.VersionTLS12,
    }
}

3. 访问控制

JWT认证示例

// API认证中间件
func authMiddleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        token := r.Header.Get("Authorization")
        if token == "" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        
        // 验证JWT token
        if !validateJWT(token) {
            http.Error(w, "Invalid token", http.StatusUnauthorized)
            return
        }
        
        next(w, r)
    }
}

4. 监控和审计

安全事件监控

# 监控脚本示例
#!/bin/bash

# 监控异常连接
netstat -an | grep :9000 | wc -l > /var/log/tunnel-connections.log

# 监控失败的认证尝试
grep "Unauthorized" /var/log/go-tunnel/server.log | tail -10

# 监控端口扫描
iptables -L -n -v | grep DROP

5. 生产环境清单

部署前检查清单

  • 网络配置

    • 防火墙规则配置正确
    • 端口范围合理设置
    • DNS解析正确
  • 安全配置

    • TLS证书有效
    • 认证机制启用
    • 访问控制列表配置
  • 性能配置

    • 缓冲区大小优化
    • 连接池配置合理
    • 资源限制设置
  • 监控配置

    • 日志记录正常
    • 监控指标收集
    • 告警规则配置
  • 备份和恢复

    • 数据库定期备份
    • 配置文件备份
    • 恢复流程测试

故障排查指南

常见问题诊断流程

flowchart TD
    Problem[问题发生] --> Identify{问题识别}
    
    Identify -->|连接问题| ConnIssue[连接问题]
    Identify -->|性能问题| PerfIssue[性能问题]
    Identify -->|隧道问题| TunnelIssue[隧道问题]
    
    ConnIssue --> CheckPort{检查端口}
    CheckPort -->|端口被占用| PortSolution[更换端口或停止占用进程]
    CheckPort -->|端口超范围| RangeSolution[调整端口范围配置]
    CheckPort -->|防火墙| FirewallSolution[配置防火墙规则]
    
    PerfIssue --> CheckResource{检查资源}
    CheckResource -->|CPU高| CPUSolution[优化算法或增加服务器]
    CheckResource -->|内存高| MemSolution[调整缓冲区或检查内存泄漏]
    CheckResource -->|网络慢| NetSolution[检查网络质量]
    
    TunnelIssue --> CheckTunnel{检查隧道}
    CheckTunnel -->|连接断开| ReconnectSolution[自动重连机制]
    CheckTunnel -->|认证失败| AuthSolution[检查服务器地址和端口]
    CheckTunnel -->|协议错误| ProtocolSolution[检查版本兼容性]
    
    style Problem fill:#ffebee
    style ConnIssue fill:#fff3e0
    style PerfIssue fill:#e3f2fd
    style TunnelIssue fill:#f3e5f5

问题分类与解决方案

🔌 连接类问题

问题 1: 端口映射创建失败

# 诊断命令
netstat -tlnp | grep :10001
lsof -i :10001

# 解决方案
1. 检查端口是否被占用
2. 确认端口在配置范围内
3. 检查权限1024以下端口需要root权限

问题 2: 外部客户端无法连接

# 诊断命令
telnet server_ip 10001
nmap -p 10001 server_ip

# 解决方案
1. 检查防火墙设置
2. 确认服务器监听正确的接口
3. 验证端口映射是否正确创建

🚀 性能类问题

问题 3: 数据传输缓慢

graph LR
    SlowTransfer[传输缓慢] --> CheckNetwork{网络检查}
    CheckNetwork -->|延迟高| Latency[网络延迟问题]
    CheckNetwork -->|带宽低| Bandwidth[带宽限制]
    CheckNetwork -->|正常| ConfigCheck[配置检查]
    
    ConfigCheck --> BufferSize[调整缓冲区大小]
    ConfigCheck --> ConcurrencyLimit[检查并发限制]
    
    Latency --> OptimizeRoute[优化网络路由]
    Bandwidth --> UpgradeBandwidth[升级带宽]
    
    style SlowTransfer fill:#ffebee
    style Latency fill:#fff3e0
    style Bandwidth fill:#e3f2fd

调优建议:

// 调整缓冲区大小
const BufferSize = 64 * 1024  // 64KB for high throughput

// 调整TCP参数
conn.(*net.TCPConn).SetNoDelay(true)
conn.(*net.TCPConn).SetKeepAlive(true)

🔗 隧道类问题

问题 4: 隧道连接不稳定

诊断步骤:

# 1. 检查隧道服务器状态
curl http://server:8080/health

# 2. 检查网络连通性  
ping server_ip
traceroute server_ip

# 3. 检查客户端日志
./client -server server:9000 -debug

解决方案:

  • 配置更短的心跳间隔
  • 增加重连重试次数
  • 使用更稳定的网络连接

日志分析

日志级别说明

graph LR
    subgraph "日志级别"
        Debug[DEBUG] --> Info[INFO]
        Info --> Warn[WARN]
        Warn --> Error[ERROR]
        Error --> Fatal[FATAL]
    end
    
    subgraph "内容说明"
        Debug --> DebugContent[详细调试信息]
        Info --> InfoContent[一般运行信息]
        Warn --> WarnContent[警告信息]
        Error --> ErrorContent[错误信息]
        Fatal --> FatalContent[致命错误]
    end
    
    style Debug fill:#e8f5e8
    style Warn fill:#fff3e0
    style Error fill:#ffebee
    style Fatal fill:#ffcdd2

关键日志模式

# 隧道连接日志
grep "隧道客户端已连接" server.log
grep "隧道客户端已断开" server.log

# 端口映射日志
grep "端口转发启动" server.log
grep "端口转发已停止" server.log

# 错误日志
grep "ERROR\|FATAL" server.log

# 性能日志
grep "连接建立\|连接关闭" server.log | wc -l

监控设置

Prometheus指标示例

# prometheus.yml 配置示例
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'go-tunnel'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/metrics'
    scrape_interval: 5s

告警规则示例

groups:
  - name: go-tunnel
    rules:
      - alert: TunnelDisconnected
        expr: tunnel_connected == 0
        for: 30s
        labels:
          severity: critical
        annotations:
          summary: "隧道连接断开"
          
      - alert: HighConnectionCount
        expr: active_connections > 1000
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "连接数过高"

开发和贡献

开发环境设置

# 克隆项目
git clone <repository-url>
cd go-tunnel/src

# 安装开发依赖
go mod download
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

# 代码格式化
goimports -w .
golangci-lint run

编译选项

# 开发编译
make dev

# 生产编译
make release

# 交叉编译
make cross-compile

# 具体平台编译
GOOS=linux GOARCH=amd64 go build -o server-linux ./server
GOOS=windows GOARCH=amd64 go build -o server.exe ./server
GOOS=darwin GOARCH=amd64 go build -o server-mac ./server

测试套件

# 运行所有测试
make test

# 运行单元测试
go test ./... -v

# 运行集成测试
go test ./test -v

# 运行基准测试
go test -bench=. ./...

# 测试覆盖率
go test -cover ./...

代码贡献指南

  1. 分支策略: 使用 Git Flow 工作流
  2. 提交规范: 遵循 Conventional Commits
  3. 代码审查: 所有PR需要代码审查
  4. 测试要求: 新功能需要对应测试

版本更新日志

v2.0.0 (2025-10-14) - 重大更新

🚀 新增特性

  • 重新设计隧道协议: 采用自定义应用层协议 | 版本(1B) | 类型(1B) | 长度(4B) | 数据 |
  • 透明代理机制: 隧道对外部完全不可见,实现真正的透明转发
  • 多路复用支持: 单个隧道连接支持多个并发TCP会话
  • 连接生命周期管理: 实现连接请求/响应/数据/关闭的完整流程
  • 心跳保活机制: 自动检测和维护隧道连接状态

🔧 技术改进

  • 协议版本控制: 支持协议版本检查和兼容性处理
  • 错误处理优化: 完善的错误边界和异常恢复机制
  • 性能优化: 优化缓冲区管理和并发控制
  • 测试覆盖: 全面的单元测试和集成测试

📋 协议消息类型

  • 0x01 - 连接请求 (ConnectRequest)
  • 0x02 - 连接响应 (ConnectResponse)
  • 0x03 - 数据传输 (Data)
  • 0x04 - 关闭连接 (Close)
  • 0x05 - 心跳保活 (KeepAlive)

🛠️ 重构组件

  • 服务器端: server/tunnel/tunnel.go - 完全重写
  • 客户端: client/tunnel/client.go - 完全重写
  • 测试套件: 新增协议测试和性能测试

v1.0.0 (2024-01-01) - 初始版本

基础功能

  • 端口转发功能
  • 基础内网穿透
  • HTTP API 管理
  • SQLite 持久化存储
  • 自动重连机制

技术规范

协议兼容性

版本 协议格式 兼容性 状态
v2.0+ 版本+类型+长度+数据 向后兼容 当前
v1.x 长度+连接ID+数据 已弃用 不推荐

性能基准

在标准测试环境下的性能指标:

指标 数值 说明
并发连接数 10,000+ 单服务器实例
吞吐量 1GB/s 千兆网络环境
延迟增加 <5ms 相比直连的额外延迟
内存使用 <100MB 1000个活跃连接
CPU使用 <30% 单核,高负载场景

系统要求

最低要求

  • 操作系统: Linux/macOS/Windows
  • Go版本: 1.19+
  • 内存: 128MB
  • CPU: 单核
  • 网络: 10Mbps

推荐配置

  • 操作系统: Linux (Ubuntu 20.04+/CentOS 8+)
  • Go版本: 1.21+
  • 内存: 512MB+
  • CPU: 双核+
  • 网络: 100Mbps+
  • 存储: SSD

许可证

MIT License - 详见 LICENSE 文件

社区和支持

  • 文档: 本README和代码注释
  • 问题反馈: GitHub Issues
  • 功能请求: GitHub Discussions
  • 安全问题: 请私密联系维护者

致谢

感谢所有为这个项目做出贡献的开发者和用户。


Go-Tunnel - 高性能、生产就绪的TCP端口转发和内网穿透解决方案