跳转至

BGP 路由泄露防护实战:RPKI、ASPA 与前缀过滤的完整防线

BGP 是互联网的"地图协议"——几十万个自治系统靠它互相宣告"我这边能到哪些网段"。它设计于信任优先的年代,默认相信邻居说的话。一旦某个网络配错或故意宣告了不属于自己的路由,流量就会被牵着鼻子走,轻则自己变慢,重则整片区域断网。这些年闹过的事故不少:某国电信把谷歌、推特的流量导到自己网络绕了一圈,某运营商把路由泄露到上游让半个互联网抖动,还有云厂商的 BGP 会话被误配导致大面积不可达。

路由泄露(route leak)和路由劫持(hijack)常被混为一谈,但防护思路不同:劫持是"冒领"别人的前缀,泄露是"乱传"本不该由自己转发的路由。本文不讲怎么抢前缀,只讲怎么让"不该出现的路由"在你的网络里进不来、出不去、传不开,给一套从源验证到路径验证、从过滤到监控的多层防线。

1. 路由泄露是怎么发生的

先弄清敌人长什么样,才好布防。常见泄露有三类:

  • 对等关系错用:两家本该只交换自己及客户的路由(peer-to-peer),结果一方把从别处收到的全网路由也转发给对方,等于把自己当成了 transit。这是最典型的"泄露"定义。
  • 没有出口过滤:下游客户宣告了超出授权范围的前缀,上游没做 prefix-list 校验就照单全收并继续广播。
  • 配置翻转:把 import 和 export 策略贴反,或者 no-export community 没生效,导致本该内部消化的路由漏到了外部。

根因几乎都是同一件事:没有对邻居宣告的内容做验证和限制。所以防护的第一性原理就是——凡是对外宣告或接收的路由,都必须经过明确的策略过滤,而不是"邻居说什么我都信"。

2. 第一层:RPKI ROV 源验证

RPKI(资源公钥基础设施)解决"这个前缀到底该由哪个 AS 起源"的问题。网络运营者用自己的证书给"某前缀 + 某源 AS"签一个授权对象(ROA),放在全球依赖方仓库里。路由器通过 RTR 协议(RPKI to Router)从验证缓存拉取这些记录,对收到的每条路由做源验证,得出三种状态:

  • Valid:源 AS 与 ROA 匹配。
  • Invalid:前缀存在 ROA,但当前宣告的源 AS 不在授权列表里——典型的源冒充。
  • Unknown:该前缀没有对应的 ROA——目前互联网上仍是大多数。

实战建议:先开启"屏幕模式"只观测不丢弃。在 Cisco 上用 route-map 给 Invalid 打 community 或本地偏好,Juniper 用 validation-state invalid 匹配;观察两周,确认 Invalid 的来源确实是异常宣告,再切到真正丢弃。FRR 和 BIRD 都原生支持 RPKI,配一个 rpki 段落指向缓存(如 Routinator、OctoRPKI)即可。

3. 第二层:ASPA 路径验证

RPKI 只管"源",不管"路径"。ASPA( Autonomous System Provider Authorization)补上这一刀:它声明"我的 AS 的上游/对等是谁",路由器据此检查 AS_PATH 里每一对相邻 AS 的上下游关系是否真实。如果一条路径里出现了"本应是客户却放在提供商位置"的异常相邻关系,就判定为路径型泄露并拦下。

ASPA 目前处在逐步部署阶段,不像 ROV 那么普及,但价值很高:它能挡住"用自己合法 AS 起源、却绕了不该经过的链路"的高级泄露。部署方式类似 RPKI,由 CA 签发 ASPA 对象,路由器消费后做路径校验。建议在有 RPKI 基础后逐步启用,对新接入的对等优先级高。

4. 第三层:IRR 与精确前缀过滤

光有加密验证还不够,因为你根本不该收一堆无关的明细路由。IRR(Internet Routing Registry)是各 NCC/RIR 维护的路由对象库,网络运营者登记自己要宣告的前缀。最佳实践是对每个邻居套一个 prefix-list(Cisco)或 prefix-list/policy-options(Juniper),只放行它"应该"宣告的段:

  • 对上游运营商:通常只收默认路由或它自己及客户的聚合。
  • 对 Peer:只收对方及其客户的路由,绝不收 transit 来的第三方。
  • 对下游客户:严格按合同里登记的前缀白名单,多一条都不收。

很多团队把 IRR 对象当摆设、过期不更新,结果过滤器和实际宣告对不上,要么漏过、要么误杀。纪律是:IRR 对象和 RPKI ROA 一起作为白名单源,CI 里加校验,改前缀前先改登记。

5. 第四层:max-prefix 接收限速

即便前面都做了,bug 和误操作仍可能让一个邻居突然塞给你几万条路由,撑爆 RIB 或 CPU。max-prefix(前缀数量上限)是最后一道保险:

  • 软上限(warning):达到阈值只告警,方便你介入看是不是正常增长。
  • 硬上限(超限动作):可以选"断开会话"或"停止接收新路由但保留已有",后者更稳,避免震荡。

阈值怎么定?拉邻居过去 30 天通告量的峰值,软限取 1.2-1.5 倍,硬限取 1.8-2 倍。对上游可宽、对 Peer 和客户要严。这条配置改一次能管很久,但"增长时忘了调"是常见坑,所以巡检里要把"阈值余量"列为固定检查项。

6. 第五层:peer-lock 与 bogon 过滤

