订阅以接收新文章的通知:

Cloudflare 服务器不再拥有 IP - 那么它们如何连接到互联网?

2022/11/25

19 分钟(阅读时间)
Cloudflare servers don't own IPs anymore – so how do they connect to the Internet?

Cloudflare 的很多技术都是有据可查的。例如,我们如何处理眼球(客户)和我们的服务器之间的流量,在这个博客上已经讨论过很多次:“anycast的简单入门(2011)”, "没有负载平衡器的负载平衡(2013)", "实际操作中的路径 MTU 发现(2015)",  "Cloudflare 的边缘负载平衡器(2020)", "我们如何修复 BSD 套接字 API(2022)"。

然而,我们很少谈及我们网络设置的第二部分--我们的服务器如何从互联网上获取内容。 在这篇博客中,我们将介绍这一差距。 我们将讨论我们如何管理用于从互联网检索数据的 Cloudflare IP 地址,我们的出口网络设计是如何发展的,以及我们如何优化它以最佳方式利用可用的 IP 空间。

打起精神来。 我们有很多内容要讲。

术语第一!

每台 Cloudflare 服务器都要处理许多种网络流量,但有两个粗略的类别非常突出:

  • 互联网来源的流量 - 由眼球向我们的服务器发起的入站连接。在这篇博文中,我们将这些称为"入口连接"。
  • Cloudflare来源的流量 - 由我们的服务器向互联网上的其他主机发起的传出连接。为简洁起见,我们将这些称为"出口连接"。

虽然在这个博客上很少讨论,但出口部分对我们的运作至关重要。 我们的服务器必须启动传出连接来完成它们的工作! 喜欢:

  • 在我们的 CDN 产品中,在缓存内容之前,内容是从源服务器中获取的。参见《 Pingora,将 Cloudflare 连接到互联网的代理(2022) 》、 Argo分层缓存
  • 对于 Spectrum 产品,每个入口 TCP 连接会导致一个出口连接。
  • Workers ,经常运行多个子请求来构建一个 HTTP 响应。其中一些可能是对互联网的服务器进行查询。
  • 我们还运营面向客户的前向代理产品--如 WARP 和 Cloudflare Gateway。这些代理机构处理的是以互联网为目的地的眼球连接。 我们的服务器需要代表我们的用户与互联网建立连接。

等等

入口的 Anycast,出口的单播

我们的入口网络架构与出口网络架构非常不同。 在入口处,来自互联网的连接完全由我们的 anycast IP 范围处理。 Anycast 是一种技术,我们的每个数据中心"宣布" ,并可以处理相同的IP范围。 由于可能有许多目的地,互联网如何知道将数据包路由到哪里? 那么,根据互联网 BGP 指标,眼球数据包被路由到最近的数据中心,往往也是地理上最近的一个。 通常情况下,BGP 路由变化不大,每个眼球IP可预期被路由到一个单独数据中心。

然而,虽然 Anycast 在入口方向工作良好,但它不能在出口方向操作。 从一个 Anycast IP 建立一个出口连接并不可行。想一想响应数据包。 它很可能被路由回一个错误的地方--在地理上最接近发件人的数据中心,而不一定是源数据中心!

由于这个原因,直到最近,我们都是以一种直接和传统的方式建立出口连接:每个服务器都获得自己的单播 IP 地址。 "单播 IP" 意味着世界上只有一个服务器在使用该地址。 返回的数据包将正常工作,并准确地返回到由单播 IP 识别的正确服务器。

根据出口 IP 对流量进行分割

最初,由 Cloudflare 提供的连接主要是前往互联网上的源服务器的HTTP 提取。随着我们产品线的增长,流量的种类也越来越多。最明显的例子是我们的 WARP 应用程序。对于 WARP,我们的服务器运行一个前向代理,并处理由最终用户设备产生的流量。这是在没有与我们的 CDN 产品相同程度的中介的情况下完成的。这就产生了一个问题。互联网上的第三方服务器--如源服务器--必须能够区分来自Cloudflare 服务的连接和我们的 WARP 用户的连接。这种流量细分传统上是通过对不同的流量类型使用不同的IP范围来完成的(尽管最近我们引入了更强大的技术,如 Authenticated Origin Pulls )。

