Go to file
yanglc c87104ad2a
add readme file
2026-05-20 16:28:05 +08:00
README.md add readme file 2026-05-20 16:28:05 +08:00
tunnel-generator.sh first commit 2026-05-20 16:21:04 +08:00

README.md

TunnelGen

GRE/VXLAN 隧道服务生成器 - 自动生成 systemd 服务文件,支持 IPv4/IPv6IPv6 支持 PBR 防止 bird 路由冲突。

功能特性

  • 双协议支持: IPv4 和 IPv6
  • 三种隧道类型: GRE、VXLAN、SSH TUN
  • 智能检测: 自动检测网络接口和网关
  • IPv6 PBR: 创建专用路由表,防止 bird 路由覆盖导致隧道断联
  • SSH TUN: TCP 隧道方案,适用于 UDP 受限环境
  • systemd 集成: 生成开机自启的服务文件
  • 交互式界面: 简单易用的中文交互界面

快速开始

环境要求

  • Linux 系统
  • root 权限
  • ip 命令 (iproute2)

安装

# 克隆仓库
git clone https://github.com/yanglc721/tunnelgen.git
cd tunnelgen

# 添加执行权限
chmod +x tunnel-generator.sh

# 运行脚本
sudo ./tunnel-generator.sh

快速安装

# 下载脚本
curl -fsSL https://raw.githubusercontent.com/yanglc721/tunnelgen/main/tunnel-generator.sh -o tunnel-generator.sh

# 添加执行权限
chmod +x tunnel-generator.sh

# 运行脚本
sudo ./tunnel-generator.sh

使用说明

交互式配置

运行脚本后,按照提示进行配置:

========================================
    GRE/VXLAN 隧道服务生成器
========================================

选择 IP 版本:
  1) IPv4
  2) IPv6

请输入选项 [1-2]: 2
[信息] 已选择: ipv6

选择隧道类型:
  1) GRE
  2) VXLAN

请输入选项 [1-2]: 1
[信息] 已选择: gre

请输入隧道名称 (例如: gre-hk1, vxlan-hk4): gre-hk1

请输入本地 IPv6 地址: 2001:db8:1000::1
请输入远端 IPv6 地址: 2001:db8:2000::1

可用的网络接口:
=====================================
  [1] eth0         状态:UP       IPv6: 2001:db8:1000::1
  [2] ix-ams      状态:UP       IPv6: 2001:db8:9000::1
=====================================

[信息] 自动检测到网关: fe80::1

========================================
配置摘要:
========================================
隧道名称:       gre-hk1
IP 版本:        ipv6
隧道类型:       gre
本地 IP:        2001:db8:1000::1
远端 IP:        2001:db8:2000::1
接口:           eth0
网关:           fe80::1
PBR:            已启用 (使用专用路由表)
========================================

生成服务文件? [Y/n]: y
立即启用并启动服务? [Y/n]: y

配置参数说明

参数 说明 示例
IP 版本 选择 IPv4 或 IPv6 ipv6
隧道类型 GRE / VXLAN / SSH TUN gre
隧道名称 服务标识符,用于生成服务文件名 gre-hk1
本地 IP 本地隧道端点地址 2001:db8:1000::1
远端 IP 对端隧道端点地址 2001:db8:2000::1
接口 物理网络接口 (承载隧道流量) eth0
网关 PBR 使用的网关 (仅 IPv6) fe80::1
VNI VXLAN 网络标识符 (仅 VXLAN) 100
目标端口 VXLAN 端口 (仅 VXLAN) 4789

SSH TUN 特有参数

参数 说明 示例
角色 服务端 (公网 IP) 或客户端 (NAT 内) server / client
SSH 端口 SSH 服务端口 22
SSH 用户 SSH 登录用户 root
隧道 IP 类型 隧道内部 IP 版本 ipv4 / ipv6
本地隧道 IP 隧道内的本地 IP fd00::1
对端隧道 IP 隧道内的对端 IP fd00::2

生成的文件

运行脚本后会生成以下文件:

