add readme file

main
yanglc 2026-05-20 16:28:05 +08:00
parent 4f374c54a3
commit c87104ad2a
Signed by: yanglc
GPG Key ID: 96D67AF34B199F2A
1 changed files with 456 additions and 0 deletions

456
README.md Normal file
View File

@ -0,0 +1,456 @@
# 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)
### 安装
```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 <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) 之前执行,确保隧道端点流量使用干净的路由表。
## 服务管理
```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)