为了解决受信任与不受信任的流量池差异问题,我们在每台服务器上添加了一个不受信任的 WARP IP 地址:

国家标记的出口 IP 地址

很快就发现,受信任与不受信任并不是唯一需要的标记。 对于 WARP 服务,我们还需要国家标记。 例如,英国的 WARP 用户希望 bbc.com 网站只是工作。 然而,BBC 将其许多服务限制在仅允许英国境内的人使用。

它通过地理围栏 —— 使用一个数据库将公共IP地址映射到国家,并只允许英国的 IP 地址。地理围栏在今天的互联网上是很普遍的。为了避免地理围栏问题,我们需要根据 WARP 用户的位置,选择特定的出口地址,并标记一个适当的国家。像互联网上的许多其他各方一样,我们用国家代码标记我们的出口IP空间,并将其作为地理信息发布(如这个 )。注意,发布的 geofeed 只是数据。实际上,一个IP被标记为英国并不意味着它是从英国提供的,它只是意味着运营商希望它被地理定位到英国。像互联网上的许多事情一样,其前提是基于信任。

注意,在这一点上,我们有三个独立的地理标记:

  • WARP 用户的国家标记 - 连接 IP 的眼球
  • 该眼球所连接的数据中心的位置
  • 出口 IP 的国家标记

为了获得最佳服务,我们要选择出口 IP,使其国家标记与眼球IP的国家相匹配。 但是,从一个特定的国家标记的 IP 出口是具有挑战性的:我们的数据中心为来自世界各地的用户服务,可能是来自许多国家的用户! 记住:由于 Anycast,我们不直接控制入口的路由。 互联网的地理环境并不总是与自然地理环境相符。 例如,我们的伦敦数据中心不仅接收来自英国用户的流量,而且还接收来自爱尔兰和沙特阿拉伯的流量。 因此,我们在伦敦的服务器需要很多与国家相关的 WARP 出口地址:

你能看出它要前往哪里吗? 问题空间就这样爆发了! 以前每台服务器有一个或两个出口 IP 地址,现在我们需要几十个,而 IPv4 地址并不便宜。 通过这种设计,每台服务器需要有很多地址,而我们运营着成千上万的服务器。 这种架构变得非常昂贵。

Anycast 广播是个问题吗?

让我回顾一下:在 Anycast 入口处,我们不控制用户被路由到哪个数据中心。 因此,我们的每一个数据中心都必须能够从一个具有任何可以想象的标记的地址流出。 在数据中心内,我们也不能控制连接被路由到哪个服务器。 可能有许多标记,许多数据中心,以及数据中心内的许多服务器。

也许问题出在入口架构上?也许使用传统的网络设计更好,即用 DNS 将特定的眼球路由到特定的数据中心,甚至是服务器?

这是一种思考方式,但我们决定不这样做。 我们喜欢在入口处进行 Anycast。 它给我们带来了许多好处:

  • 性能:根据定义,通过 Anycast,眼球被路由到最近的(按 BGP 指标)数据中心。这通常是指定用户的最快数据中心。
  • 自动故障转移:如果我们的一个数据中心变得不可用,流量将立即自动重新路由到下一个最佳地点。
  • DDoS 弹性:在拒绝服务攻击或流量峰值期间,负载在许多数据中心之间自动平衡,从而大大减少影响。
  • 统一软件:每个数据中心和数据中心内的每台服务器的功能都是相同的。我们在世界各地的所有服务器上使用相同的软件堆栈。每台机器可以对任何产品进行任何操作。这可以使调试更容易,可扩展性更好。

由于这些原因,我们希望在入口处保留 Anycast。我们决定用其他方式来解决出口地址基数问题。

解决一百万美元的问题

在我们运营的数千台服务器中,每一台都应该能够使用一个带有任何可能标记的出口 IP。 要解释我们的解决方案,最简单的是先展示两个极端的设计。

每台服务器拥有所有需要的 IP :每台服务器拥有所有专门的出口 IP,并带有需要的标记。