两个低成本高收益的底线动作:

  • bogon/martian 过滤:在全部 eBGP 入方向丢弃 RFC1918 私网、文档段(192.0.2.0/24 等)、未分配段、以及明显非法的源。这是 ISP 边界的标配,不做就是失职,因为它直接关系到源地址伪造和反射攻击。
  • peer-lock:把"只发给特定邻居"的路由显式锁死,防止策略贴反导致本该内部的路由外泄。在 Juniper 里常用 export 策略配合 then community add no-export,在 FRR 里用 route-map 的 community 动作。核心是"默认不导出,白名单才导出"的零信任思路。

7. 配置片段速查

下面给出各平台的骨架,具体数值按你的拓扑填:

Cisco(RPKI + 丢弃 Invalid):

router bgp 65001
 bgp rpki server 192.0.2.10 port 323 refresh 300
route-map RPKI-IN permit 10
 match rpki invalid
 set community 666:1
route-map RPKI-IN permit 20
neighbor 203.0.113.1 route-map RPKI-IN in

Juniper(按验证状态匹配):

policy-options policy-statement RPKI-IN
 term invalid
  from validation-state invalid
  then reject
 term else
  then accept

FRR(原生 RPKI):

rpki
 rpki polling-period 300
 rpki cache 192.0.2.10 323
 exit
route-map RPKI-IN deny 10
 match rpki invalid

BIRD(rpki 协议 + 过滤器):

protocol rpki RPKI {
  roa4 { table roa_table; };
  remote 192.0.2.10 port 323;
}
filter bgp_in { if (roa_check(roa_table, net, from) = ROA_INVALID) then reject; accept; }

8. 监控与异常检测

防线布好不等于万事大吉,得能"看见"异常:

  • 持续统计每天 Invalid/Unknown 占比,占比突增往往意味着某处 ROA 配错或被攻击。
  • 监控每个邻居的路由条数,超过 max-prefix 软限即告警。
  • 对关键前缀(你自己的、重要客户的)做可达性探测,一旦路径突然变长或下一跳异常就告警。
  • 订阅 RPKI 仓库和 IRR 的变更通知,前置发现可能影响你的改动。

告警要接进现有的监控体系(Prometheus + Alertmanager 或直接发到值班群),别让告警沉睡在日志里。

9. 上线后的巡检与防退化纪律

路由过滤是"会悄悄退化"的配置,一次错误的策略回滚、一次 IRR 对象过期、一次工程师手滑贴反 import/export,防线就没了。建立以下纪律:

  • 每周:跑一次全邻居 ROV 状态统计,确认 Invalid 仍在丢弃、Unknown 占比无异常飙升。
  • 每月:核对 IRR 登记对象与实际宣告是否一致,过期对象触发整改工单。
  • 每次变更前:在 staging 或只读会话里先 show 验证策略效果,再上生产;变更后立刻复核收到的路由条数和状态分布。
  • 每次扩前缀/加邻居:先改 IRR 和 RPKI ROA,再改路由器 prefix-list,顺序不能反,改完用 show route receive-protocol 确认生效。
  • 红线:禁止"先放行再补过滤"。任何新邻居接入默认 deny-all,白名单一条条加;任何 export 默认 no-export,要导出显式授权。

FAQ

RPKI ROV 和 ASPA 有什么区别,是不是配了 RPKI 就够了? 不够。RPKI ROV 只验证"这个前缀的源 AS 是否合法",挡的是源冒充,管不到路径。比如攻击者用自己合法注册的 AS 起源一个前缀、却绕了一段不该经过的链路,ROV 可能放行。ASPA 额外验证"AS 路径里每一跳的相邻关系是否真实存在",专治路径型泄露。两者是正交的两层,建议都开,ROV 先上、ASPA 逐步铺开。 max-prefix 设多少合适?设太小会不会误伤正常增长? 没有统一值,按对端实际通告量留余量。先看邻居过去 30 天的峰值条数,取峰值的 1.2-1.5 倍作为软上限(warning),再乘 1.8-2 倍作为硬上限(超限直接断会话或限接收)。对上游运营商可放宽,对 Peer 和下游客户要收严。关键是在"增长"和"雪崩"之间留缓冲:太小会在正常扩容时误断,太大又失去限速意义。 运营商没开 RPKI,我自己开了 ROV 会不会把合法路由也丢掉? 会,如果走"无效即丢弃"模式。正确做法是分状态处理:Valid 放行、Invalid 丢弃、Unknown(未签名)先放行并打标统计。很多前缀目前仍是 Unknown,直接丢会断网。先用屏幕模式(仅记录、不动作)观察两周,确认 Invalid 占比和来源都符合预期,再切到丢弃。这叫"先观测后执行",是运维上线新过滤器的通用纪律。 bogon 和 martian 前缀过滤是什么,为什么必须做? bogon 是尚未分配或保留的地址段(如 RFC1918 私网、文档用的 192.0.2.0/24、还未 IANA 分配的段),martian 是明显非法的段。运营商之间如果互相收了 bogon,攻击者可伪造源 IP 做反射放大。在 eBGP 入方向一律丢弃收到的 bogon 前缀,是 ISP 边界的底线过滤,工作量小、收益高,属于"不做就是失职"的那类防护。 小公司、没自己的 AS 号,还需要关心路由泄露吗? 需要,只是角色变成"防御接收方"。你没有 AS 号去签 RPKI,但你的上游运营商和云厂商(AWS/GCP/Azure 的 BGP 接入)都开了 ROV。你能做的是:在自家边界路由器上启用 ROV 校验、对上游只收默认路由或严格前缀列表、监控收到的路由条数突变。本质是"相信上游但自己留一手校验",避免上游被泄露连累到你。

相关文章