文件路径 说明
/etc/systemd/system/<隧道名>.service systemd 服务文件
/usr/local/sbin/<隧道名>-pbr-setup.sh PBR 设置脚本 (仅 IPv6 GRE/VXLAN)
/usr/local/sbin/<隧道名>-ip-config.sh IP 配置脚本 (仅 SSH TUN 服务端)
/etc/iproute2/rt_tables 路由表定义 (追加,仅 IPv6 GRE/VXLAN)

服务文件示例 (IPv6 GRE)

[Unit]
Description=GRE 隧道 gre-hk1
After=network.target network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/usr/local/sbin/gre-hk1-pbr-setup.sh
ExecStart=/bin/sh -c "ip tunnel add gre-hk1 mode ip6gre remote 2001:db8:2000::1 local 2001:db8:1000::1 ttl 255 && ip link set gre-hk1 up"
ExecStop=/bin/sh -c "ip link set gre-hk1 down; ip tunnel del gre-hk1; ip -6 rule del to 2001:db8:2000::1 table gre-hk1_underlay priority 50 || true; ip -6 rule del from 2001:db8:1000::1 table gre-hk1_underlay priority 51 || true"

[Install]
WantedBy=multi-user.target

IPv6 PBR 原理

问题背景

当运行 bird 等 BGP 路由软件时bird 会向 main 路由表注入路由。这可能导致:

  1. 隧道端点的路由被覆盖
  2. 到对端 IP 的流量被路由到隧道接口
  3. 形成路由环路,导致隧道断联
┌─────────────────────────────────────────────┐
│  问题: bird 注入路由后 main 表的状态         │
├─────────────────────────────────────────────┤
│  2001:db8:2000::1 via ... dev gre-hk1       │  ← 被覆盖!
│  导致隧道流量又被路由回隧道,形成死循环      │
└─────────────────────────────────────────────┘

解决方案

创建一个 bird 无法影响的专用路由表

┌─────────────────────────────────────────────┐
│  流量到对端IP                                │
│  destination = 2001:db8:2000::1            │
└─────────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────────┐
│  PBR规则priority 50                        │
│  to <remote> → table gre-hk1_underlay       │
└─────────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────────┐
│  gre-hk1_underlay 表干净不受bird影响   │
│                                             │
│  2001:db8:2000::1 via fe80::1 dev eth0      │
│  ↑ 正确!走物理网卡                          │
└─────────────────────────────────────────────┘

PBR 规则优先级

优先级 50: to <远端IP> table <隧道名>_underlay
优先级 51: from <本地IP> table <隧道名>_underlay
   ...
优先级 32766: from all lookup main (默认规则)

PBR 规则优先级 50-51在默认 main 表查询 (32766) 之前执行,确保隧道端点流量使用干净的路由表。

服务管理

# 启动服务
systemctl start gre-hk1

# 停止服务
systemctl stop gre-hk1

# 查看状态
systemctl status gre-hk1

# 开机自启
systemctl enable gre-hk1

# 禁用开机自启
systemctl disable gre-hk1

验证隧道

检查隧道接口

ip link show gre-hk1
ip -6 addr show gre-hk1

检查 PBR 规则 (IPv6)

# 查看 PBR 规则
ip -6 rule show | grep priority

# 查看专用路由表
ip -6 route show table gre-hk1_underlay

# 验证路由是否正确
ip -6 route get 2001:db8:2000::1
# 应显示: dev eth0 (物理接口),而不是 dev gre-hk1

测试连通性

# ping 对端隧道地址
ping6 2001:db8:2000::1

# 或通过隧道 ping 对端内网地址
ping6 <对端内网IPv6>

删除隧道

# 停止并禁用服务
systemctl stop gre-hk1
systemctl disable gre-hk1

# 删除服务文件
rm /etc/systemd/system/gre-hk1.service
rm /usr/local/sbin/gre-hk1-pbr-setup.sh  # 如果存在

# 重载 systemd
systemctl daemon-reload

# (可选) 删除路由表定义
# 编辑 /etc/iproute2/rt_tables删除对应行

