参考与致谢:
一、什么是 GRE?
GRE(Generic Routing Encapsulation,通用路由封装) 是一种隧道协议,能在两个网络节点之间建立一条虚拟的点对点连接,将封装后的数据包通过公网传输,实现两端内网的互联互通。
简单理解:在互联网上拉一根虚拟网线,把两个私网连起来,让它们像在同一个局域网里一样通信。
二、为什么要 GRE?
在物联网专线场景中,我们的业务涉及移动机房、阿里云 VPC、企业内网等多个网络节点,需要通过互联网将它们打通。面临以下问题:
专线昂贵:物理专线成本高、部署周期长
端口映射繁琐:传统方案需为每个终端维护端口映射表,管理复杂
无法透明通信:服务器无法直接看到终端真实 IP,日志溯源困难
扩展性差:新增设备或服务需要反复调整网络配置
GRE 隧道解决了这些问题:
透明通信:服务器直接看到终端真实 IP(如 10.6.1.100),无需端口映射,通信如同本地局域网。
路由即通:只需添加一条路由(如 ip route add 10.6.0.0/22 via 172.16.0.1),即可打通整个网段。
广泛兼容:支持 TCP/UDP/ICMP 等所有基于 IP 的协议。
精准安全:防火墙可直接基于真实 IP 设置细粒度策略。
一句话概括:GRE 让每个终端都有了"直拨号码",网络回归本质通信,化繁为简。
传统方案 vs GRE 方案
传统专线方案:
VPC A ─── 物理专线 ─── VPC B
(成本高、周期长)
GRE隧道方案(虚拟专线):
VPC A ─── GRE over Internet ─── VPC B
(低成本、灵活部署)下面将结合真实的跨公网互联需求,分场景记录 GRE 隧道的搭建步骤。场景一至三均为物联网专线业务,用于打通移动机房与客户机房,实现专网卡内网与客户内网的互访。
三、通用前置配置
以下配置在所有场景中均需完成,请根据目标平台执行相应操作。
1、开启 IP 转发
# 检查是否已开启(返回 1 表示已开启)
cat /proc/sys/net/ipv4/ip_forward
# 临时生效
echo 1 > /proc/sys/net/ipv4/ip_forward永久生效:
2、防火墙放行 GRE
# 一、CentOS 7
# 1、iptables
iptables -A INPUT -p gre -j ACCEPT
# 持久化(详见《CentOS7 iptables 使用》)
iptables-save > /etc/iptables.rules
iptables-restore < /etc/iptables.rules # 重启执行
# 2、firewalld
# 加入到规则链 INPUT_direct
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p gre -j ACCEPT
firewall-cmd --reload
# 验证(查看防火墙 GRE 是否放行)
iptables -L INPUT -n -v | grep 47
# 二、OpenWrt(UCI)
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-GRE'
uci set firewall.@rule[-1].proto='gre'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart💡 企业级设备(华为/H3C/思科等):通常可通过 Web 管理界面或图形化安全策略配置,在防火墙策略中放行 协议号 47(GRE) 即可,具体路径请参考对应设备手册。
3、安全组(云厂商)
阿里云/腾讯云等需在控制台放行 协议号 47(GRE)。
⚠️ GRE 是三层协议(协议号 47),不是 TCP/UDP 端口,安全组中需选择"GRE"或"自定义协议"并填入 47。
四、基本参数
以下参数在所有场景通用,均以本端(云服务器/企业侧)视角描述:
注意事项
云服务器隧道创建命令中,local 必须使用内网 IP(如 172.30.0.7)。因为云厂商采用 NAT 映射,公网 IP 不在本地网卡上(云平台 DNAT)。
对端 remote 指向本端公网 IP(114.67.200.161)。
其他设备(如物理机、路由器)local 使用本地公网 IP 即可。
五、分场景 GRE 配置
场景一:阿里云 ECS 到移动机房
本端配置命令(CentOS 7):
# 加载 GRE 内核模块
modprobe ip_gre
lsmod | grep gre
# 创建 GRE 隧道(remote 指向移动机房公网 IP,local 用本端内网 IP)
ip tunnel add tun1 mode gre remote 1.2.3.4 local 172.30.0.7 ttl 255
# 启动隧道
ip link set tun1 up mtu 1400
# 配置隧道 IP(本端为 172.16.0.2,对端为 172.16.0.1)
ip addr add 172.16.0.2/30 dev tun1
# 添加路由(访问移动机房内网走隧道)
ip route add 172.18.96.0/20 via 172.16.0.1 dev tun1 metric 100
# 备用隧道配置相同,仅调整 metric 为 200 实现主备切换对端(移动机房)配置参考:
以下为移动机房侧的配置逻辑,用于理解对端如何将流量引入隧道。
# 移动机房侧 GRE 隧道配置
ip tunnel add gre-aliyun mode gre remote 114.67.200.161 local <移动机房内网IP> ttl 255
ip link set gre-aliyun up mtu 1400
ip addr add 172.16.0.1/30 dev gre-aliyun
# 添加默认路由:所有流量通过隧道发往本端(云服务器)
# metric 100 作为备用路由,低于主路由优先级
ip route add default via 172.16.0.2 dev gre-aliyun metric 100💡 配置解读:ip route add default via 172.16.0.2 dev gre-aliyun metric 100 的含义是——移动机房将所有出站流量通过 GRE 隧道转发至本端(云服务器/企业侧),由本端进行后续路由或 NAT 处理。
本端配置持久化(CentOS 7):
# (1)使用 systemd service
cat > /etc/systemd/system/gre-tun1.service << 'EOF'
[Unit]
Description=GRE Tunnel tun1
After=network.target network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
# 启动前加载 GRE 内核模块
ExecStartPre=/usr/sbin/modprobe ip_gre
# 创建 GRE 隧道(remote 指向移动机房公网 IP,local 用本端内网 IP)
ExecStart=/usr/sbin/ip tunnel add tun1 mode gre remote 1.2.3.4 local 172.30.0.7 ttl 255
# 启动隧道
ExecStart=/usr/sbin/ip link set tun1 up mtu 1400
# 配置隧道 IP(本端为 172.16.0.2,对端为 172.16.0.1)
ExecStart=/usr/sbin/ip addr add 172.16.0.2/30 dev tun1
# 添加路由(访问移动机房内网走隧道)
ExecStart=/usr/sbin/ip route add 172.18.96.0/20 via 172.16.0.1 dev tun1 metric 100
# 停止时清理(反向顺序:先删路由,再删 IP,最后删隧道)
ExecStop=/usr/sbin/ip route del 172.18.96.0/20 via 172.16.0.1 dev tun1 metric 100 2>/dev/null
ExecStop=/usr/sbin/ip addr del 172.16.0.2/30 dev tun1 2>/dev/null
ExecStop=/usr/sbin/ip tunnel del tun1 2>/dev/null
[Install]
WantedBy=multi-user.target
EOF
# 加载并启用
systemctl daemon-reload
systemctl enable gre-tun1
systemctl start gre-tun1
# 查看日志
journalctl -u gre-tun1 -n 20
journalctl -u gre-tun1 -f场景二:企业路由器/华为/H3C 到对端
本端路由器配置(华为/H3C)
以下为华为/H3C 路由器 GRE 配置模板,实际参数请替换为业务实际值。
# 创建 Tunnel 接口
interface Tunnel0/0/0
tunnel-protocol gre
ip address 172.16.0.2 255.255.255.252
source <路由器公网IP> # 本端公网 IP
destination 1.2.3.4 # 对端公网 IP
# 添加静态路由(访问对端内网走隧道)
ip route-static 172.18.96.0 255.255.248.0 Tunnel0/0/0
# 备用隧道配置相同,仅设置 preference 为 70 实现主备切换
# preference 默认 60,越小优先级越高。例如:
ip route-static 10.98.0.0 255.255.248.0 Tunnel0/0/6 preference 70场景三:OpenWrt 到对端
本端 OpenWrt 配置
详见《GRE 隧道配置(OpenWrt 实战篇)》,关键配置如下:
静态 IP 配置:WAN 口配置本端公网 IP
防火墙放行 GRE:协议号 47
GRE 隧道脚本:创建 /etc/init.d/gre-tun1,参数如下:
ip tunnel add tun1 mode gre remote <对端公网IP> local <OpenWrt公网IP> ttl 255
ip link set tun1 up mtu 1400
ip addr add 172.16.0.2/30 dev tun1
ip route add <对端内网网段> via 172.16.0.1 dev tun1 metric 100开机自启:写入 /etc/rc.local
六、连通验证
以下命令所有场景通用,用于确认隧道是否建立成功。
# 0. 检查对端公网 IP 是否可达
# -c:发包数量
# -W:超时时间
ping -c 3 -W 2 <对端公网IP>
# 1. 检查 GRE 内核模块是否加载
lsmod | grep gre
# 2. 检查隧道接口是否存在
ip link show tun1
# 3. 检查隧道 IP 是否配置正确
ip addr show tun1
# 4. 测试隧道对端 IP 是否可达
ping -I tun1 172.16.0.1
# 5. 测试对端内网 IP 是否可达
ping -I tun1 <对端内网IP>
# 6. 追踪路径
traceroute -i tun1 <对端内网IP>
# 7. 查看路由表
ip route show | grep tun1七、隧道与路由清理(还原)
测试或者配置错误时,需要清理 GRE 隧道及相关路由,恢复网络初始状态。
# 删除单条隧道
ip tunnel del tun1 2>/dev/null
# 删除对应路由(如果有)
ip route del 172.18.96.0/20 via 172.16.0.1 dev tun1 2>/dev/null八、内网互访验证
隧道建立并确认连通后,即可实现两端内网资源的互访。
本端内网 (172.30.0.0/20)
↕
GRE 隧道 (tun1: 172.16.0.2 ↔ 172.16.0.1)
↕
对端内网⚠️ 策略路由、NAT 转发、抓包分析等高级流量管控详见:《GRE 隧道转发与抓包分析》。