BeyondProd

本页内容的上次更新时间为 2024 年 5 月,代表截至本文撰写之时的状况。由于我们会不断改善对客户的保护机制,Google 的安全政策和系统今后可能会发生变化。

本文档介绍了 Google 如何使用名为 BeyondProdBeyondProd 的云原生架构在我们的基础架构中实现安全性。BeyondProd 是指我们的基础架构中的服务和控制,协同工作以帮助保护工作负载。工作负载是应用完成的独特任务。BeyondProd 有助于保护我们环境中运行的微服务,包括我们如何更改代码以及如何访问用户数据。

本文档是描述技术的一系列技术论文的一部分,这些技术包括我们开发来帮助保护 Google 平台免受复杂威胁的 BeyondCorp Enterprise、 。BeyondCorp Enterprise 实现零信任架构,旨在提供对 Google 平台及其中运行的服务的安全访问。与 BeyondCorp Enterprise 一样,BeyondProd 不依赖于防火墙等传统网络边界保护。BeyondProd 使用代码出处、服务身份和可信硬件等特性来帮助在微服务之间建立信任。这种信任扩展到在 Google Cloud 中运行的软件以及 Google Cloud 客户部署和访问的软件。

本文档介绍 BeyondProd 的优势、其服务和流程,以及我们如何迁移到此架构。如需大致了解我们的基础架构安全性,请参阅 Google 基础架构安全设计概览

简介

现代的安全架构已经超越了基于边界的传统安全模型,传统模型通过防火墙保护边界,而边界内的所有用户或服务被视为可信。

如今,用户采用移动工作方式,常常会在组织的传统安全边界之外(例如家中、咖啡馆或飞机)工作。借助 BeyondCorp Enterprise,我们使用多种因素授予对公司资源的访问权限,包括用户身份、用于访问资源的设备的身份、设备的运行状况、用户行为等信任信号以及访问控制列表。

BeyondProd 解决了与 BeyondCorp Enterprise 对用户相同的生产服务问题。在云原生架构中,我们不能单纯依靠防火墙来保护生产网络。微服务会迁移并部署在不同的环境、跨异构主机,并在各种信任和敏感度级层运行。BeyondCorp Enterprise 声明用户信任应取决于设备内容感知状态(而不是连接到公司网络的能力)等特性,BeyondProd 声明服务信任应取决于代码出处、可信硬件和服务身份等特性,而不是生产网络中的位置,例如 IP 地址或主机名。

容器化基础架构

我们的基础架构将工作负载作为单独的微服务部署在容器中。微服务将应用需要执行的各个任务分离成不同的服务中。每项服务都可以通过各自的 API、发布、扩缩和配额管理来独立开发和管理。微服务是独立的、模块化的、动态的、短暂的。它们可以分布在许多主机、集群甚至云端上。 在微服务架构中,工作负载可能是一项或多项微服务。

容器化基础架构意味着每项微服务都作为自己的一组可移动和可调度的容器进行部署。为了在内部管理这些容器,我们开发了一个名为 Borg容器编排系统,该系统每周部署数十亿个容器。Borg 是 Google 的统一容器管理系统,也是 Kubernetes 的灵感来源。

容器使工作负载更易于、更高效地安排在机器之间。将微服务封装到容器中,可以将工作负载拆分成更易于管理的较小单元,方便维护和发现问题。此架构会根据需要扩缩工作负载 - 如果对特定工作负载有较高需求,则可能有多台机器运行相同容器的副本以处理所需的工作负载规模。

在 Google,安全性在我们架构的每一次演变中都起着至关重要的作用。我们采用这种微服务架构和开发过程的目标,是在开发和部署生命周期中尽早解决安全问题(这一阶段解决问题的花费较低),并通过标准化和一致的方式加以解决。最终的结果是,开发者在确保安全性方面花费的时间更少,同时仍能获得更安全的效果。

BeyondProd 的优势