注意事项

  1. 多网卡环境: 请确保选择正确的物理网卡IX 专用网卡通常无法提供互联网服务

  2. 网关变更: 如果物理网关变更,需要更新 PBR 脚本并重启服务

    # 编辑 PBR 脚本
    vi /usr/local/sbin/gre-hk1-pbr-setup.sh
    # 重启服务
    systemctl restart gre-hk1
    
  3. 防火墙: 确保 GRE/VXLAN 协议通过防火墙

    # GRE
    ip6tables -A INPUT -p ipv6-encap -j ACCEPT
    ip6tables -A OUTPUT -p ipv6-encap -j ACCEPT
    
    # VXLAN (UDP 端口)
    ip6tables -A INPUT -p udp --dport 4789 -j ACCEPT
    ip6tables -A OUTPUT -p udp --dport 4789 -j ACCEPT
    
  4. MTU: GRE 隧道会减少 MTU可能需要调整

    ip link set gre-hk1 mtu 1400
    

与 bird 配合

在 bird 配置中,确保 kernel 协议正确配置:

protocol kernel {
    scan time 60;
    import all;
    export all;
    kernel table 254;  # main 表
}

# 隧道接口路由由 PBR 处理,无需在 bird 中特殊配置

支持的隧道类型

类型 IPv4 模式 IPv6 模式 特点
GRE gre ip6gre 标准 IP 隧道,开销小,性能最佳
VXLAN vxlan vxlan 支持 VNI适合数据中心
SSH TUN TCP TCP 基于 SSH适用于 UDP 受限环境

SSH TUN 隧道

SSH TUN 是基于 SSH 协议的 TCP 隧道,适用于 UDP 端口被阻挡的环境。

使用场景

  • UDP 端口被运营商或防火墙阻挡
  • 一端在 NAT 内,只有有限的公网端口
  • 需要加密传输的场景

隧道 IP 类型

SSH TUN 支持两种隧道内部 IP

类型 默认地址范围 说明
IPv4 10.0.0.1/24 适合 IPv4 内网通信
IPv6 fd00::1/64 适合 IPv6 内网通信(推荐)

配置步骤

服务端(有公网 IP

sudo ./tunnel-generator.sh
# 选择: IPv4 -> SSH TUN -> 服务端
# 选择隧道 IP 类型: IPv6
# 输入 SSH 端口、用户
# 隧道 IP 默认: fd00::1 (服务端) / fd00::2 (客户端)

服务端会自动:

  1. 启用 SSH PermitTunnel
  2. 重启 SSH 服务
  3. 生成 IP 配置脚本

客户端NAT 内)

sudo ./tunnel-generator.sh
# 选择: IPv4 -> SSH TUN -> 客户端
# 输入服务端 IP: 23.154.9.54
# 选择隧道 IP 类型: IPv6
# 隧道 IP 默认: fd00::2 (本地) / fd00::1 (对端)

客户端会自动:

  1. 检查/生成 SSH 密钥
  2. 显示公钥(需要添加到服务端)
  3. 创建 systemd 服务(自动连接和重连)

添加 SSH 公钥

在服务端添加客户端的公钥:

# 在服务端执行
echo 'ssh-ed25519 AAAA... client@hostname' >> /root/.ssh/authorized_keys

验证连接IPv6 隧道 IP

# 客户端
ping6 fd00::1  # 服务端隧道 IP

# 服务端(连接建立后先运行 IP 配置脚本)
/usr/local/sbin/<隧道名>-ip-config.sh
ping6 fd00::2  # 客户端隧道 IP

性能说明

隧道类型 典型速度 CPU 占用
GRE/VXLAN 线速 (1Gbps+)
SSH TUN 100-500 Mbps 中等

SSH TUN 由于 SSH 加密开销,性能低于 GRE/VXLAN但足以满足大多数应用场景。

常见问题

Q: IPv6 隧道启动后无法连通?

检查 PBR 是否生效:

ip -6 route get <远端IP>

应显示走物理接口,而不是隧道接口。

Q: bird 重启后隧道断开?

确保 PBR 规则优先级正确 (50-51),在 main 表之前查询。

Q: 如何查看当前所有隧道?

# GRE 隧道
ip tunnel show

# 所有虚拟接口
ip link show type gre
ip link show type vxlan

许可证

MIT License

贡献

欢迎提交 Issue 和 Pull Request

作者

yanglc721

链接