BGP 学到了前缀,流量却仍在绕过隧道
BGP 表里的前缀是控制面消息,不是转发决策。先依次排查接收、选中、装入和命中,再去找隧道的麻烦。
分支网关的 BGP 表里能看到云上前缀,到提供商的会话也处于 Established,可用户访问该前缀的请求仍然从错误的接口发出去。按监控看到的样子,哪里都没坏,因为 “BGP 学到了” 只是一句关于控制面的话。那张表和报文之间有四道彼此独立的关口,流量恰好卡在其中一道。按顺序走完这四道门,在第一个失败处停下。
第一道门:邻居实际送来了什么
从收到的前缀本身入手,而不是看汇总结果。在 BGP 表里查准的网络和掩码,记下下一跳、AS 路径,以及导入策略可能匹配的任意 community。仪表盘上的汇总路由会掩盖一个事实:这条具体前缀从未被接受。
导入策略正是路由静默消失的常见位置。前缀列表、community 过滤器或入向 route-map 都可能把这条更新丢掉,而会话本身依旧 Up、邻居依旧健康,所以绿色的邻居指示灯几乎证明不了什么。日志里没有记录,不等于没有做过决策,通常恰恰说明决策是按配置静默执行的。
show ip bgp 10.60.20.0/24 show ip bgp neighbors 203.0.113.5 advertised-routes show ip route 10.60.20.0 show ip cef 10.60.20.0
按这个顺序读输出。前两条命令告诉你信息到没到、对端声称发了什么;后两条告诉你有没有东西进到路由表和转发表。第一条命令里有、第三条里没有,属于选路或装入的问题,不是连通性问题。
第二道门:先选中,再装入
BGP 会选出最优路径,但选中的路径不会自动被装入。下一跳必须能被解析,而且可能已有其他路由来源以更优的管理距离占着这条前缀。迁移时残留的一条静态路由,就能轻松压过合法的 BGP 路径,把流量送去别处。
RFC 4271 把三件事分开:对端送来了什么、本发言者选中了什么作为最优、以及它接下来会向外通告什么。这是三个概念角色,而不是厂商必须暴露的三个物理数据库;但正因为分得清,“它在 BGP 里” 才是一个不完整的回答。
还要确认你读的是哪个路由上下文。装在与用户接口无关的 VRF 里的路由,对该用户的报文是不可见的,而那张表看上去一直都没问题。
第三道门:适用于这条流量的查表
现在别问路由了,改问报文。记下用户的源地址、目的地址、协议、端口和入接口,因为其中任何一项都可能选中不同的策略。然后看作用于这个组合的查表结果,而不是那张通用路由表。
ip route get 10.60.20.25 from 10.60.10.40 ip rule show sudo tcpdump -ni tun0 'host 10.60.20.25'
这里最常见的意外是更具体的前缀,其次是策略路由。两者都会压过你正在看的那条聚合路由,而它们在 BGP 表汇总里都看不到。
从网关自己发出的 ping,不能作为用户会话的证据。源地址不同、策略路径不同,结果往往也不同。要用应用所用的同一个源去测,或者承认这个测试回答的是另一个问题。
第四道门:路径的远端那一半
如果本地查表确实选中了隧道,报文还要被保护策略接受、被转发规则放行,并由对端某个东西回应。加密 ACL 若未包含这对地址,就会在隧道自报 Up 的同时把流量丢掉,产生的超时与路由故障根本无法区分。
回程路径和去程一样重要。云侧必须知道怎么回到分支源地址,无论是靠一条路由,还是靠你刻意配置的地址转换。只从一个方向测过的设计里,非对称回程非常常见。
把一条新的授权连接与三个观察对上:命中的本地策略、有变化的隧道计数器,以及可见时远端的接收情况。计数器不动,说明报文根本没进隧道,路由表说什么都不算数。计数器动了却没到达,说明远端在丢弃或错误地转发。这两种结论会指向完全不同的团队。
给失败的那次转换命名
把结果写成五种状态之一:没有收到、未被策略接受、未被选中、未被装入,或未被这条流量命中。再加第六种:本地路径正确,但远端无法应答。这句话就是交付物,它比一张邻居已建立的截图有用得多。
验收计划里也要留一条否定测试:一个不该走隧道的目标地址,变更后复核。只证明顺利路径的检查表,抓不住下次维护窗口里有人加上的那条宽泛策略规则。