BeyondProd 为 Google 基础架构提供了许多自动化和安全优势。这些优势包括:

  • 网络边缘保护:工作负载与网络攻击和来自互联网的未经授权的流量相隔离。虽然边界方法不是新概念,但它仍然是云架构的安全性最佳实践。边界方法有助于保护尽可能多的基础架构,使其免受来自互联网的未经授权的流量和潜在的攻击,例如基于卷的 DoS 攻击。
  • 服务之间没有固有的相互信任:只有经过身份验证的、受信任的特定调用者或服务才能访问任何其他服务。这样可以阻止攻击者使用不可信代码访问服务。如果一项服务被破解,这一优势有助于防止攻击者执行扩大其攻击范围的操作。这种“互不信任”机制与精细的访问权限控制相结合,有助于限制危害的范围。
  • 运行具有已知出处的代码的受信任机器:服务身份只能使用经过授权的代码和配置,并且只能在经过验证的授权环境中运行。
  • 一致地跨服务强制执行政策:一致的政策强制执行有助于确保服务决策之间的访问决策可靠。例如,您可以创建一个政策执行来验证对用户数据的访问请求。要访问服务,授权的最终用户必须提供经过验证的请求,并且管理员必须提供业务理由。
  • 简单、自动化、标准化的更改发布:相关人员可以轻松审核基础架构更改对安全性的影响,并且可以在几乎不影响生产环境的情况下发布安全补丁。
  • 共享操作系统的工作负载之间的隔离:服务被破解后不会影响同一主机上运行的其他工作负载的安全性。这种隔离有助于限制危害的范围。
  • 可信硬件和证明:硬件信任根有助于确保在安排任何工作负载运行之前,只有主机上知道且已获授权的代码(从固件到用户模式)运行。

这些优势意味着可以在我们的云架构内运行的容器和微服务可以部署、互相通信并并行运行,而不会削弱基础架构的安全性。此外,个别微服务开发者无需承受底层基础架构的安全性和实现细节的负担。

BeyondProd 安全服务

我们设计并开发了多项 BeyondProd 安全服务,以打造 BeyondProd 优势中讨论的优势。以下部分介绍了这些安全服务。

用于网络边缘保护的 Google Front End

Google Front End (GFE) 提供网络边缘保护。GFE 终止与最终用户的连接,并为强制执行 TLS 最佳实践提供一个中心点。

即使我们的重点已不再是基于边界的安全性,但 GFE 仍是我们保护内部服务免受 DoS 攻击的重要策略部分。GFE 是连接到 Google 基础设施的用户的第一个入口点。用户连接到我们的基础架构后,GFE 还负责根据需要在区域之间均衡负载和重新路由流量。GFE 是将流量路由到适当微服务的边缘代理。

Google Cloud 上的客户虚拟机不向 GFE 注册,而是向 Cloud Front End 注册,Cloud Front End 是使用 Compute Engine 网络堆栈的特殊 GFE 配置。借助 Cloud Front End,客户虚拟机可以使用其公共或专用 IP 地址直接访问 Google 服务。(只有在启用专用 Google 访问通道后才能使用专用 IP 地址。)

服务间的信任层应用安全传输

应用层传输安全 (ALTS) 有助于确保服务之间没有固有的相互信任。ALTS 用于远程过程调用 (RPC) 身份验证、完整性、流量加密和服务身份。ALTS 是一种用于 Google 基础架构服务的相互身份验证和传输加密系统。身份通常绑定到服务,而不是绑定到特定的服务器名称或主机。此绑定有助于实现各主机之间的无缝微服务复制、负载均衡和重新安排。

每台机器均具有使用主机完整性系统预配的 ALTS 凭据,并且只有在主机完整性系统已验证安全启动成功时才能解密。大多数 Google 服务作为微服务在 Borg 上运行,并且这些微服务各自具有自己的 ALTS 身份。Borg Prime(Borg 的集中式控制器)根据微服务的身份将这些 ALTS 微服务凭据授予工作负载。机器级 ALTS 凭据构成了预配微服务凭据的安全通道,只有成功通过主机完整性验证启动的机器才能托管微服务工作负载。如需详细了解 ALTS 凭据,请参阅工作负载证书

可了解代码出处的 Binary Authorization for Borg

Binary Authorization for Borg (BAB) 提供代码出处验证。BAB 是一种部署时强制执行检查,有助于确保代码在部署代码之前符合内部的安全性要求。例如,BAB 强制执行检查包括确保代码在提交到我们的源代码库之前由第二个工程师审核,并且二进制文件可验证地构建在专用基础架构上。在我们的基础架构中,BAB 会限制未经授权的微服务的部署。

机器信任的主机完整性

