狩猎困扰的BGP路线

2021-04-22 11:42:58

BGP是构成互联网的所有数千路由器之间的胶水(您可以找到这篇文章(战舰)和这篇文章(夏娃)作为BGP如何工作的崩溃课程)。

使用当前包含大约1,000,000条路线的“默认自由区域”,该表最多可以了解如何达到几乎所有内容的路由信息​​。然而,正如在侧面项目(BGP.Tools)的同时慢慢困扰我,那个路由器并不总是有最新信息......

要了解一个卡住的路线,您必须先了解与BGP的路线/前缀的自然生命周期。

在上面的示例中,您可以看到可达性信息沿连接路由器链传递。当始发路由器撤销前缀/路由时,也沿着对等体传递该信息,并且假设这些对等体没有有关如何达到该IP前缀的替代信息,则IP前缀变得无法访问。

在此示例中,中间路线确实已发送了提款信息,但无论出于何种原因,它会出现何处。

这是糟糕的,因为中间的下游路由器没有意识到前缀/路由的不可用,这意味着它们可能会继续发送流量。这也意味着存储器仍然消耗以保持不再可达的路由。根据内存可能是非常有价值的情况(和有限)的情况。

要检查问题的情况是多么糟糕,我设置了一个BGP路由骑车者,它将宣布不同的IPv6前缀每月的每个日历日。这方面这意味着系统应该只看到来自ME,A / 40 IPv6块的两条路线,以及每日更改的较小的“孔打孔”/ 48:

然而,正如预期的那样,经过一段时间的运行,一小堆叠的路线开始弹出各种网站,如bgp.he.net:

那是什么给了?这些路线如何陷入困境?他们陷入困境的地方?我们能否坚持他们?

所以我试图通过调查成熟-NCC RIS MRT文件来跟踪它们。

前缀:2a0b:6b86:d28 :: / 48prefix_as_path:2a0b:6b86:d28 ::/ 48 [[50673 33891 1299 6939 4261299 6939 4261299 6939 4261299 6939 4261299 6939 4261299 6939 4261299 6939 4261299 6939 4261299 6939 4261299 6939 4261292232]] prefix_as_path:2a0b:6b86:d28 ::/ 48 ]] prefix_as_path:2a0b:6b86:d28 ::/ 48:280b:6b86 299 6939 42612928628 D28 :: / 48 [[49697 61438 33891 1299 6939 42615 212232]] PREFIX_AS_PATH:2a0b:6b86:D28 :: / 48 [[51184 47692 33891 1299 6939 42615 212232]]

在这里,我们可以看到一个被困的前缀(写作时的一天是第12个,但前缀为28日),我们假设基于这些路径的一些东西。 AS212232是宣布ASN,这是我。它遵循我的上游(42615),然后飓风电气(6939),然后Telia(1299),然后击中核心骨干(33891),似乎卡住了。我们可以看到这一点,因为在那一点上它开始攻击其他网络,因此它可能更有可能内核心骨干内的路由器未能处理当天发出的撤销消息。

在这种情况下,它非常无害,但随着全球路线表继续越来越长的“随意”的陷入困境可能会变得相当烦人。

然而,有时候没有撤回可能是灾难性的。 2020年8月30日最大的载体之一(Lumen,更好地称为CenturyLink,他购买了3级)推出了防火墙规则来阻止其网络上的所有内部BGP流量。此FlowsPec规则在其网络内部导致质量混沌,导致广泛的无法合理,但常规载体中断的差异是他们的路由器未发送BGP,以指示他们无法向其同行和客户提供部分网络。由于这一中断在解决之前已经持续了数小时。许多网络必须争夺以改变配置,以避免所有成本的流明/级别3。他们的路由器未撤销路线的确切原因尚不清楚,但还有其他公共写入的事件造成的混乱

然而,有一种方法可以发生这种情况,它是由BGP协议本身的更普遍的缺陷引起的。

BGP在TCP上运行(尽管它还保留了UDP和SCTP端口号),并且受到TCP套接字语义的影响,Daniel Morsing最佳描述为“TCP是一个欠指定的两节点共识算法”。

请记住,它也值得理解BGP自己的内部计时器:

#bird2c spa rr1bird e7aa-x Ready.name proto表格状态以来inforr1 bgp --- up 2021-01-27建立的bgp状态:已建立的邻居地址:xxx.xxx.xxx.xxx邻居为:206924邻居ID:xxx.xxx .xxx.xxx ...保持计时器:198.758 / 240 Keepalive计时器:6.716 / 80 ...

BGP有两个内部定时器,保持计时器是一个倒计时计时器,因为它已经从对等体接收了keepalive数据包,并且keepalive计时器是一个倒计时计时器,直到进程本身发送keepalive数据包到同行。

如果保持计时器达到0,则假设对等体变得不可用(由于TCP无法在连接黑洞时快速发现)。

协议内的致命缺陷在邮件列表发布到IET中的作业Snijders指出的是,BGP守护进程可能不会处理对等体具有0个大小的TCP窗口时的边缘情况。

零窗口是TCP插座的常用边缘案例。当套接字应用程序的远程侧未读取其自己的TCP接收队列时,它们通常会发生,因为这是有限量,将填充尚未读取的数据。在远程TCP堆栈中没有选项,但可以说它无法接受任何更多数据(AKA,它的TCP窗口是0字节大)。这意味着本地方面自己的发送队列将开始填充,但这也是有限的,当本地发送队列已满时。对套接字的写入调用将阻止或返回eWOLDBLOCK。这意味着数据无法再将其写入套接字。

在BGP中,这似乎导致远程对等体无法发送Keepalive,停止,更新和提取消息。

我建立了一个可以重现这个的测试,工作细胞们确认瞻博网络,Arista,思科以及鸟,Quagga / FRR都挂起,无法发送Keepalives或任何其他数据,但它们不会终止会话。

问题是,根据网络条件,这可能会丑陋。例如:

假设您对恶意BGP对等体进行了运行会话。同行可以根据需要将其TCP窗口减少到0。

然后,这会阻止您向路由器发送消息或对它们作用,但它会允许恶意路由器向您发送。因此,它可以继续发送要保持保持计时器的keepalive才能到期,它也可能阻止您完全关闭会话,或发送路由更新。

虽然我没有理由相信这是恶意在现实世界中被剥削的,但我怀疑它是在几个地方错误发生的

对此的解决方案是发明一个新的第二种计时器,它与BGP中已经存在的“保持定时器”类似,除了它倒数能够成功发送一些东西。 由于发送几乎即时此计时器击中零信号,该路由器可能妨碍负责任地传递交通的路由器。 所以关闭BGP凝视将是一个负责任的事情。 为此,我们需要修补BGP的RFC来添加它,这意味着获得RFC。 与此同时,您可以关注我,工作Snijders,也许是在https://datatracker.ietf.org/doc//draft-spaghetti上写出RFC(或在它的当前陈述互联网草稿中)的其他冒险 -idr-bgp-securedholdtimer 在那时,零窗口边缘壳体可以在路由器中大约一段时间。 如果您想与博客保持最新信息,您可以使用RSS Feed或者您可以在Twitter上关注我