如何检查 BGP 路由与 RPKI 有效性
BGP 路由检查回答的是服务器检查答不了的问题:不是“机器活着吗?”,而是“互联网真的在把流量送到这个前缀吗、且来自正确的起源吗?”。它读取其他网络所看到的通告——起源自治系统、AS 路径、有多少路由收集器能看到这个前缀——并用 RPKI 检验它们,RPKI 是签名的注册表,写明谁被允许起源什么。本指南逐一讲清每个信号的含义、它在哪里会误导人,并用本站的 BGP 查询给出一套五步流程。
最后更新:
路由出错的时候
跑过公共服务的人都熟悉这个场景:站点在你这里能打开,服务器健康,证书有效——而另一个国家的客户什么都打不开。你办公室里的监控说一切正常。他们的流量根本到不了,因为可达性不是你的服务器的属性。它是那些把你的前缀穿越他人网络送出去的通告的属性,而这些通告可以在你机器上什么都没变的情况下改变、被过滤、或被另一条通告反驳。“站点挂了”有时是一个穿着服务器外衣的路由事实。
路由故障有三种值得区分的形状。劫持:另一个自治系统通告你的前缀——或它的一块更具体切片——把从不属于它的流量吸了过去。路由泄漏:一个网络把收到的路由传播给了本不该发给的对等方或提供商,于是流量走上荒谬的绕路,或掉进一个无法投递的网络里。还有安静的那种:一条通告被撤销,或被配置变更、对等纠纷或 RPKI 丢弃过滤掉,于是互联网的一部分干脆没有了路径。三种的修法完全不同,所以第一件工作是把它们区分开——而这从看清实际通告了什么开始。
从通告开始
第一个问题最朴素:这个前缀到底有没有被通告到全球路由表里,如果有,由谁通告?通告的最后一个 AS——起源 ASN——点名声称持有该前缀的网络,它背后的注册数据点名该 ASN 所属的组织。如果起源是你自己的 ASN,或你的提供商的,这条通告至少声称了正确的家。如果是一个你从未见过的名字,你在头十秒里就已经学到了重要的东西。
信息藏在边缘情形里。一个完全没有起源的前缀,意味着它在收集器能看到的任何地方都没有被通告——前缀打错了、通告从未发出、或已在各处被撤销;在下结论前,先查有没有一个覆盖它的较不具体前缀,因为流量也许仍在聚合之下流动。同一前缀的多个起源并不自动可疑:anycast 服务和大型 CDN 本来就设计成从许多网络起源同一前缀,一个正在提供商之间转移的前缀也可以合理地在一段时间内显示两个起源。多个起源,再加上一个你不认识的持有者,且开始时间你什么都没改过——这个组合才值得警觉。
可见度与 AS 路径
looking glass 不问你的路由器;它问路由收集器——本站数据背后的 RIPE RIS 收集器与全世界的网络对等,记录这些对等方向它们通告了什么。可见度是能看到你的前缀的收集器对等方数量。一个健康、存在已久的前缀通常被几乎所有收集器看到。一个正在自由落体的计数——或昨天还满格、今天只剩一把——都提示一条通告正在被撤销、被过滤,或只能通过一组不断收窄的路径被看到。
AS 路径是一条通告走过的网络链:从右往左读,从起源经由传输提供商向外,一直到收集器的对等方。它告诉你哪些上游在承载这条路由、你自己的提供商在链中坐在哪里——泄漏发生时,路径会显示那个不该出现的网络,坐在中间,把流量横向转发。养成一个读法习惯:路径中重复的 ASN 通常是刻意的 prepend(路径预填充),是一种流量工程信号,不是环路;而最短的路径并不总是真实流量走的那条,因为路由服从的是商业政策,不是地理。
信任仪表之前先校准它。收集器看到的是与它们对等的那些网络的视图——一个庞大、位置优越的样本,但不是地球上的每一台路由器。一个前缀可以对收集器不可见,却在一个不与 RIS 对等的提供商内部可达;也可以对收集器可见,却被某个具体的传输网络在下游过滤掉。looking glass 的结果是关于“从严肃的观察点看到的全球路由表”的证据。它不是此刻正在对你的前缀做出的每一个转发决定的照片。
用大白话讲 RPKI
RPKI 是互联网让“我有权通告这个”成为可检验主张、而不只是喊一嗓子的尝试。前缀持有者发布一个 ROA——路由起源授权,一份签名的对象,声明某个具名 ASN 可以起源该前缀,直到一个声明的最大前缀长度。Routinator 这样的验证器——本站检查背后的就是它——从五个区域注册机构的信任锚(APNIC、ARIN、LACNIC、RIPE NCC 和 AFRINIC)抓取 ROA,并逐条检验通告。一份签名声明要么覆盖你的通告,要么不覆盖;整个机制就是这么多。
每条通告都落进三种状态之一。有效(valid):一个 ROA 覆盖这个前缀、这个起源 ASN 和这个长度。无效(invalid):一个 ROA 覆盖该前缀,但通告违反了它的条款——而无效内部的区别要紧:invalid_asn 意味着起源它的网络不对,而 invalid_length 意味着正确的网络通告了比 ROA 允许的更具体的前缀。未知(unknown,常称 not-found):根本没有 ROA 覆盖该前缀,所以无从检验。
现在说诚实的部分。无效是证据,不是劫持的证明。ROA 会被错发、在前缀转移后变陈旧,或写了一个运维团队随后在拆分聚合时忘掉的最大长度——错 ASN 的情形值得一个快速电话,但在指责任何人之前,先查你自己的文件。而未知通常只意味着没人发布过 ROA;世界上很大一部分前缀至今没有 ROA,所以未知是系统里的一个缺口,不是对该前缀的不利标记。不过无效确实有真实的牙齿:许多大型网络如今直接丢弃无效通告,所以一个无效状态可能正是你一开始遇到的那个可达性窟窿的直接成因。
一套五步检查流程
先排除更简单的层——一条还在传播中的新 DNS 记录(用 DNS 传播检查器查)或一个对外部关闭的服务端口(用端口扫描器查),都能完美地模仿路由故障。然后打开 BGP 查询按顺序做。第一步,前缀:输入 IP 或前缀,确认实际承载你流量的那条覆盖通告。第二步,起源:读起源 ASN 和持有者——你的、你的提供商的,还是陌生人的。第三步,可见度:有多少收集器对等方能看到它,这个计数看起来像该前缀的常态吗?
第四步,RPKI:有效、无效(是哪一种?)还是未知——如果 invalid_asn 点名了一个陌生人,在做完清单之前先升级处理。第五步,AS 路径:哪些上游在承载这条通告,有没有哪个网络坐在它不属于的路径里?然后趁它还在眼前写下来:前缀、起源 ASN 与持有者、可见度计数、RPKI 状态、你看到的路径——以及时间,用 UTC。该工具的数据来自 RIPEstat 和 RIPE RIS,并缓存约一小时,所以没有时间戳的截图只是一个轶事;带时间戳的记录才是可以与下一次检查做对比的证据。
值得写明的限制
有三个限制属于任何引用这份数据的报告。收集器覆盖有偏:RIS 的对等方很多,但分布不均——某些地区和某些类型的网络被代表得远好于其他,所以可见度计数是一个样本,不是一次普查。传播以分钟计,不以秒计:你刚做的合法变更,可能合理地尚未可见;一条已撤销的路由也可能在真实流量转移之后仍滞留在收集器里;在宣称修好或宣称灾难之前,先等一等再复查。RPKI 覆盖是局部的:许多前缀仍没有 ROA,验证层只能评判路由表中参与它的那部分。
还有争论中最要紧的那条限制:这里的一个干净结果,证明不了你自己路由器的路由表里有什么。你的会话、你的过滤器、你的本地优先级,都可以让互联网的你这个角落合理地与收集器不一致。用 BGP 查询确立世界通告和看到了什么;用你自己路由器的 BGP 表确立你对此做了什么。一份把这两种主张分开的事故报告,是没人需要收回的那种。
常见问题
RPKI 无效到底是什么意思?
意味着一个 ROA 覆盖该前缀,但这条通告违反了它的条款:要么起源 ASN 不是 ROA 授权的那个(invalid_asn),要么被通告的前缀比 ROA 允许的最大长度更具体(invalid_length)。它是证据,不是劫持的证明——错发的和陈旧的 ROA、以及转移中的前缀,也会产生无效通告。尽管如此还是要紧急对待:许多大型网络会丢弃无效路由,所以无效状态本身可能就是互联网的一部分无法到达该前缀的原因。
looking glass 能看到我自己路由器的路由表吗?
不能。looking glass 展示的是 RIPE RIS 这样的路由收集器从与之对等的网络那里收到的内容——全球路由表的一个庞大而有用的样本,但不是你路由器自己的视图。你的路由器会应用你的会话、过滤器和本地优先级,所以它的表可以合理地不同。要看你自己的视图,没有什么能替代直接问路由器本身(它的 BGP 汇总和路由查询);用 looking glass 看世界看到了什么,用你的路由器看你正在做什么。
为什么两个 looking glass 对同一前缀说法不一致?
因为它们坐在不同的椅子上看。每个收集器与一组不同的网络对等,所以一个可能收到另一个从未听到的通告;它们也可能在一个变更还在传播时相隔几分钟查询,而途中的网络会应用各自的过滤——包括丢弃 RPKI 无效的路由——所以不同观察点诚实地持有不同的表。不一致本身就是信息:如果一个地区的收集器能看到该前缀而另一个地区的不能,这种不一致的形状往往就是问题本身的形状。