主机完整性通过安全启动过程验证主机系统软件的完整性,并且由受支持的硬件信任根安全芯片(称为 Titan)提供支持。主机完整性检查包括在 BIOS、基板管理控制器 (BMC)、引导加载程序和操作系统内核上验证数字签名。如果支持,主机完整性检查可能包括用户模式代码和外围设备固件(如 NIC)。除了数字签名验证之外,主机完整性还有助于确保每个主机都运行这些软件组件的预期版本。

用于政策强制执行的服务访问管理和最终用户上下文标签

服务访问权限管理和最终用户上下文标签有助于跨服务提供一致的政策执行。

服务访问管理限制服务之间的数据访问方式。当远程过程调用 (RPC) 从一项服务发送到另一项服务时,服务访问管理会定义服务访问接收服务数据所需的授权和审核政策。这样会限制数据的访问方式、授予所需的最低访问权限级别,以及指定如何审核该访问权限。在 Google 基础架构中,服务访问管理会限制一项微服务对另一项微服务数据的访问,并允许全局分析访问权限控制。

最终用户上下文票证由最终用户身份验证服务发出,并为服务提供独立于其服务身份的用户身份。这些标签是受到完整性保护、集中发放、可转发的凭据,用于证明发出服务请求的最终用户的身份。这些标签可以减少服务之间的信任需求,因为使用 ALTS 的对等方身份可能不足以授予访问权限,前提是此类访问决策通常也基于最终用户的身份。

用于自动发布更改和可伸缩性的 Borg 工具

用于蓝绿部署的 Borg 工具提供简单、自动化和标准化的更改发布。 蓝绿部署是一种在不影响传入流量的情况下发布工作负载更改内容的方法,以便最终用户在访问应用时不会遭遇停机。

Borg 作业是微服务的单个实例,运行应用的某个部分。作业将扩缩以处理负载:在负载增加时部署新作业,在负载减少时终止现有作业。

Borg 工具负责在我们执行维护任务时迁移正在运行的工作负载。部署新的 Borg 作业时,负载均衡器会逐渐将流量从现有作业迁移到新作业。这样,在用户不知不觉中,系统就可以在不停机的情况下更新微服务。

我们还使用此工具在我们添加新功能时应用服务升级,以及在不停机的情况下应用重要的安全更新。对于影响我们的基础架构的更改,我们会使用客户虚拟机的实时迁移来帮助确保工作负载不受影响。

如需了解详情,请参阅 Binary Authorization for Borg

用于工作负载隔离的 gVisor 内核

gVisor 内核可在共用一个操作系统的各工作负载之间实现隔离。gVisor 使用用户空间内核来拦截和处理系统调用,从而减少与主机和潜在攻击面的交互。此内核提供了运行应用所需的大部分功能,并限制应用可访问的主机内核表面。gVisor 是我们用来隔离在同一主机上运行的内部工作负载和 Google Cloud 客户工作负载的多种工具之一。如需详细了解其他沙盒工具,请参阅代码沙盒

使用 BeyondProd 保护用户数据

本部分介绍 BeyondProd 服务如何协同帮助保护我们基础架构中的用户数据。以下部分介绍了两个示例:

  • 访问从创建的用户数据到传递到目标位置的数据请求。
  • 从开发到生产的代码更改。

并非所有列出的技术都用于我们基础架构的所有部分;这取决于服务和工作负载。

访问用户数据

下图展示了我们的基础架构用于验证用户是否可以访问用户数据的过程。

Google 的云原生安全控制措施访问用户数据。

访问用户账号的步骤如下所示:

  1. 用户向 GFE 发送请求。
  2. GFE 终结 TLS 连接并使用 ALTS 将请求转发到相应服务的前端。
  3. 应用前端使用中央最终用户身份验证 (EUA) 服务对用户的请求进行身份验证,如果成功,则接收短期加密的最终用户上下文标签。
  4. 然应用前端通过 ALTS 向存储后端服务发出远程过程调用 (RPC),从而在后端请求中转发标签。
  5. 后端服务使用服务访问管理来确保满足以下条件:
    • 前端使用有效的未撤消证书进行身份验证。此检查意味着它正在可信主机上运行,并且 BAB 检查成功。
    • 系统授权前端服务的 ALTS 身份向后端服务发出请求并提供 EUC 标签。
    • 最终用户上下文票据有效。
    • EUC 标签中的用户有权访问请求的数据。

如果这些检查中的任何检查失败,则请求会被拒绝。

