1. 项目背景与整体设计思路
企业网络里最让人头疼的场景之一,就是多条出口链路并存时的流量调度问题。比如公司同时拉了运营商A和运营商B两条宽带,默认所有流量都走A,B那条链路平时闲着,只有A断了才切过去。这种"主备模式"最大的浪费就是B链路的带宽完全没被利用起来。更麻烦的是,有些业务系统要求必须从特定出口出去——比如对外发布的服务器需要固定源IP,或者访问某个合作方的内网必须走指定专线。这时候光靠一条默认路由根本搞不定。
这个实例要解决的核心问题就是:如何让不同的流量走不同的出口,并且在经过出口时完成源地址转换,同时还要保证内网之间能通过隧道互通。三个技术点——策略路由、GRE隧道、NAT——单独拿出来都不复杂,但把它们串在一起用,就涉及到流量走向的先后顺序、路由查找的优先级、NAT转换的时机等一系列细节问题。我见过不少人在这个组合上翻车,配置看起来都对,但流量就是不通,排查半天发现是策略路由和NAT的执行顺序搞反了。
先说说整体设计思路。假设这样一个拓扑:某公司总部有一台核心路由器,下联办公网段,上联两条出口链路——一条走运营商A(主),一条走运营商B(备)。同时总部和分公司之间需要跑内网业务,但两家之间没有专线,只能通过公网建立GRE隧道来传输私网流量。分公司的网段也需要能访问互联网,并且从总部出口出去。
这个场景下,策略路由的作用是根据流量的源地址或目的地址决定走哪条出口;GRE隧道的作用是在公网之上虚拟出一条点对点的私有通道,让两端私网能互通;NAT的作用是在流量离开本地网络时把私网源地址转换成公网地址,保证回包能找到路。
三者配合的关键在于执行顺序。数据包进入路由器后,先查路由表还是先匹配策略路由?NAT是在路由决策之前做还是之后做?GRE封装后的外层地址怎么走?这些问题如果不想清楚,配置写出来就是一堆看似正确但完全不工作的命令。
我个人的经验是,把整个转发流程拆成三个阶段来看:入站处理阶段(策略路由匹配、NAT转换决策)、路由查找与封装阶段(查表、GRE封装)、出站处理阶段(NAT实际转换、发送)。每个阶段做什么事,设备厂商的实现可能有细微差异,但大逻辑是相通的。下面我会按照这个思路,把每个技术点的配置细节和配合关系讲清楚。
2. 策略路由的核心机制与配置要点
2.1 策略路由和普通路由的本质区别
普通路由是"查目的地"——路由器收到包,看目的IP,然后查路由表决定从哪个接口发出去。策略路由是"查来源或更多条件"——不光看目的IP,还可以看源IP、协议类型、端口号、包大小等等,匹配到特定条件后,强制指定下一跳或出接口。
打个比方:普通路由像邮局按收件地址分拣邮件,策略路由像公司前台按寄件人部门决定用哪家快递。前者只看"送到哪",后者看"谁寄的"。
这个区别在实际配置中体现得很明显。普通路由你只需要写ip route 目的网段 掩码 下一跳,策略路由则需要先定义一个匹配规则(ACL或前缀列表),再定义一个行为(往哪发),最后把规则和行为绑定成一个策略,再应用到接口上。
2.2 策略路由的匹配逻辑与优先级
策略路由的匹配顺序是从上到下依次匹配,匹配到第一条就执行对应动作,不再往下查。这个特性非常重要,因为如果你把宽泛的规则放在前面,后面的精细规则就永远不会生效。
比如你写了两条规则:第一条匹配所有源地址走出口A,第二条匹配特定源地址走出口B。那么第二条永远不会被匹配到,因为所有流量都在第一条就被拦截了。正确的做法是把精细规则放前面,宽泛规则放后面。
另外,策略路由和普通路由的优先级关系也要搞清楚。在大多数设备上,策略路由优先于普通路由。也就是说,如果一个包同时匹配了策略路由和普通路由表,设备会优先按策略路由转发。但这里有个例外:如果策略路由指定的下一跳不可达,设备可能会回退到普通路由表去查。这个行为取决于具体实现,配置时需要确认。
2.3 策略路由的典型配置结构
以常见的网络设备命令风格为例,策略路由的配置分三步走:
第一步,定义匹配条件。通常用ACL来实现:
# 定义匹配办公网段流量的ACL acl number 3000 rule 5 permit ip source 192.168.10.0 0.0.0.255 rule 10 permit ip source 192.168.20.0 0.0.0.255第二步,定义策略路由行为:
# 定义策略路由,匹配ACL 3000的流量走出口B policy-based-route PBR_OFFICE permit node 10 if-match acl 3000 apply ip-address next-hop 200.1.1.2第三步,应用到接口:
# 在办公网入接口上应用策略路由 interface GigabitEthernet0/0/1 ip policy-based-route PBR_OFFICE这三步看起来简单,但有几个坑要注意。第一个坑:ACL的规则编号要留出间隔,方便后续插入新规则。我一般用5、10、15这样的编号,中间留空。第二个坑:策略路由应用在接口上时,要注意方向——是应用在入接口还是出接口。通常应用在入接口,因为包一进来就决定走向,效率最高。第三个坑:如果策略路由的下一跳是对方设备的接口地址,要确保这个地址是可达的,否则策略路由不生效。
2.4 策略路由的常见应用场景
策略路由最常用的场景有这么几个:
- 多出口负载分担:不同部门走不同出口,或者按业务类型分流。
- 源地址选路:某些服务器需要固定从某个出口出去,保证对端看到的源IP是固定的。
- 目的地址选路:访问特定合作方走专线,访问互联网走普通宽带。
- 协议分流:语音流量走低延迟链路,普通数据走大带宽链路。
在这个实例里,我们主要用的是源地址选路——办公网段走一条出口,服务器网段走另一条出口。这样既能实现分流,又能配合NAT做源地址转换。
3. GRE隧道的工作原理与实操细节
3.1 GRE隧道解决了什么问题
GRE(通用路由封装)的核心价值是在公网之上虚拟出一条点对点的私有通道。两个私网之间本来不能直接通信,因为私网地址在公网上不可路由。通过GRE,我们可以把私网包整个封装在一个公网包里,外层用公网地址传输,到了对端再解封装,把内层私网包还原出来。
这个过程就像你把一封信装进快递信封里寄出去。信的内容是私密的(内层私网包),快递信封上写的是公开的地址(外层公网包)。快递公司只负责把信封送到目的地,收件人拆开信封才能看到里面的信。
GRE隧道的好处是配置简单、支持多协议。它不像IPsec那样需要复杂的加密协商,基本上两边配好隧道源和目的地址就能通。但缺点也很明显:不加密、不认证,安全性全靠上层协议自己保证。所以如果传输敏感数据,通常会在GRE外面再套一层IPsec。
3.2 GRE隧道的配置参数详解
GRE隧道的配置看起来就几行命令,但每个参数都有讲究:
# 总部侧GRE隧道配置 interface Tunnel0/0/0 ip address 10.0.0.1 255.255.255.252 tunnel-protocol gre source 100.1.1.1 destination 200.1.1.1隧道接口的IP地址:这是隧道两端用来通信的私网地址,通常用一个30位掩码的网段(只有两个可用地址)。这个地址不占用物理接口地址,是逻辑上的。
source和destination:这是隧道的起点和终点公网地址。source是本端出口接口的公网IP,destination是对端出口的公网IP。这两个地址必须互相可达,否则隧道起不来。
tunnel-protocol gre:指定隧道封装协议。有些设备上还需要指定gre key来做简单的标识,防止不同隧道之间的混淆。
配置完隧道接口后,还需要配置路由让私网流量走隧道。比如:
# 去往分公司网段的路由指向隧道接口 ip route-static 192.168.30.0 255.255.255.0 Tunnel0/0/0这条路由的意思是:要去192.168.30.0/24的包,从Tunnel0/0/0发出去。设备会把包封装成GRE格式,外层源地址是100.1.1.1,外层目的地址是200.1.1.1,然后查公网路由表把封装后的包发出去。
3.3 GRE与策略路由、NAT的配合关系
这是整个实例最核心的部分。GRE隧道建好之后,私网流量要经过隧道传输,但隧道外层包还需要走公网出口。这时候策略路由和NAT就要配合工作了。
关键点一:GRE流量本身不能被NAT转换。如果出口做了NAT,把GRE外层包的源地址转换了,对端收到包后发现源地址不对,隧道就断了。所以NAT配置里必须排除GRE流量,通常用ACL匹配GRE协议(协议号47)或者匹配隧道端点地址来放行。
关键点二:策略路由要区分"隧道流量"和"普通上网流量"。隧道流量走物理出口但不需要NAT,普通上网流量走物理出口且需要NAT。策略路由可以根据目的地址来区分——目的地址是隧道对端的,走隧道;目的是互联网的,走NAT出口。
关键点三:NAT的执行顺序。在大多数设备上,NAT是在路由查找之后执行的。也就是说,包先查路由表决定从哪个接口出去,然后在出接口上做NAT转换。但策略路由是在路由查找之前执行的,所以策略路由指定的出口会直接影响后续NAT的行为。
我踩过的一个坑是:策略路由把流量指到了一个没有配置NAT的出口,结果私网地址直接发出去了,回包根本回不来。后来在策略路由的出口接口上补了NAT配置才解决。所以策略路由和NAT要成对配置,指到哪个出口,哪个出口就要有对应的NAT规则。
4. NAT转换的时机与配置策略
4.1 NAT的类型选择与适用场景
NAT分好几种,常见的有静态NAT、动态NAT、PAT(端口地址转换)。这个实例里我们主要用PAT,因为多个内网主机共享一个公网IP是最常见的需求。
PAT的原理是:把内网主机的源IP和源端口一起转换成公网IP和一个新的端口号,并在设备上维护一张转换表。回包回来时,根据目的端口号查表,找到对应的内网主机,把包转回去。
用生活类比:PAT就像公司前台的总机号码。外面打总机,前台根据分机号转接。总机只有一个号码(公网IP),但可以同时处理很多通话(端口号区分)。
静态NAT适合服务器对外发布,因为需要固定的映射关系。动态NAT适合内网用户上网,但需要公网IP池。PAT最适合内网用户共享少量公网IP上网。
4.2 NAT与策略路由的配合配置
在这个实例里,NAT的配置要配合策略路由来做。假设办公网段走出口A,服务器网段走出口B,那么两个出口都要配置NAT,但转换规则不同。
出口A的NAT配置:
# 定义允许NAT的内网网段 acl number 2000 rule 5 permit source 192.168.10.0 0.0.0.255 rule 10 permit source 192.168.20.0 0.0.0.255 # 在出口A接口上应用NAT interface GigabitEthernet0/0/0 nat outbound 2000出口B的NAT配置:
# 定义允许NAT的服务器网段 acl number 2001 rule 5 permit source 192.168.30.0 0.0.0.255 # 在出口B接口上应用NAT interface GigabitEthernet0/0/1 nat outbound 2001注意这里ACL 2000和2001的区别:出口A的NAT允许办公网段和服务器网段(作为备份路径),出口B的NAT只允许服务器网段。这样配置的目的是:正常情况下服务器走出口B,办公走出口A;如果出口A断了,办公流量切到出口B时也能做NAT。
4.3 NAT排除GRE流量的配置方法
前面提到GRE流量不能被NAT转换,具体怎么排除呢?有两种方法:
方法一:在NAT的ACL里拒绝GRE流量。比如:
acl number 2000 rule 0 deny gre rule 5 permit source 192.168.10.0 0.0.0.255这里的rule 0 deny gre就是拒绝所有GRE协议的包做NAT。注意规则编号用0,确保它在最前面匹配。
方法二:用策略路由把GRE流量引到不配NAT的接口。但这种方法比较绕,不如第一种直接。
我一般用第一种方法,简单直接。但要注意,有些设备上deny gre的写法可能不支持,需要写成deny 47(47是GRE的协议号)。配置前最好查一下设备文档。
4.4 NAT转换表的查看与排查
NAT配置完不生效,最常见的原因是转换表没建立起来。查看NAT转换表的命令通常是:
display nat session all如果表里没有条目,说明流量根本没触发NAT。可能的原因有:ACL没匹配上、流量没从正确的接口出去、或者策略路由把流量引到了别的接口。
排查时我习惯按这个顺序来:先看策略路由是否生效(display policy-based-route),再看路由表是否正确(display ip routing-table),最后看NAT会话是否建立(display nat session)。三步下来基本能定位问题。
5. 完整实操流程与关键环节实现
5.1 拓扑规划与地址分配
先把整个拓扑和地址规划清楚,这是所有配置的基础。假设:
- 总部核心路由器:R1
- 分公司路由器:R2
- 总部办公网段:192.168.10.0/24
- 总部服务器网段:192.168.20.0/24
- 分公司网段:192.168.30.0/24
- 总部出口A(运营商A):100.1.1.1/30,对端100.1.1.2
- 总部出口B(运营商B):200.1.1.1/30,对端200.1.1.2
- 分公司出口:200.1.1.5/30,对端200.1.1.6
- GRE隧道网段:10.0.0.0/30,总部10.0.0.1,分公司10.0.0.2
地址规划的原则是:公网地址用运营商分配的,私网地址自己规划,隧道地址单独用一个30位网段。私网地址规划要留出扩展空间,不要用得太满。
5.2 基础路由配置
先配基础路由,保证公网可达:
# R1默认路由走出口A ip route-static 0.0.0.0 0.0.0.0 100.1.1.2 # R1去往分公司公网地址的路由走出口B ip route-static 200.1.1.4 255.255.255.252 200.1.1.2 # R2默认路由走自己的出口 ip route-static 0.0.0.0 0.0.0.0 200.1.1.6这里有个细节:R1去往分公司公网地址的路由必须走出口B,因为分公司的公网地址在运营商B的网段里。如果走出口A,包可能到不了对端。
5.3 GRE隧道建立与验证
两边配好隧道接口:
# R1隧道配置 interface Tunnel0/0/0 ip address 10.0.0.1 255.255.255.252 tunnel-protocol gre source 200.1.1.1 destination 200.1.1.5 # R2隧道配置 interface Tunnel0/0/0 ip address 10.0.0.2 255.255.255.252 tunnel-protocol gre source 200.1.1.5 destination 200.1.1.1注意这里的source和destination用的是出口B的公网地址,因为隧道要走出口B。配完后用display interface Tunnel0/0/0查看隧道状态,如果显示up,说明隧道建立成功。
如果隧道起不来,先ping一下对端的公网地址,确认公网可达。公网通了隧道还不通,检查source和destination是否写反了,或者中间有没有防火墙拦截了GRE协议。
5.4 策略路由配置与验证
配置策略路由让办公网段走出口A,服务器网段走出口B:
# 匹配办公网段的ACL acl number 3000 rule 5 permit ip source 192.168.10.0 0.0.0.255 # 匹配服务器网段的ACL acl number 3001 rule 5 permit ip source 192.168.20.0 0.0.0.255 # 策略路由:办公走出口A policy-based-route PBR_OFFICE permit node 10 if-match acl 3000 apply ip-address next-hop 100.1.1.2 # 策略路由:服务器走出口B policy-based-route PBR_SERVER permit node 10 if-match acl 3001 apply ip-address next-hop 200.1.1.2 # 应用到内网入接口 interface GigabitEthernet0/0/1 ip policy-based-route PBR_OFFICE ip policy-based-route PBR_SERVER验证策略路由是否生效,可以用display policy-based-route查看策略状态,或者用tracert从内网主机测试走的是哪个出口。
5.5 NAT配置与联调
最后配NAT:
# 出口A的NAT ACL,排除GRE acl number 2000 rule 0 deny gre rule 5 permit source 192.168.10.0 0.0.0.255 rule 10 permit source 192.168.20.0 0.0.0.255 # 出口B的NAT ACL,排除GRE acl number 2001 rule 0 deny gre rule 5 permit source 192.168.20.0 0.0.0.255 # 应用NAT interface GigabitEthernet0/0/0 nat outbound 2000 interface GigabitEthernet0/0/2 nat outbound 2001配完后从办公网主机ping公网地址,从服务器ping公网地址,从办公网ping分公司内网地址,三个方向都通了,说明配置正确。
6. 常见问题排查与避坑经验
6.1 策略路由不生效的排查思路
策略路由配了但流量还是走默认路由,最常见的原因有:
- ACL没匹配上:检查ACL的源地址是否写对,掩码是否精确。我见过有人把
0.0.0.255写成0.0.0.0,结果匹配了所有地址。 - 策略路由没应用到正确的接口:要应用在流量的入接口,不是出接口。
- 策略路由的节点号顺序问题:如果配了多个节点,匹配顺序是从小到大,匹配到就停止。
- 下一跳不可达:策略路由指定的下一跳如果路由表里查不到,策略不生效。
排查时先用display acl 3000看ACL有没有匹配计数,再用display policy-based-route看策略有没有命中。
6.2 GRE隧道频繁up/down的处理
隧道不稳定,多半是底层公网链路抖动导致的。GRE本身没有保活机制,底层一断,隧道就down。解决办法是配置keepalive:
interface Tunnel0/0/0 keepalive 10 3意思是每10秒发一次保活包,连续3次收不到就认为隧道down。这样能更快感知隧道故障,及时切换到备用路径。
另一个原因是MTU问题。GRE封装会增加24字节的开销(20字节新IP头+4字节GRE头),如果内层包是1500字节,封装后就变成1524字节,超过物理接口MTU会被分片或丢弃。解决办法是调整隧道接口的MTU:
interface Tunnel0/0/0 mtu 1476 tcp mss 14201476 = 1500 - 24,这样封装后不会超过1500。tcp mss 1420是告诉TCP协商时用更小的MSS,避免分片。
6.3 NAT转换失败的典型原因
NAT不生效,按这个表排查:
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 内网ping不通外网 | NAT ACL没匹配 | 检查ACL源地址和接口应用 |
| 外网能ping通但访问不了服务 | 端口映射没配 | 配置静态NAT或端口映射 |
| GRE隧道断了 | GRE流量被NAT转换 | 在NAT ACL里deny gre |
| 部分主机能上网部分不能 | ACL规则顺序问题 | 调整ACL规则顺序 |
| 上网时通时不通 | NAT会话表满 | 扩大NAT会话规格或清理会话 |
我遇到最多的是ACL规则顺序问题。比如先配了permit source 192.168.10.0 0.0.0.255,又配了deny gre,结果GRE流量先匹配了permit规则,被NAT转换了。正确的顺序是deny在前,permit在后。
6.4 多出口场景下的回包路径问题
多出口最容易出的问题是回包不走原路。比如请求从出口A出去,源地址被NAT成出口A的公网IP,但回包回来时,设备查路由表发现去往这个公网IP的路由走出口B,结果回包从出口B发出去了,对端收到后发现源地址不对,连接就断了。
解决办法是配置策略路由让回包也走原出口,或者用NAT的会话保持功能。大多数设备上,NAT会话建立后,回包会自动匹配会话表,不需要额外配置。但如果设备重启或会话老化,回包就可能走错路。
我一般会在出口设备上配一条基于源地址的策略路由,让从出口A出去的流量,回包也走出口A。具体配置和前面的策略路由类似,只是匹配条件换成公网地址。
6.5 配置保存与重启后的注意事项
所有配置配完后,记得保存配置。不保存的话,设备重启后配置全丢。保存命令通常是save,有些设备需要确认。
另外,策略路由和NAT的配置顺序在重启后可能影响生效。有些设备重启后先加载NAT配置再加载策略路由,导致策略路由暂时不生效。解决办法是配置启动优先级或者延迟应用,但大多数情况下设备会自动处理,不用太担心。
最后分享一个我踩过的坑:策略路由的下一跳写成了出接口而不是下一跳地址。有些设备支持apply interface,有些只支持apply ip-address next-hop。如果写错了,策略路由不生效但也不报错,排查起来很费劲。配置前一定查清楚设备支持哪种写法。