ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

华为eNSP实战:GRE隧道配置、OSPF动态路由与排错详解

2026/10/8 2:36:07 拓冰建站 浏览量
华为eNSP实战:GRE隧道配置、OSPF动态路由与排错详解 前几天有人在网络技术群里问GRE实验怎么做我刚好上周用华为eNSP把GRE隧道从零到抓包完整跑了一遍。这个话题说难不难说简单又藏着不少细节网上很多教程把最容易出问题的地方一笔带过。这篇笔记就把实验思路、配置、验证和排错过程全部整理出来适合刚接触GRE的同行也适合准备在公司内部做网络实验培训的朋友参考。1. 为什么要在eNSP里搭GRE实验私网跨公网直连的真实需求1.1 两个私网之间靠默认路由和NAT为什么不够先还原一个非常常见的组网场景总部和分支各自使用私网网段中间走的是运营商提供的IP链路。表面上两边都有公网地址可以通信但真正的业务诉求往往是“私网直达”——总部要能直接访问分支内部的服务器分支要能直接访问总部的业务系统。有人会想两边都做NAT映射不就行了在实验里NAT确实能解决“某一侧主动访问另一侧出口公网地址”的需求但它有一个绕不过去的硬伤NAT只能做地址转换不能把你的私网路由传到对端。举个最简单的例子总部私网是192.168.10.0/24分支私网是192.168.20.0/24两边各自做了NAT那么访问对端时必须通过“公网地址端口映射”来中转每加一条业务就要加一条映射规则而且很多应用依赖真实源IP被NAT一改就出现各种兼容性问题。更麻烦的是如果两侧私网网段相同比如都是192.168.1.0/24NAT方案基本没办法干净地解决冲突。这时就需要一种机制让两个私网在逻辑上像直连一样中间承载网对它们来说是透明的——这正是GRE这种隧道封装技术发挥作用的地方。1.2 GRE在整套方案中所处的角色GRE的全称是Generic Routing Encapsulation通用路由封装核心思想非常简单把一份完整的原始IP报文当作“乘客”在外面再套一层新的IP头变成一份可以在承载网上正常转发的外层报文。到了对端隧道接口再把外层头剥掉还原子原始报文。这样做的效果很直接承载网设备根本不需要认识私网路由它只需要把外层IP报文从一头运到另一头。真正负责私网路由决策的是隧道两端的路由器。在eNSP实验里中间那台路由器模拟运营商的转发设备我在它上面完全不配任何私网路由隧道照样能通。这里有一个值得注意的点GRE本身不加密它只做封装。安全加固通常需要叠加其他加密手段这点我在后面第7章会提到。但单就“私网互联”这个需求来说GRE是最轻量、最容易理解、也是排障思路最清晰的方案之一。2. 实验拓扑与IP规划先把网络地图画清楚再动手2.1 设备选型与接口连线做GRE实验没必要上复杂的设备华为eNSP里选三台AR2220路由器就足够了。AR2220自带多个GE接口模拟企业边缘路由器非常合适性能也完全带得动GRE隧道和OSPF进程。拓扑结构采用最经典的“三台路由器串成一条线”R1作为左侧私网网关同时充当GRE隧道本端端点R2作为中间承载网路由器模拟运营商或公司骨干转发节点R3作为右侧私网网关同时充当GRE隧道对端端点。具体连线关系R1的GE0/0/0接R2的GE0/0/0组成第一段承载网链路R2的GE0/0/1接R3的GE0/0/0组成第二段承载网链路R1的GE0/0/1接PC1网段192.168.10.0/24R3的GE0/0/1接PC2网段192.168.20.0/24。PC1的IP设为192.168.10.10/24网关192.168.10.1PC2的IP设为192.168.20.10/24网关192.168.20.1。这个规划很普通但正是这种普通环境最能暴露GRE实验里容易被忽略的问题。2.2 接口IP与路由基础配置承载网地址我用了文档测试网段203.0.113.0/24这个网段专门用于示例和文档不会和真实公网冲突拿来做实验很合适。详细的IP规划如下设备接口IP地址对端设备R1GE0/0/0203.0.113.1/30R2 GE0/0/0R2GE0/0/0203.0.113.2/30R1 GE0/0/0R2GE0/0/1203.0.113.5/30R3 GE0/0/0R3GE0/0/0203.0.113.6/30R2 GE0/0/1R1GE0/0/1192.168.10.1/24PC1R3GE0/0/1192.168.20.1/24PC2注意我故意把承载网分成两个独立的/30网段这样最能模拟真实运营商链路的状态——两端之间是一段独立的点对点链路而不是共享同一个广播域。先把三台路由器的物理接口配置好system-view sysname R1 interface GigabitEthernet0/0/0 ip address 203.0.113.1 255.255.255.252 interface GigabitEthernet0/0/1 ip address 192.168.10.1 255.255.255.0system-view sysname R2 interface GigabitEthernet0/0/0 ip address 203.0.113.2 255.255.255.252 interface GigabitEthernet0/0/1 ip address 203.0.113.5 255.255.255.252system-view sysname R3 interface GigabitEthernet0/0/0 ip address 203.0.113.6 255.255.255.252 interface GigabitEthernet0/0/1 ip address 192.168.20.1 255.255.255.0R1和R3需要写两条指向远端的静态路由否则GRE隧道的外层报文无法到达对端。这个步骤很多人会漏掉但它决定了隧道接口能不能进入up状态。# R1 ip route-static 203.0.113.4 255.255.255.252 203.0.113.2 # R3 ip route-static 203.0.113.0 255.255.255.252 203.0.113.5配完后在R1上ping 203.0.113.6R3上ping 203.0.113.1确认承载网双向都能通再进入下一阶段。我强烈建议把这一步单独验证完再继续因为GRE实验里一半的问题是“外层根本不通”造成的而很多人会误以为是隧道配置写错了。3. GRE隧道搭建Tunnel接口、封装源和目的地的配置细节3.1 隧道接口参数逐条拆解物理链路通了就可以创建隧道接口。华为VRP平台和Cisco的Tunnel概念本质上一样区别只在命令关键字。在R1上配置如下interface Tunnel0/0/0 ip address 10.0.0.1 255.255.255.252 tunnel-protocol gre source GigabitEthernet0/0/0 destination 203.0.113.6R3对称interface Tunnel0/0/0 ip address 10.0.0.2 255.255.255.252 tunnel-protocol gre source GigabitEthernet0/0/0 destination 203.0.113.1逐条解释这几个参数ip address 10.0.0.x 255.255.255.252这是隧道接口自身的IP地址属于逻辑上的点对点链路段。后端的私网路由会把下一跳指向这个网段里的对端地址。tunnel-protocol gre指定隧道封装协议为GRE。华为接口默认不启用任何隧道模式不写这句的话Tunnel接口无法工作。source GigabitEthernet0/0/0指定外层IP报文的源地址来源。这里可以直接写接口名也可以直接写IP地址203.0.113.1。用接口名的好处是如果这个接口的IP发生变化隧道会自动跟随新IP不用改配置。destination 203.0.113.6指定外层IP报文的目的地址也就是对端隧道的真实承载网接口IP。这里要特别强调source和destination一定是承载网地址而不是隧道接口自己的IP。很多人第一次配置时会把source误写成10.0.0.1隧道永远起不来因为GRE隧道的职责就是把10.0.0.0/30这个逻辑网段封装到203.0.113.x这条物理路径里去外层头的源和目的必须属于“真实可路由”的地址域。3.2 验证隧道状态的两个前提配置完成后用一条命令看隧道状态display interface Tunnel0/0/0重点关注两个字段物理层状态和链路层协议状态。正常情况下应该是“Administratively up, Line protocol up”。如果协议状态是down优先检查三件事第一source对应的接口是否物理up。如果R1的GE0/0/0被down掉R1根本拿不到203.0.113.1作为源地址隧道自然起不来。第二隧道接口能否在路由表里找到到达destination的路由。在R1上执行display ip routing-table 203.0.113.6必须能看到下一跳为203.0.113.2的表项。如果这行路由缺失Tunnel接口协议层一定down。这就是我上一章强调要先验证承载网路由的原因。第三两端tunnel-protocol是否都是gre。如果一端写成了gre另一端没写或者写成了其他隧道类型两端协议不匹配即使物理接口都up协议层也会反复振荡。我在实验里故意把R3的tunnel-protocol删掉一次R1隧道立即从up变成down再把配置补回去几秒钟后恢复。这个操作很适合作为上课时的演示能让新人直观理解“隧道协议一致性”的含义。4. 静态路由引流让私网报文主动走进隧道4.1 隧道两侧的路由写法隧道接口起来之后隧道本身只是搭建了一条“管道”管道两端并不知道应该把哪些流量送进管道。这时需要写静态路由把私网网段的流量“引流”到隧道接口上。R1上需要告诉路由器凡是去192.168.20.0/24的流量都交给10.0.0.2。ip route-static 192.168.20.0 255.255.255.0 10.0.0.2R3上配套写ip route-static 192.168.10.0 255.255.255.0 10.0.0.1注意这里有个容易绕进去的点下一跳为什么写10.0.0.2而不是203.0.113.6因为10.0.0.0/30是隧道接口所在网段路由指向这个网段出接口就会被判定为Tunnel0/0/0。流量到达隧道接口后接口根据自身的封装配置自动把原始IP报文封装成外层目的203.0.113.6的报文。换句话说下一跳10.0.0.2负责“决定走隧道”destination 203.0.113.6负责“决定隧道怎么走”这两层逻辑是分开的。配完静态路由后在PC1上直接ping PC2的私网地址ping 192.168.20.10应该能通。我在实验中特意观察了R2的路由表它只有203.0.113.0/30和203.0.113.4/30这两条直连路由完全没有192.168.10.0/24和192.168.20.0/24这些私网网段。但数据面就是通的这个现象很直观地说明了GRE隧道的一个本质承载网只负责搬运外层报文私网路由永远只在隧道两端决策。4.2 从抓包看GRE封装结构只看现象不够还得看报文结构。eNSP支持在接口上直接抓包我在R1的GE0/0/0接口上抓了一份报文这时候能看到非常清晰的层次关系外层以太网头外层IPv4头源地址203.0.113.1目的地址203.0.113.6协议号47GRE头其中协议类型字段为0x0800表明内层是IPv4报文内层IPv4头源地址192.168.10.10目的地址192.168.20.10。GRE头的结构并不复杂前面4字节是标志位和协议类型其中低16位就是内层协议类型。如果内层封装的是IPv6这个字段会变成0x86DD。你可以把GRE头理解成一张快递面单箱子里面装的什么东西写在面单上拆包的人一看面单就知道里面是什么。抓包还能清楚看到TTL的变化。外层IP的TTL是承载网设备逐跳减的内层IP报文的TTL却完全没变。这是因为GRE采取的是“先封装、后转发”的方式中间路由器不处理内层头。对这个实验来说抓包的意义不只是看个热闹它能直接验证隧道封装是否真的在预期发生后面排障时也会频繁用到。5. 在GRE隧道上跑OSPF把静态路由换成动态协议5.1 为什么值得把静态路由升级成OSPF静态路由在小规模实验里完全够用但真实网络里隧道对端设备的地址、后端私网网段都可能有变化。每次变化都手工改静态路由维护成本太高还容易出错。一个更接近生产环境的做法是让隧道两端跑OSPF让私网路由通过隧道动态交换。我在实验里把静态路由删掉改跑OSPF。为了演示效果R1和R3各自宣告自己的私网网段和隧道网段这样两边都能自动学到对端的私网路由。OSPF会定期发送Hello报文维护邻居关系一旦链路断了路由表能在几十秒内自动收敛。这种特性是静态路由不具备的。5.2 OSPF配置与邻居验证在R1上配置ospf 1 router-id 1.1.1.1 area 0.0.0.0 network 192.168.10.0 0.0.0.255 network 10.0.0.0 0.0.0.3在R3上配置ospf 1 router-id 3.3.3.3 area 0.0.0.0 network 192.168.20.0 0.0.0.255 network 10.0.0.0 0.0.0.3配置前建议先把前面的静态路由删掉undo ip route-static 192.168.20.0 255.255.255.0 10.0.0.2 undo ip route-static 192.168.10.0 255.255.255.0 10.0.0.1有一个细节需要强调OSPF的network语句匹配的是接口地址而不是隧道接口的出接口方向。10.0.0.0/30正是隧道接口所在的网段宣告它之后OSPF才会把Tunnel0/0/0这个接口纳入协议进程。如果漏掉这条OSPF邻居这辈子都建立不起来。由于GRE隧道天然是点对点逻辑拓扑我建议在隧道接口下显式指定OSPF网络类型为p2p这样能避免DR/BDR选举收敛速度更快行为也更符合直觉interface Tunnel0/0/0 ospf network-type p2p配置完成后在两台路由器上执行display ospf peer brief正常情况下R1和R3互为邻居状态为Full。再查看路由表display ip routing-table 192.168.20.0能看到一条OSPF路由协议类型为OSPFcost值也列在表里。这时PC1再去ping PC2和之前静态路由的效果没有区别但路由的来源已经完全不同。5.3 断链后的收敛测试为了验证OSPF over GRE真的能感知隧道故障我做了一个破坏性测试在R3上直接shutdown连接承载网的GE0/0/0接口。# R3 interface GigabitEthernet0/0/0 shutdown几秒后R1上执行display ospf peer brief会发现邻居已经消失。再查看192.168.20.0的路由OSPF路由已经不在表里而是变成了不可达状态。这反映了动态路由的核心价值隧道断了路由表能立刻同步反映出来业务流量不会傻乎乎地继续往黑洞里送。测完恢复接口邻居会在Hello机制下重新建立私网路由自动回表。整个收敛过程完全不需要手工干预。做这个测试时建议把Keepalive也一并开启能让协议层的感知更快关于Keepalive的细节我在下一章详细展开。6. 实验里的三个经典坑MTU、递归路由与Keepalive6.1 大包不通小包通MTU与分片这是我做GRE实验时第一个踩到的坑现象非常典型PC1 ping PC2默认大小的包能通但只要把包调大立刻丢包甚至完全不通。原因要从GRE封装的16字节开销说起。标准GRE头固定20字节再加上外层新加的一个20字节IPv4头相当于整份外层报文比原始内层报文多了40字节。如果原始报文的IP长度是1500字节封装后就变成1540字节超过了物理接口1500字节的MTU于是被分片。分片本身不是问题问题出在很多应用报文在承载网入口被设置成不允许分片或者分片后重组性能很差。结果就是大包丢失小包畅通。解决办法很直接让隧道接口的MTU小一点给外层封装留出余量。我在实验里把两端隧道接口的MTU调整为1460interface Tunnel0/0/0 mtu 1460这样内层报文最大1460字节加上外层40字节正好1500不会超过物理接口限制。对于TCP业务还建议在终端接入侧接口上配置TCP MSS调整华为的写法是interface GigabitEthernet0/0/1 tcp adjust-mss 1400这条命令的作用是修改TCP三次握手时的MSS协商值让TCP报文从源头上就别大过隧道能承载的范围从根上避免分片。6.2 递归路由怎么把外层寻址卷进隧道第二个坑是递归路由。刚学GRE时容易产生一个冲动既然隧道能承载私网路由那我干脆把去对端隧道目的地址的路由也指向隧道接口好了。比如在R1上写ip route-static 203.0.113.6 255.255.255.255 Tunnel0/0/0这条配置初看好像没毛病但细想就发现问题GRE报文外层目的地址正是203.0.113.6路由器要把这份封装后的报文发出去需要先查路由表决定往哪个接口送。结果一看去203.0.113.6的路由下一跳又是Tunnel0/0/0意味着它要先通过隧道到达203.0.113.6而隧道又要通过203.0.113.6才能建立这就成了先有鸡还是先有蛋的递归依赖路由无效。在实验里的表现是静态路由配置成功但路由状态不是Active或者持续振荡。排查方法display ip routing-table 203.0.113.6 verbose我建议遵循一条黄金规则隧道接口永远只承载“隧道两端私网”的路由而外层承载网地址必须走物理出接口和物理下一跳。换句话说203.0.113.x这段承载网路由要交给物理接口GE0/0/0的直连链路来维护Tunnel0/0/0只能用来传递192.168.x.x这类后端私网路由。一旦出现交叉寻址排查方向就往递归路由上面靠。6.3 Keepalive该不该开第三个坑和隧道接口协议状态的“虚假up”有关。在默认情况下GRE隧道接口只要物理接口up、source和destination可达协议就一直显示up。即使对端隧道已经彻底失效本端也不会自动感知。业务流量照样进入隧道接口然后被直接丢弃像个黑洞。解决手段是开启GRE Keepalive。华为设备在Tunnel接口下配置interface Tunnel0/0/0 keepalive 10 3含义是每10秒发送一次Keepalive探测报文连续3次没有收到对端的Keepalive回复就认为隧道不可达本端Tunnel接口协议变为down。我建议在承载关键业务的GRE隧道上开启Keepalive这样路由协议能快速感知隧道故障触发业务切换到备用路径。开启后的实测效果R3把GE0/0/0 shutdownR1的Tunnel0/0/0在几十秒内协议变为downOSPF邻居也随之消失。如果没开KeepaliveR1的隧道协议会一直显示up但你ping对端隧道地址一个包都回不来。需要说明的是Keepalive只能证明“GRE封装解封装路径基本可用”不能代表端到端业务质量。它解决的问题是“快速感知隧道失效”真正的链路质量还是要依靠业务流量的统计和监控来判断。7. 实验之后往哪走多跳GRE与IPv6封装7.1 把一跳变成多跳中间设备能看到什么当前这个实验其实已经是“多跳”场景了R1到R3的GRE报文经过了R2这台中间设备。你可以在R2上抓包看看会发现R2只做一件事根据外层IP目的地址203.0.113.6查找自己的路由表然后转发出去。R2根本不需要知道内层报文是192.168.10.10访问192.168.20.10。这说明GRE隧道逻辑上相当于一根贯穿承载网的虚拟网线中间经过多少台物理路由器对隧道两端完全透明。生产环境里经常利用这点在跨越多个运营商或内部骨干段的场景下用GRE做“私网透传”只要保证外层IP能通隧道就能工作。进一步扩展可以做双向隧道冗余R1同时建两条tunnel分别指向R3的两个不同承载网接口再配合策略路由或者等价路由实现链路备份和负载分担。这类拓扑在实际运维里非常常见建议在eNSP里把“双tunnel主备切换”作为下一个实验目标。7.2 用GRE承载IPv6孤岛互通的思路最后说一个很有价值的扩展方向。现在很多企业的IPv6地址都是“孤岛式”的各区域都能拿到IPv6地址但区域之间没有IPv6承载网。此时GRE可以充当IPv6的搬运工把IPv6报文封装进IPv4报文里通过现有的IPv4网络把IPv6孤岛串起来。配置思路和不IPv4承载完全一样只是隧道接口上要启用IPv6地址族interface Tunnel0/0/0 ipv6 enable ipv6 address 2001:db8:10::1/64 tunnel-protocol gre source GigabitEthernet0/0/0 destination 203.0.113.6对端R3配置2001:db8:10::2/64其余一致。这样隧道逻辑链路的IPv6地址就是2001:db8:10::0/64两端的IPv6私网路由可以在这个隧道接口上跑动态路由协议实现IPv6孤岛互通。反向思路也一样成立。在纯IPv6承载网里外层用IPv6地址内层装IPv4报文就能让IPv4孤岛继续通过IPv6网络互访。GRE的协议类型字段决定了内层是谁0x0800表示IPv40x86DD表示IPv6所以这套封装机制非常通用。做完这轮实验我最深的体会是GRE的命令行只有那么几条真正决定实验成败的往往是对外层寻址、MTU和路由表里“下一跳走向”的理解。在eNSP里可以反复抓包、反复破坏链路去验证每个机制把坑踩明白了到了真实设备上心里才有底。如果下一步想继续延伸可以试试在GRE隧道上加QoS策略或者同时建多条隧道做双归互备这些都是网络运维环境里非常现实的需求。