如果这些检查通过,则数据会返回到获得授权的应用前端,并提供给获得授权的用户。

在许多情况下,存在一系列后端调用,并且每个中间服务都会对入站远程过程调用 (RPC) 执行服务访问检查,而在执行出站远程过程调用 (RPC) 时会转发标签。

如需详细了解流量在基础架构内的路由方式,请参阅流量路由方式

更改代码

下图展示了如何部署代码更改。

如何更改代码。

更改代码的步骤如下:

  1. 开发者对受 BAB 保护的微服务做出了更改。更改被提交到我们的中央代码库,该代码库会强制执行代码审核。 获得批准后,更改的内容会提交到受信任的中央构建系统,该系统会生成一个包含已签名的可验证构建清单证书的软件包。

  2. 在部署时,BAB 会验证来自构建流水线的签名证书,从而验证是否执行了上述流程。

  3. Borg 使用可靠性模型来处理所有工作负载更新,该模型可确保最大限度地减少服务(无论是常规发布还是紧急安全补丁)中断。

  4. GFE 使用负载均衡将流量迁移到新部署,以帮助确保操作的连续性。

如需详细了解此过程,请参阅我们的开发和生产过程

所有工作负载都需要隔离。如果工作负载不太可信(因为源代码来自于 Google 外部),则可能会部署到受 gVisor 保护的环境中,或使用其他隔离层。这种隔离有助于抵御恶意入侵应用的攻击者。

云原生安全性影响

以下部分对比了传统基础架构安全性方面与云原生架构中的安全性方面。

应用架构

较传统的安全模型专注于基于边界的安全性,无法独力保护云原生架构。传统上,单体式应用采用三层架构,并部署到私有公司数据中心,这些数据中心有足够的容量来处理重要事件的峰值负载。具有特定硬件或网络要求的应用被特意部署到通常保留固定 IP 地址的特定机器上。更新的发布频率较低、规模较大、难以协调,因为更新所带来的更改同时影响了应用的许多部分。这会导致应用的生命周期极长,而且更新频率较低,其安全补丁的应用频率通常也较低。

然而,在云原生模型中,应用必须在不同的环境之间移植,因为它们可以在公有云、私有数据中心或第三方托管的服务上运行。因此,拆分为微服务的容器化应用非常适合云端环境,而不是单体式应用。容器可将您的应用所需的二进制文件与底层主机操作系统分离,使应用更具可移植性。我们的容器是不可变的,这意味着容器在部署后不会更改,但会频繁重新构建和重新部署。

由于容器会频繁重启、停止或重新调度,因此硬件和网络会得到更加频繁的重复使用和共享。借助通用的标准化构建和分发流程,团队之间的开发流程更加一致、统一,即使团队独立管理其微服务的开发也是如此。因此,安全性相关事务(例如安全性审核、代码扫描和漏洞管理)可以在开发周期的早期阶段进行。

Service Mesh

通过构建所有开发者都使用的共享且安全设计的基础架构,开发者在了解和实施常见安全要求方面的负担会降至最低。安全功能应该几乎不需要集成到各个应用中,而是作为封装和连接所有微服务的结构来提供。这通常称为服务网格。这也意味着可以与常规开发或部署活动分开管理和实施安全性。

服务网格是基础架构层的共享结构,其中包含和连接所有微服务。服务网格允许服务到服务的通信,从而控制流量、应用政策以及集中监控服务调用。

零信任安全性

在使用私有数据中心的传统安全模型中,组织的应用依靠防火墙来帮助保护工作负载免受基于网络的外部威胁。

在零信任安全性模型中,授权决策不依赖于防火墙。其他控制措施(如工作负载身份、身份验证和授权)可确保内部或外部连接在能够处理事务之前得到验证,从而帮助保护微服务。当您不再依赖防火墙或基于网络的控制时,可以实现微服务级层细分,使得服务之间没有固有的信任。借助微服务级层细分,流量可以具有不同的信任级别和不同的控制措施,并且您不再仅比较内部与外部流量。

集成到服务堆栈中的共享安全性要求

在传统的安全性模型中,各个应用负责独立于其他服务来满足自己的安全性要求。此类要求包括身份管理、TLS 终结和数据访问管理。这可能会导致实现不一致或安全问题尚未解决,因为这些问题必须在许多地方得到修复,这使得应用修复变得更加困难。