一台服务器拥有所需的 IP :一个具有特定标记的专门的出口 IP 位于一个地方,其他服务器将流量转发给它。

这两种选择都有优点和缺点:

每台服务器上都有专用 IP 一台服务器上的专用 IP
价格超级昂贵,每台服务器都需要许多个 IP 地址。 价格便宜,一个标记只需要一个专门的 IP。
出口始终在本地 - 快速 出口几乎总是被转发 - 缓慢
卓越的可靠性 - 每台服务器都是独立的 可靠性差 - 引入了拥堵点

有第三种方法

我们一直在认真思考这个问题。 坦白说,让每个 Cloudflare 服务器上都有每个需要的 IP,这第一个极端选项并非完全不可行。 这大致上就是我们为 IPv6 所能做到的。 有了 IPv6,获取所需的大量 IP 空间就不是问题了。

然而,在 IPv4 中,这两种选择都不能接受。 第一种方法提供快速和可靠的出口,但需要高昂的成本--所需的 IPv4 地址很昂贵。 第二种方案使用尽可能小的 IP 空间,所以它很便宜,但在性能和可靠性上有所妥协。

我们设计的解决方案是在两个极端之间找到妥协。 大致的想法是改变分配单位。 我们没有为每台服务器分配一个 /32 IPv4 地址,而是设计了一种方法,为每个数据中心分配一个 /32 IP,然后在物理服务器之间共享。

每台服务器上都有专用 IP 每个数据中心的专用 IP 一台服务器上的专用 IP
价格超级昂贵 价格合理 价格实惠
出口始终在本地 - 快速 出口始终在本地 - 快速 出口几乎总是被转发 - 缓慢
卓越的可靠性 - 每台服务器都是独立的 卓越的可靠性 - 每台服务器都是独立的 可靠性差--许多拥堵点

在数据中心内共享一个 IP

服务器之间共享一个 IP 的想法并不新鲜。传统上,这可以通过路由器上的 Source-NAT 实现。遗憾的是,我们需要的出口 IP 的数量和我们的运行规模,使我们无法在路由器层面上依赖状态防火墙 /NAT。我们也不喜欢共享状态,所以我们并不热衷于分布式 NAT 安装。

我们选择的方式是通过端口范围将一个出口 IP 分割到各个服务器。对于一个给定的出口 IP,每台服务器都拥有一小部分可用的源端口——一个端口片。

当返回的数据包从互联网到达时,我们必须将它们路由回正确的机器。对于这项任务,我们已经自定义 "Unimog" - 我们基于 L4 XDP 的负载平衡器 - ("Unimog, Cloudflare的负载平衡器(2020) "),这个方法非常有效。

使用 2,048 个端口的端口片,我们可以在 31 个服务器之间共享一个 IP。但是,总是存在端口用完的可能性。为了解决这个问题,我们想尽办法高效地重新利用出口端口。请参阅“如何避免端口不足 (2022) ”、“如何共享 IPv4 地址 (2022) ”和我们的 Cloudflare.TV 部分

基本上就是这样了。每台服务器都知道它拥有哪些 IP 地址和端口片。对于入站路由,Unimog 会检查端口并将数据包分配给适当的机器。

数据中心之间共享一个子网

但这并不是故事的结束,我们还没有讨论如何将一个 /32 地址路由到一个数据中心。传统上,在公共互联网上,只能对粒度为 /24 或 256 个 IP 地址的子网进行路由。 在我们的案例中,这将导致 IP 空间的极大浪费。

为了解决这个问题并提高我们的IP空间的利用率,我们将我们的出口范围部署为... anycast !有了这些,我们自定义了 Unimog,并教它通过我们的骨干网络转发数据包到正确的数据中心。Unimog 可维护这样一个数据库:

198.51.100.1 - forward to LHR
198.51.100.2 - forward to CDG
198.51.100.3 - forward to MAN
...

借助这种设计,返回的数据包被送到哪个数据中心就不再重要。 Unimog 可以随时修复它,并将数据转发到正确的地方。 基本上,虽然在 BGP 层我们使用 Anycast,但由于我们的设计,从语义上讲,一个 IP 可识别一个数据中心,一个 IP 和端口范围可识别一个特定的机器。 这种行为方式几乎像一个单播。

