diff --git a/README.md b/README.md new file mode 100644 index 0000000..b535aca --- /dev/null +++ b/README.md @@ -0,0 +1,456 @@ +# TunnelGen + +GRE/VXLAN 隧道服务生成器 - 自动生成 systemd 服务文件,支持 IPv4/IPv6,IPv6 支持 PBR 防止 bird 路由冲突。 + +## 功能特性 + +- **双协议支持**: IPv4 和 IPv6 +- **三种隧道类型**: GRE、VXLAN、SSH TUN +- **智能检测**: 自动检测网络接口和网关 +- **IPv6 PBR**: 创建专用路由表,防止 bird 路由覆盖导致隧道断联 +- **SSH TUN**: TCP 隧道方案,适用于 UDP 受限环境 +- **systemd 集成**: 生成开机自启的服务文件 +- **交互式界面**: 简单易用的中文交互界面 + +## 快速开始 + +### 环境要求 + +- Linux 系统 +- root 权限 +- `ip` 命令 (iproute2) + +### 安装 + +```bash +# 克隆仓库 +git clone https://github.com/yanglc721/tunnelgen.git +cd tunnelgen + +# 添加执行权限 +chmod +x tunnel-generator.sh + +# 运行脚本 +sudo ./tunnel-generator.sh +``` + +### 快速安装 + +```bash +# 下载脚本 +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) + +```ini +[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 → 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) 之前执行,确保隧道端点流量使用干净的路由表。 + +## 服务管理 + +```bash +# 启动服务 +systemctl start gre-hk1 + +# 停止服务 +systemctl stop gre-hk1 + +# 查看状态 +systemctl status gre-hk1 + +# 开机自启 +systemctl enable gre-hk1 + +# 禁用开机自启 +systemctl disable gre-hk1 +``` + +## 验证隧道 + +### 检查隧道接口 + +```bash +ip link show gre-hk1 +ip -6 addr show gre-hk1 +``` + +### 检查 PBR 规则 (IPv6) + +```bash +# 查看 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 +``` + +### 测试连通性 + +```bash +# ping 对端隧道地址 +ping6 2001:db8:2000::1 + +# 或通过隧道 ping 对端内网地址 +ping6 <对端内网IPv6> +``` + +## 删除隧道 + +```bash +# 停止并禁用服务 +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 脚本并重启服务 + ```bash + # 编辑 PBR 脚本 + vi /usr/local/sbin/gre-hk1-pbr-setup.sh + # 重启服务 + systemctl restart gre-hk1 + ``` + +3. **防火墙**: 确保 GRE/VXLAN 协议通过防火墙 + ```bash + # 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,可能需要调整 + ```bash + 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) + +```bash +sudo ./tunnel-generator.sh +# 选择: IPv4 -> SSH TUN -> 服务端 +# 选择隧道 IP 类型: IPv6 +# 输入 SSH 端口、用户 +# 隧道 IP 默认: fd00::1 (服务端) / fd00::2 (客户端) +``` + +服务端会自动: +1. 启用 SSH PermitTunnel +2. 重启 SSH 服务 +3. 生成 IP 配置脚本 + +#### 客户端(NAT 内) + +```bash +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 公钥 + +在服务端添加客户端的公钥: + +```bash +# 在服务端执行 +echo 'ssh-ed25519 AAAA... client@hostname' >> /root/.ssh/authorized_keys +``` + +#### 验证连接(IPv6 隧道 IP) + +```bash +# 客户端 +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 是否生效: +```bash +ip -6 route get <远端IP> +``` +应显示走物理接口,而不是隧道接口。 + +### Q: bird 重启后隧道断开? + +确保 PBR 规则优先级正确 (50-51),在 main 表之前查询。 + +### Q: 如何查看当前所有隧道? + +```bash +# GRE 隧道 +ip tunnel show + +# 所有虚拟接口 +ip link show type gre +ip link show type vxlan +``` + +## 许可证 + +MIT License + +## 贡献 + +欢迎提交 Issue 和 Pull Request! + +## 作者 + +[yanglc721](https://github.com/yanglc721) + +## 链接 + +- [GitHub 仓库](https://github.com/yanglc721/tunnelgen) +- [问题反馈](https://github.com/yanglc721/tunnelgen/issues)