恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
GRE隧道实战:从MTU故障到GRE over IPsec的运维避坑指南
首页
资讯中心
/
GRE隧道实战:从MTU故障到GRE over IPsec的运维避坑指南
GRE隧道实战:从MTU故障到GRE over IPsec的运维避坑指南
发布时间:2026/10/18 5:36:26
1. 从一个看起来通了但实际没通的故障说起GRE全称Generic Routing Encapsulation通用路由封装。这名字听起来很学术但如果你做过网络运维大概率在某个深夜被它折腾过。我第一次接触GRE是在一个跨机房互联的项目里两个机房的私网需要互通中间隔着一段运营商网络。当时想得很简单两边各起一个GRE隧道把私网路由指过去收工。结果隧道状态显示up接口能ping通但业务流量就是过不去。排查了整整一个下午才发现是MTU的问题——GRE封装会额外增加24字节的开销加上外层IP头20字节总共多出44字节导致大包被丢弃小包正常。这就是GRE最典型的看起来通了但实际没通。所以这篇内容我想聊的不是教科书上那些定义而是GRE隧道在实际工程中到底怎么用、为什么这么用、以及那些只有踩过坑才知道的细节。适合已经了解基本网络概念、需要把GRE真正落地到项目里的运维和网络工程师。如果你只是想知道GRE是什么网上有大把定义但如果你想搞清楚GRE在什么场景下比IPsec更合适、怎么配才能稳、出了问题从哪查起那接下来的内容应该对你有用。GRE的本质其实很朴素它就是一种把一种协议的数据包套在另一种协议的数据包里的方法。你可以把它想象成快递里的箱中箱——你要寄一个形状不规则的物品内层原始数据包直接寄不好寄于是先装进一个小箱子GRE封装再把小箱子放进标准的大纸箱外层IP包这样任何快递网络都能运送。收件人拆开大纸箱取出小箱子再打开小箱子拿到真正的物品。这个套娃的过程就是隧道。2. GRE封装结构里那些容易被忽略的字段2.1 外层IP头与GRE头的分工要理解GRE的行为必须先把它的封装结构拆开看。一个完整的GRE隧道包由三部分组成外层IP头、GRE头、内层原始数据包。外层IP头的源地址和目的地址分别是隧道两端接口的地址这是隧道能建立的基础。协议号字段填47标识这是一个GRE包。很多人配完隧道后不检查这个字段但如果中间有防火墙协议号47被拦了隧道就起不来——而且因为GRE本身没有认证机制你甚至不会收到任何报错只能看到隧道一直down。GRE头本身的结构值得细看。标志位和版本字段通常为0但如果你用到GRE的扩展能力比如带Key或带序列号这里就会有值。协议类型字段标识内层承载的是什么协议0x0800代表IPv40x86DD代表IPv60x8847代表MPLS。这个字段决定了隧道运什么货。2.2 Key字段与序列号的实际用途Key字段是一个4字节的标识符可以理解为隧道的门牌号。它的实际价值在于当多个GRE隧道终止在同一对设备上时用Key来区分不同的隧道。我见过一个场景两台核心设备之间需要跑三条不同业务的GRE隧道如果不加Key接收端无法区分哪个包属于哪条隧道配置就会冲突。加上Key之后每条隧道有独立的标识问题解决。序列号字段用于保证包的顺序。默认情况下GRE不启用序列号因为大多数内层协议如TCP自己有重传和排序机制。但在承载某些对顺序敏感的非IP协议时序列号就有意义了。不过要注意启用序列号会增加处理开销而且如果中间路径存在乱序序列号机制反而可能引入额外延迟。我的建议是除非有明确需求否则不要开。校验和字段同理。GRE头里的校验和只校验GRE头和内层包不包括外层IP头。启用它会增加每包的计算成本在高速链路上可能成为瓶颈。实际项目中我基本不启用GRE校验和而是依赖外层IP头的校验和以及内层协议自身的校验机制。2.3 MTU问题GRE隧道最大的隐形杀手回到开头那个故障。GRE封装增加的开销具体是外层IP头20字节 GRE头4字节基础情况下 24字节。如果外层还跑了IPsec那开销更大。标准以太网MTU是1500字节减去24字节隧道内层能承载的最大包就是1476字节。问题在于很多应用和协议默认使用1500字节的包而且设置了禁止分片位。当这样的包进入GRE隧道时设备发现加上封装头后超过了出口MTU但又不能分片只能丢弃。表现就是ping小包正常ping大包失败网页能打开但图片加载不全SSH能连上但一传文件就断。解决方案有三种。第一种是调整隧道接口的MTU和TCP MSS。把隧道接口MTU设为1476同时用ip tcp adjust-mss 1436让经过隧道的TCP连接协商更小的MSS。1436的计算方式是1476减去20字节TCP头再减去20字节IP头。第二种是在隧道两端启用路径MTU发现但这依赖中间网络配合实际环境中经常不靠谱。第三种是直接在外层网络上把MTU调大比如启用巨帧但这需要整条路径都支持跨运营商场景基本不可行。我个人的经验是不管三七二十一配GRE隧道时先把MTU和MSS调了。这个动作花不了两分钟但能省掉后面可能几个小时的排查。3. 什么时候该用GRE什么时候该换方案3.1 GRE与IPsec的分工逻辑很多人会问既然IPsec也能建隧道为什么还要用GRE答案在于两者解决的问题不同。IPsec的核心是安全——加密、认证、防篡改。GRE的核心是封装——把一种协议套进另一种协议里。它们不是竞争关系而是互补关系。GRE本身没有任何加密能力所有数据明文传输。这意味着如果你用纯GRE隧道跑敏感数据中间任何一跳都能看到内容。所以纯GRE只适合两种场景一是中间网络本身可信比如同一个数据中心内部的不同网段二是GRE只作为封装层上面再跑IPsec来加密。IPsec的问题在于它通常只支持单播IP流量而且配置复杂不同厂商设备之间的互通性经常出问题。GRE则简单得多而且能承载组播、广播、非IP协议。所以经典组合是GRE负责封装和承载多协议流量IPsec负责加密。这就是常说的GRE over IPsec。3.2 动态路由协议穿越GRE的实战价值GRE最实用的场景之一是让动态路由协议穿越不支持它的网络。比如两个站点之间隔着运营商网络你想跑OSPF让两边路由自动学习。但OSPF使用组播地址224.0.0.5运营商网络通常不转发组播。这时候GRE隧道就派上用场了隧道接口是一个点对点的逻辑链路OSPF可以在这个接口上正常跑组播包被GRE封装成单播包顺利穿过运营商网络。配置上隧道两端各起一个Tunnel接口配上网段地址然后在OSPF进程里把Tunnel接口的网段宣告出去。隧道建立后OSPF邻居关系会在Tunnel接口上形成两边路由自动同步。这个方案我在多个跨地域组网项目里用过稳定可靠。但要注意一个细节OSPF在Tunnel接口上的邻居关系建立依赖于隧道本身的可达性。如果隧道底层网络断了Tunnel接口会downOSPF邻居也会断。这其实是好事——避免了路由黑洞。但如果你在隧道上还跑了静态路由指向对端就要小心递归路由的问题静态路由指向Tunnel接口Tunnel接口的源地址又依赖底层网络路由如果底层路由丢失整个链路就断了。3.3 组播与广播流量穿越的注意事项GRE能承载组播和广播这是它比IPsec强的地方。但实际用的时候有几个坑。第一GRE隧道默认不转发广播需要在隧道接口上显式开启广播转发。第二组播流量进入隧道后外层是单播内层是组播接收端解封装后需要正确还原组播包。如果两端组播配置不一致流量就丢了。第三广播风暴的风险——如果隧道一端有广播风暴会通过隧道传到另一端。所以生产环境里我通常会在隧道接口上做广播抑制或风暴控制。4. 从零搭建一条GRE隧道的完整操作链路4.1 基础配置两端接口与隧道参数假设有两台设备A端公网地址是198.51.100.1私网网段是10.1.1.0/24B端公网地址是203.0.113.1私网网段是10.2.2.0/24。目标是通过GRE隧道让两个私网互通。A端配置interface Tunnel0 ip address 172.16.0.1 255.255.255.252 tunnel source 198.51.100.1 tunnel destination 203.0.113.1 tunnel mode gre ip ip mtu 1476 ip tcp adjust-mss 1436 ! interface GigabitEthernet0/0 ip address 198.51.100.1 255.255.255.0 ! interface GigabitEthernet0/1 ip address 10.1.1.1 255.255.255.0 ! ip route 10.2.2.0 255.255.255.0 Tunnel0B端配置对称interface Tunnel0 ip address 172.16.0.2 255.255.255.252 tunnel source 203.0.113.1 tunnel destination 198.51.100.1 tunnel mode gre ip ip mtu 1476 ip tcp adjust-mss 1436 ! interface GigabitEthernet0/0 ip address 203.0.113.1 255.255.255.0 ! interface GigabitEthernet0/1 ip address 10.2.2.1 255.255.255.0 ! ip route 10.1.1.0 255.255.255.0 Tunnel0这里有几个关键点。隧道接口的地址用了172.16.0.0/30这个私网网段只用了两个可用地址不浪费。tunnel source和destination分别指向对方的公网地址这是隧道能建立的前提。ip mtu和ip tcp adjust-mss是必须加的原因前面已经说过。静态路由把对端私网指向Tunnel接口这样流量才会进入隧道。4.2 验证隧道状态的三层检查法配完之后别急着收工按三层顺序检查。第一层物理和底层可达性。在A端ping B端的公网地址203.0.113.1必须通。如果不通隧道肯定起不来先查底层路由。第二层隧道接口状态。show interface Tunnel0看接口是否up协议是否up。如果接口up但协议down通常是tunnel destination不可达或者中间有防火墙拦了协议47。如果接口down检查tunnel source地址是否本地有效地址。第三层隧道内层连通性。在A端ping 172.16.0.2这是B端隧道接口地址。通了说明隧道本身工作正常。然后再ping 10.2.2.1这是B端私网接口地址。如果隧道内层通但私网不通检查静态路由和B端的回程路由。我习惯用show interface Tunnel0的输出里看几个关键计数packets input/output、CRC错误、drops。如果input有包但output没包可能是路由问题如果有drops且数值持续增长大概率是MTU问题。4.3 隧道建立不起来的排查顺序隧道起不来是最常见的问题。我的排查顺序是这样的先确认两端tunnel source和destination是否互为对方的地址。这个听起来很基础但我确实见过配错地址的情况——A端destination写了B端的私网地址而不是公网地址。再确认中间网络是否放行了协议47。GRE没有端口概念防火墙只能基于协议号过滤。如果中间有防火墙需要放行IP协议47。可以用telnet或traceroute辅助判断但最直接的方法是在两端抓包看GRE包有没有发出去、有没有收到。然后检查路由。tunnel destination地址必须在本地路由表里有明确的路由而且不能是默认路由指向Tunnel接口本身——这会造成递归路由隧道永远起不来。可以用show ip route 203.0.113.1确认走的是物理接口而不是Tunnel接口。最后检查ACL。如果设备上有ACL应用在物理接口的入方向可能会拦掉GRE包。GRE包的源地址是对方公网地址目的地址是本地公网地址协议47。确认ACL里有permit gre any any或者更精确的规则。5. GRE over IPsec加密与封装的正确组合方式5.1 为什么不能直接用IPsec承载动态路由前面提到GRE over IPsec是经典组合但为什么不能直接用IPsec而要套一层GRE核心原因是IPsec的ACL匹配逻辑。IPsec的感兴趣流ACL通常匹配的是源和目的IP地址对它只对匹配的流量做加密。如果你想让OSPF穿越IPsec就需要在ACL里放行OSPF的组播地址224.0.0.5。但IPsec的加密隧道是点对点的组播流量进入IPsec后无法正确映射到隧道上。而且IPsec的ACL是单向的需要两端镜像配置维护起来很麻烦。GRE over IPsec的做法是先建GRE隧道让所有需要穿越的流量包括OSPF都走GRE隧道然后用IPsec保护GRE隧道本身。IPsec的ACL只需要匹配GRE包的源和目的地址即两端公网地址协议47。这样配置简单而且所有进入GRE隧道的流量自动被加密。5.2 配置顺序与关键参数配置顺序很重要先配GRE隧道并验证隧道内层能通再配IPsec保护GRE。如果反过来IPsec配好了但GRE没通排查起来会很混乱。IPsec部分的配置要点IKE阶段用预共享密钥或证书IPsec阶段用ESP加密和认证。ACL匹配协议47源和目的分别是两端公网地址。应用crypto map到物理接口。这些是标准IPsec配置不展开细说。关键参数是IPsec的MTU处理。GRE已经增加了24字节开销IPsec的ESP头尾又增加约50-73字节取决于加密和认证算法。所以隧道内层实际可用的MTU可能只有1400左右。这时候ip mtu和ip tcp adjust-mss要相应调小。我通常会把隧道接口MTU设为1400MSS设为1360留足余量。5.3 加密后性能下降的实测数据GRE over IPsec的性能开销主要来自加密和封装。在软件转发平台上启用IPsec后吞吐量可能下降50%以上。硬件加速卡能大幅改善但不同厂商的实现差异很大。我实测过一组数据纯GRE隧道在千兆链路上能跑到线速加上IPsec后降到400-600Mbps具体取决于包大小和加密算法。AES-256比AES-128慢约15-20%SHA-256比SHA-1慢约10%。如果性能是瓶颈可以考虑用AES-128和SHA-1但安全性会降低需要根据实际威胁模型权衡。6. 那些只有踩过才知道的GRE运维细节6.1 隧道震荡与路由翻动GRE隧道本身没有保活机制。如果中间网络出现闪断隧道接口可能不会立即down但实际流量已经不通了。如果隧道上跑了OSPFOSPF的hello超时后邻居会断路由翻动然后隧道恢复后OSPF重新收敛。这个过程可能造成几十秒的业务中断。解决方案是启用GRE的keepalive。配置keepalive 10 3表示每10秒发一次保活包连续3次收不到就认为隧道down。这样隧道接口能快速感知底层故障触发路由切换。但要注意keepalive包本身也走隧道如果底层完全断了keepalive也发不出去所以它只能检测部分故障场景。另一个方案是在隧道上跑BFD。BFD的检测间隔可以做到毫秒级比keepalive快得多。但BFD需要两端设备都支持而且配置稍复杂。我的建议是如果业务对中断时间敏感上BFD如果只是普通互联keepalive够用。6.2 多隧道场景下的Key与源地址选择当一台设备上有多条GRE隧道时Key字段就变得重要了。假设一台设备同时连接三个分支每条隧道用不同的Key。接收端根据Key值把包分发给对应的隧道接口。如果不配Key所有隧道共用同一个源和目的地址对接收端无法区分配置会报错。另一个细节是tunnel source的选择。如果设备有多个公网地址tunnel source指定哪个地址隧道就用哪个地址作为外层源地址。这个地址必须是对方能路由到的地址。我见过一个案例设备有两个公网地址一个用于业务一个用于管理。tunnel source配了管理地址但对方没有到管理地址的路由隧道起不来。后来改成业务地址就好了。6.3 GRE与NAT的兼容性问题GRE和NAT一起用的时候要特别小心。NAT设备通常只处理TCP和UDP对协议47的GRE包可能直接丢弃或者无法正确转换。如果GRE隧道的一端在NAT后面隧道可能起不来。解决方案有两种。一是用GRE的NAT穿越能力但这需要两端设备都支持而且配置复杂。二是把GRE隧道的一端放在有公网地址的设备上避免NAT。如果实在避不开可以考虑用IPsec的NAT穿越功能来替代纯GRE因为IPsec over UDP可以穿透NAT。我在一个项目里遇到过这种情况分支机构的出口设备做了NAT总部想和分支建GRE隧道。试了各种配置都不行最后改成在分支设备上配一条静态NAT把GRE流量映射到内网设备才解决问题。但这个方案要求分支有固定公网地址动态地址场景下不可行。6.4 隧道接口的ACL与安全加固GRE隧道默认不加密所以隧道接口上的ACL很重要。我通常会在隧道接口的入方向配ACL只允许必要的流量进入。比如只允许对端私网网段访问本地私网网段其他一律拒绝。这样即使隧道被利用攻击面也有限。另外隧道接口不要配公网地址用私网地址即可。隧道接口地址只用于隧道内层通信和路由协议不需要对外暴露。如果隧道上跑了动态路由还要考虑路由认证防止恶意路由注入。还有一个容易忽略的点GRE隧道会转发广播。如果一端有ARP广播风暴会通过隧道传到另一端。所以隧道接口上最好配广播抑制或者用ACL限制广播流量。7. 从故障现象反推GRE问题的排查思路7.1 隧道up但业务不通的四种可能隧道接口显示up但业务流量不通这是最让人头疼的情况。根据我的经验可能的原因有四种。第一种是MTU问题。表现是小包通、大包不通。验证方法是用不同大小的ping包测试比如ping 10.2.2.1 size 1400和ping 10.2.2.1 size 1500。如果1400通、1500不通基本可以确定是MTU。解决方案是调小隧道接口MTU和TCP MSS。第二种是路由问题。隧道内层能ping通对端隧道接口地址但ping不通对端私网地址。检查两端的路由表确认对端私网网段指向Tunnel接口。同时检查是否有更精确的路由覆盖了隧道路由。第三种是ACL拦截。隧道接口或物理接口上的ACL可能拦掉了业务流量。检查ACL的匹配顺序和规则内容。特别注意隐式deny any如果ACL最后没有permit规则所有不匹配的流量都会被丢弃。第四种是非对称路由。去程走隧道回程走其他路径。这种情况在有多条路径的网络里常见。表现是ping通但TCP连接建立失败因为TCP握手需要双向通。检查两端的路由表确保去程和回程路径一致。7.2 抓包分析在哪个接口抓、看什么字段抓包是排查GRE问题的终极手段。抓包位置很关键在物理接口抓包能看到GRE封装后的包在隧道接口抓包能看到解封装后的内层包。在物理接口抓包时看外层IP头的源和目的地址是否正确协议号是否为47。如果看不到GRE包说明流量根本没进隧道问题在路由或ACL。如果看到GRE包但对方没收到问题在中间网络。在隧道接口抓包时看内层包的源和目的地址以及TCP/UDP端口。如果内层包正常但业务不通问题可能在应用层或MTU。我常用的抓包命令是tcpdump -i GigabitEthernet0/0 -n -v proto 47只抓GRE包减少干扰。分析时重点看包的源和目的地址、包的大小、是否有分片标志、序列号是否连续。7.3 性能问题的定位是GRE的锅还是底层网络的锅GRE隧道的性能问题不一定都是GRE本身造成的。定位方法很简单在隧道两端做吞吐量测试对比隧道内和隧道外的结果。如果隧道外能跑满带宽隧道内只有一半那可能是GRE封装解封装的开销也可能是MTU问题导致的分片重传。另一个方法是看CPU利用率。软件转发的GRE隧道会消耗CPU如果CPU跑满了吞吐量就上不去。这时候需要考虑硬件加速或者换用支持硬件GRE转发的平台。还有一个容易被忽略的点GRE隧道的流量会经过物理接口如果物理接口本身有拥塞或错误隧道性能也会受影响。检查物理接口的错包计数和带宽利用率排除底层问题。8. 我个人在GRE运维中积累的几条实用原则第一条原则配GRE必调MTU和MSS。不管你觉得有没有必要先调了再说。这个动作的成本极低但能避免大量诡异问题。第二条原则隧道接口地址用/30或/31。只给隧道两端各一个地址不浪费地址空间。隧道接口不需要广播地址/31在点对点链路上完全够用。第三条原则隧道上跑路由协议时一定要配路由认证。GRE不加密路由协议如果不认证容易被恶意注入。OSPF用MD5或SHA认证BGP用TCP MD5或更高级的认证。第四条原则生产环境的GRE隧道必须配监控。监控隧道接口的状态、流量、错包计数。隧道down了要告警流量异常也要告警。我见过隧道断了三天没人发现的情况就是因为没有监控。第五条原则能用IPsec保护就用IPsec保护。纯GRE只适合完全可信的网络环境。跨公网的GRE隧道不管业务是否敏感都建议套一层IPsec。成本不高但安全性提升明显。最后分享一个排查小技巧当你怀疑GRE隧道有问题但不确定时在两端同时抓包对比发出的包和收到的包。如果A端发出了100个GRE包B端只收到80个说明中间网络丢了20个。如果B端收到了100个但解封装后只有80个说明GRE处理有问题。这个方法能快速定位问题出在传输路径还是隧道端点。