我们把这个技术栈称为“软单播”,感觉很神奇。这就像我们在 BGP 层的 Anycast 上进行软件单播。

软性单播无异于魔法

通过这种设置,我们可以取得显著的效益:

  • 我们能够在许多服务器之间共享一个 /32 出口 IP 。
  • 我们可以将一个子网分布在许多数据中心,并可以很容易地在传输中改变它。这使我们能够充分利用我们的出口 IPv4 范围。
  • 我们可以把类似的 IP 地址归类为一组。例如,所有被标记为 "UK" 的 IP 地址可能形成一个单一的连续范围。这就减少了发布的地理信息的大小。
  • 我们很容易载入新的出口 IP 范围 ,如客户的 IP。这对我们的一些产品来说非常有用,如 Cloudflare Zero Trust  。

所有这些都可以在合理的成本内完成,而且不会影响性能和可靠性:

  • 通常情况下,用户能够直接从最近的数据中心出口,提供尽可能好的性能
  • 根据实际需要,我们可以分配或释放IP地址。这使我们可以灵活调整 IP 成本管理,从而不会在前期出现超支。
  • 由于我们在不同地点运营多个出口IP地址,可靠性不会受到影响

我们的IP地址的真正位置是:"云"

虽然软单播使我们获得了巨大效率,但我们也遇到了一些问题。 有时我们会遇到一个问题:"这个 IP 实际存在于哪里?"。但这个问题没有答案! 我们的出口 IP 不会真实存在于任何地方。从 BGP 的角度看,我们的出口范围是 Anycast,所以它们无处不在。 从逻辑上讲,每个地址每次用于一个数据中心,但我们可以根据需要移动它。

内容交付网络会误导用户

另举一个例子,这是我们在第三方 CDN 上遇到的一个问题。 正如我们之前提到的,在我们的管道中,有三个国家标记:

  • 眼球所连接的 IP 的国家标记。
  • 我们数据中心的位置。
  • 我们为出口连接选择的 IP 地址的国家标记。

我们的出口地址被标记为 "UK",这并不总是意味着它实际上是在英国使用。我们已经有过案例,当一个标记为 UK 的 WARP 用户,由于我们的 LHR 数据中心的维护而被路由到巴黎。一个热门 CDN 对我们的出口 IP 进行了反向查询,发现它被标记为 "UK" ,并将用户引导到伦敦的 CDN 服务器。 一般情况下这没什么问题......但我们当时实际上是从巴黎传出的。这个用户最终将数据包从他们在英国的家路由到巴黎,再回到英国。这样做显然没什么性能可言。

我们通过在出口数据中心执行 DNS 请求来解决这个问题。对于 DNS,我们使用标有数据中心位置的 IP 地址 ,而不是用户的预定地理位置。这通常能解决这个问题,但可悲的是,仍然有一些例外。

未来就在这里

我们 2021 年在 Addressing Agility 的实验证明我们有很多机会对入口寻址进行创新。软单播向我们展示了我们可以在出口端实现巨大的灵活性和密度。

随着每个新产品的推出,我们在出口处需要的标记数量也在增加--从流量可信度、产品类别到地理位置。 随着可用的 IPv4 地址池的缩小,我们可以肯定在该领域将有更多的创新。 软单播是我们的解决方案,但可以肯定的是,这不会是我们的终点。

不过现在看来,我们正在远离传统的单播。 我们的出口 IP 真的不再存在于一个固定的地方,我们的一些服务器现在甚至不拥有一个真正的单播 IP。

我们保护 整个企业网络,帮助客户 高效构建互联网规模应用,加速任何 网站或互联网应用,抵御 DDoS 攻击,阻止 黑客,并为您的 Zero Trust 之旅提供协助

从任何设备访问 1.1.1.1,使用我们的免费应用加速和保护您的互联网。

如需进一步了解我们帮助构建更美好互联网的使命,请从 这里 开始。如果您正在寻找新的职业方向,请查看 我们的空缺职位
Network (CN)简体中文

在 X 上关注

Marek Majkowski|@majek04
Cloudflare|@cloudflare

相关帖子