在云原生架构中,服务在服务之间重复使用的频率要高得多。关卡确保跨服务一致强制执行政策。您可以使用不同的安全性服务来强制执行不同的政策。您可以将各种政策拆分成单独的微服务,而不是要求每个应用单独实施重要的安全性服务。例如,您可以创建一项政策以确保对用户数据进行授权的访问,并创建另一项政策以确保使用最新的 TLS 加密套件。

更频繁地发布的标准化流程

在传统的安全性模型中,共享服务很有限,代码经常重复并与本地开发相结合。有限共享使您很难确定一项更改的影响,以及该更改对应用的许多部分有何影响。因此,发布很少,并且很难协调。为了进行更改,开发者可能必须直接更新每个组件(例如,打开与每个虚拟机的 SSH 连接以更新配置)。总的来说,这会导致应用的生命周期极长。

从安全性角度来看,由于代码经常重复,因此审核难度更大,甚至会带来更大的挑战,即:在修复某个漏洞后,确保在所有地方都修复该漏洞。

在云原生架构中,发布会频繁且标准化。此过程可让安全性在软件开发生命周期中提前实现。“提前”指的是在软件开发生命周期中提前执行相关步骤,其中可能包括编写代码、构建、测试、验证、部署等步骤。“提前”可实现更简单、更一致的安全性强制执行措施,包括定期应用安全补丁。

对 BeyondProd 进行更改

Google 采用 BeyondProd 时,需要对基础架构和开发过程这两个主要方面进行更改。我们同时完成了这些更改,但如果您想在自己的环境中进行类似设置,可以独立处理这些更改。

更改我们的基础架构

我们的目标是在整个基础架构中自动实现安全性,因为我们认为安全性的扩缩方式应该与服务的扩缩方式相同。服务必须从设计上保证安全;只有明确决定接受风险后才会变得不安全。对我们基础架构的直接人工干预应是例外情况(而非日常),并且干预应该在可审核的情况下进行审核。然后,我们可以根据为某项服务部署的代码和配置(而不是部署该服务的人员)来对该服务进行身份验证。

我们首先构建了服务身份、身份验证和授权的强大基础。 微服务使用服务身份向基础设施中运行的其他服务验证自己的身份。有了受信任服务身份作为基础,我们就可以实施更高级别的安全功能(例如服务访问权限管理和最终用户上下文标签),这些功能依赖于对这些服务身份进行验证。为了使新服务和现有服务的这种转换变得简单,我们首先提供了 ALTS,作为具有单个帮助程序守护进程的库。此守护进程在每项服务调用的主机上运行,并随着时间的推移逐步演变为使用服务凭据的库。ALTS 库无缝集成到核心 RPC 库中。此集成使得其更容易获得广泛采用,并且不会给个别开发团队带来沉重的负担。发布 ALTS 是发布服务访问管理和最终用户上下文标签的前提条件。

更改我们的开发流程

建立强大的构建和代码审核流程对 Google 正在运行的服务的完整性来说至关重要。我们创建了一个集中式构建流程,在该流程中,我们可以开始强制执行一些要求,例如要求在构建和部署时有两个人参与代码审核和自动化测试。(如需详细了解部署,请参阅适用于 Borg 的 Binary Authorization。)

完成这些基础工作以后,我们就开始着手满足在我们的环境中运行不受信任的外部代码的需要。为了实现此目标,我们开始进行沙盒测试 - 最初使用 ptrace,后来使用 gVisor。同样,蓝绿部署在安全性(例如修补)和可靠性方面提供了明显的优势。

我们很快发现,如果服务从一开始就记录违反政策的行为(而不是阻止违反政策的行为),则我们的目标更容易实现。这一方法具有双重优势:

  • 它让服务所有者有机会测试更改的内容并评估迁移到云原生环境对其服务产生的影响(若有)。
  • 它使我们能够修复任何 Bug,并确定我们可能需要向服务团队提供的其他任何功能。

例如,服务登录到 BAB 时,服务所有者会启用“仅限审核”模式。这有助于他们识别不满足要求的代码或工作流。解决了“仅限审核”模式所标记的问题后,服务所有者会启用强制执行模式。在 gVisor 中,我们首先将工作负载布置在沙盒中(即使沙盒功能存在兼容性问题),然后系统地解决这些兼容性问题以改善沙盒,从而达到我们的目的。

后续步骤