在本白皮书中,我们详细介绍了 Google 的多个基础架构如何在一个现在称为“云原生”的架构中共同保护工作负载。如需大致了解 Google 的安全性,请参阅安全性基础架构设计白皮书。
本文包含的内容截至 2019 年 12 月是正确无误的。本白皮书介绍的是撰文之时的现状。随着我们持续改善对用户的保护机制,Google Cloud 的安全政策和系统未来可能会发生变化。
术语库
本文档中使用了以下定义:
微服务将应用需要执行的各个任务分离成单独的服务,每项服务都可独立进行开发和管理,并且具有自己的 API、发布、扩缩和配额管理。在更现代化的架构中,诸如网站之类的应用可作为一组微服务运行,而不是作为单一的服务运行。微服务是独立的、模块化的、动态的、短暂的。它们可以分布在许多主机、集群甚至云端上。
工作负载是应用完成的独特任务。在微服务架构中,工作负载可能是一项或多项微服务。
作业是运行一个应用某个部分的单个微服务实例。
微服务使用服务身份向基础架构中运行的其他服务验证自己的身份。
服务网格是用于服务到服务通信的基础架构层,可控制流量、应用政策以及集中监控服务调用。使用微服务架构时,服务网格可以消除各项服务实施这些控制的负担,并允许跨许多微服务进行更简单的集中式管理。
面向首席信息官级别领导者的摘要
Google 的基础架构将工作负载作为单独的微服务部署在容器中,并使用 Borg(我们的容器编排系统)管理这些工作负载。这就是如今众所周知的“云原生”架构的灵感和模板。
Google 的基础架构在设计时就充分考虑了安全性,而不是后来才想起要添加安全功能。我们的基础架构假定其服务之间不应互相信任。
Google 通过一项名为 BeyondProd 的计划保护其微服务。这一保护措施的范围包括如何更改代码以及如何访问微服务中的用户数据。BeyondProd 应用的概念包括:互相进行身份验证的服务端点、传输安全性、具有全局负载平衡和拒绝服务攻击保护的边缘终止、端到端代码出处以及运行时沙盒。
从传统的安全模型迁移到云原生安全模型要求我们对基础架构和开发过程这两个主要方面进行更改。在包含和连接所有微服务的共享结构(也称为服务网格)中构建共享组件,可以更轻松地推出更改的内容并实现跨服务的一致安全性。
动机
为了提高资源利用率、构建可用性高的应用并简化 Google 开发者的工作,Google 采用了容器和容器编排技术。促使我们采用容器化基础架构的另一个动机是为了让我们的安全控制措施与我们的架构保持一致。我们早就知道,基于边界的安全模型不够安全。一旦攻击者突破了边界,就可以在边界内的网络中畅行无阻。虽然我们意识到我们需要加强整个基础架构的安全控制措施,但我们也希望 Google 开发者能够轻松编写和部署安全应用,而不必自行实现安全功能。
从单体式应用迁移到使用编排系统从容器部署的分布式微服务,具有明显的操作优势:更简单的管理和可扩缩性。这种云原生架构需要使用不同的安全模型和不同的工具来保护与微服务的管理和可扩缩性优势协调一致的部署。
本文档介绍了 Google 如何实施云原生安全性(本文档称为 BeyondProd):更改至云原生对安全性的意义、云原生安全性原则、为满足这些要求而构建的系统,以及有关如何自行应对类似更改的一些指导。
Google 的云原生安全性
容器化的微服务
从早期开始,Google 便有意识地决定利用低成本商用服务器扩大数据中心容量,而不是投资购买更昂贵的高可用性硬件。我们以前、现在和将来的可靠性指导原则是,系统的任何单一部分发生故障,都不会影响用户服务的可用性。为了实现这种可用性,需要运行冗余的服务实例,以便单一故障不会导致服务中断。基于这种原则,我们开发了容器、微服务和容器编排技术,从而能够以可扩缩的方式管理这些高度冗余和分布式系统的部署。
容器化基础架构意味着每个工作负载都作为自己的一组不可变、可移动、可调度的容器进行部署。为了在内部管理这些容器,我们开发了一套名为 Borg1 的容器编排系统,目前我们每周仍使用该系统部署数十亿个容器。
容器使工作负载更易于跨机器封装和重新调度。借助微服务,开发者可以更轻松地开发和调试应用的不同部分。如果将微服务和容器搭配使用,可以将工作负载拆分成更易于管理的较小单元,方便维护和发现问题。采用具有微服务架构的容器化基础架构被称为采用“云原生”架构。服务在 Borg 部署的容器内运行。此架构会根据需要扩缩工作负载 - 如果对特定工作负载有较高需求,则可能有多台机器运行相同服务的副本以处理所需的工作负载规模。
Google 的与众不同之处在于:在我们架构的每一次演变中,我们都考虑了安全性。最近的云原生安全性概念与 Google 多年来用于保护我们基础架构的概念相当接近。我们采用这种微服务架构和开发过程的目标,是在开发和部署生命周期中尽早解决安全问题(这一阶段解决问题的花费较低),并通过标准化和一致的方式加以解决。最终的结果是,开发者在确保安全性方面花费的时间更少,同时仍能获得更安全的效果。
迁移到云原生架构
现代的安全架构已经超越了基于边界的传统安全模型,传统模型通过防火墙保护边界,而内部的任何用户或服务受到完全的信任。BeyondCorp 旨在顺应现代公司用户的工作方式变化。如今,用户采用移动工作方式,常常会在组织的传统安全边界之外(例如咖啡馆、飞机或者这两者之间的任何地方)工作。在 BeyondCorp 中,我们摈弃了特权公司网络的概念,完全根据设备和用户凭据及特性授予访问权限,而不考虑用户的网络位置。
云原生安全性解决了服务与用户所面临的共同问题 - 在云原生环境中,我们不能单纯依靠防火墙来保护生产网络,正如我们不能依靠防火墙来保护公司网络一样。用户并非总是使用同一物理位置或设备,同样地,开发者并非总会将代码部署到同一环境。借助 BeyondProd,微服务不仅可以在受到防火墙保护的数据中心内运行,还可以在公有云、私有云或第三方托管的服务中运行;在所有地方,它们都必须是安全的。
就像用户会移动、使用不同的设备以及从不同的位置建立连接一样,微服务也会移动并且会跨异构主机部署在不同的环境中。BeyondCorp 认为“用户信任应该取决于设备的上下文感知状态等特征,而不是连接到公司网络的权限”;BeyondProd 认为“服务信任应该取决于代码出处和服务身份等特征,而不是生产网络中的位置(例如 IP 地址或主机名身份)”。
云原生架构和应用开发
较传统的安全模型专注于基于边界的安全性,无法独力保护云原生架构。假设有这样一个示例:采用三层架构的单体式应用部署到私有公司数据中心,该中心有足够的容量来处理重要事件的峰值负载。具有特定硬件或网络要求的应用被特意部署到通常保留固定 IP 地址的特定机器上。更新的发布频率较低、规模较大、难以协调,因为更新所带来的更改会同时影响应用的许多部分。这会导致应用的生命周期极长,而且更新频率较低,其安全补丁程序的应用频率通常也较低。
然而,在云原生模型中,容器会将应用所需的二进制文件与底层主机操作系统分离,使应用更具可移植性。容器是不可改变的,意味着容器在部署后不会更改,因此会频繁重新构建和重新部署。作业将扩缩以处理负载:在负载增加时部署新作业,在负载减少时终止现有作业。由于容器会频繁重启、终止或重新调度,因此硬件和网络会得到更加频繁的重复使用和共享。借助通用的标准化构建和分发流程,团队之间的开发流程更加一致、统一,即使团队独立管理其微服务的开发也是如此。因此,安全性相关事务(例如安全性审核、代码扫描和漏洞管理)可以在开发周期的早期阶段进行。
对安全性的影响
我们已经介绍过很多关于不可信内部(BeyondCorp 中的用户)模型如何应用到 BeyondProd 中的微服务的内容,但这种变化是怎样的呢?表 1 对比了传统基础架构安全性方面与云原生架构中的安全性方面。此表还显示了从一种架构迁移到另一种架构所需要满足的要求。本部分的其余内容详细介绍了此表中的每一行。
传统基础架构安全性 | 云原生安全性 | 针对云原生安全性的隐含要求 |
---|---|---|
基于边界的安全性(例如防火墙),其内部通信被认为是受到信任的。 | 零信任安全性,对服务之间的通信进行验证,环境中的服务没有隐式信任。 | 对边缘网络的保护仍然适用,服务之间没有固有的相互信任。 |
用于特定应用的固定 IP 地址和硬件。 | 更高的资源(包括 IP 地址和硬件)利用率、重复使用率和共享率。 | 运行具有已知出处的代码的受信任机器。 |
基于 IP 地址的身份。 | 基于服务的身份。 | |
服务在已知的预期位置运行。 | 服务可以在环境中的任何位置运行,包括跨公有云和私有数据中心的混合部署。 | |
每个应用都内置了特定于安全性的要求,这些要求会单独强制执行。 | 根据集中式强制执行政策,服务栈中集成了共享的安全性要求。 | 用于跨服务强制执行一致政策的关卡。 |
对有关如何构建和审核服务的限制有限。 | 安全性要求会一致应用到所有服务。 | |
对安全性组件的监督有限。 | 集中查看安全性政策以及遵守政策的情况。 | |
专门发布更新,频率较低。 | 标准化构建和发布过程,可以更频繁地更改个别微服务。 | 简单、自动化、标准化的更改发布。 |
工作负载通常作为虚拟机部署,或者部署到物理主机,并使用物理机器或管理程序进行隔离。 | 封装的工作负载及其进程在共享操作系统中运行,需要一种机制来隔离工作负载。 | 在共享操作系统的工作负载之间进行隔离。 |
表 1:迁移到云原生架构时隐含的安全性要求
从基于边界的安全性到零信任安全性
在传统的安全模型中,组织的应用可能依靠围绕其私有数据中心的外部防火墙来防止传入的流量。在云原生环境中,虽然网络边界仍然需要像 BeyondCorp 模型一样受到保护,但基于边界的安全性模型已不再具有足够的安全性。这不会引入新的安全问题,但会让人注意到一个事实:如果防火墙无法完全保护公司网络,则无法完全保护生产网络。在零信任安全性模型中,您无法再隐式信任内部流量 - 需要其他安全控制措施,例如身份验证和加密。同时,向微服务的转变为人们提供了重新思考传统安全性模型的机会。当您不再依赖单个网络边界(例如防火墙)时,可以按服务进一步细分网络。为了拓展这种想法,您可以实施微服务级细分,使得服务之间没有固有的信任。借助微服务,流量可以具有不同的信任级别和不同的控制措施 - 您不再仅仅比较内部流量与外部流量。
从固定 IP 地址和硬件到更大的共享资源
在传统的安全性模型中,组织的应用部署到特定的机器,并且这些机器的 IP 地址不会经常发生变化。这意味着安全工具可能依赖于以可预测的方式(防火墙等工具中的安全政策可能会使用 IP 地址作为标识符)关联应用的相对静态架构映射。
但是,在云原生世界中,对于共享主机和频繁更改的作业,使用防火墙来控制微服务之间的访问并不可行。您不能依赖特定 IP 地址与特定服务相关联的事实。因此,身份应基于服务,而不应基于 IP 地址或主机名。
从实施特定于应用的安全性到集成在服务栈中的共享安全性要求
在传统的安全性模型中,各个应用分别负责独立于其他服务来满足自己的安全性要求。此类要求包括身份管理、SSL/传输层安全协议 (TLS) 终止和数据访问管理。这通常会导致实施方式不一致或安全性问题得不到解决(因为许多地方都必须解决这些问题),从而使修复措施更加难以应用。
在云原生世界中,服务之间会更加频繁地重复使用组件,并且会有关卡来确保跨服务一致强制执行政策。您可以使用不同的安全性服务来强制执行不同的政策。您可以将各种政策拆分成单独的微服务(例如,一项政策用于确保对用户数据进行授权的访问,另一项政策用于确保使用最新的传输层安全协议 (TLS) 加密套件),而不是要求每个应用单独实施重要的安全性服务。
从专门发布更新且发布频率较低的流程到更加频繁发布更新的标准化流程
在传统的安全性模型中,共享服务很有限。如果代码更加分散并结合本地开发,则意味着很难确定涉及应用的许多部分的更改所造成的影响,因此更新的发布频率较低并且难以协调。为了进行更改,开发者可能必须直接更新每个组件(例如,通过 SSH 连接到虚拟机以更新配置)。总的来说,这会导致应用的生命周期极长。从安全性角度来看,由于代码更加分散,因此审核难度更大,甚至会带来更大的挑战,即:在修复某个漏洞后,确保在所有地方都修复该漏洞。迁移到频繁、标准化发布更新的云原生架构以后,安全性在软件开发生命周期中的位置会提前2。这样可以实现更简单、更一致的安全性强制执行措施,包括定期应用安全补丁程序。
从使用物理机器或管理程序隔离的工作负载到需要更强隔离功能的同一机器上运行的封装式工作负载
在传统的安全性模型中,工作负载被调度到自己的实例上,没有共享资源。应用被机器和网络边界有效隔开,工作负载隔离完全依靠物理主机隔离、管理程序和传统防火墙来强制执行。
在云原生世界中,工作负载装入容器并封装到共享主机和共享资源上。因此,您需要在工作负载之间实现更强的隔离。在使用网络控制和沙盒技术的部分中,工作负载可以分离成彼此隔离的微服务。
安全原则
在开发云原生架构时,我们希望同时加强安全性,因此我们开发并优化了以下安全原则:
在边缘保护网络,以便将工作负载与来自互联网的网络攻击和未经授权的流量隔离开来。虽然基于防火墙的方法不是云原生架构的新概念,但仍然是安全性的最佳做法。在云原生世界中,边界方法用于保护尽可能多的基础架构,使其避开来自互联网的未经授权的流量和潜在的攻击,例如基于卷的拒绝服务攻击。
服务之间没有固有的相互信任,只有已知的、受信任的、明确授权的调用者才能使用服务。这样可以阻止攻击者使用不可信代码访问服务。如果某个服务受到破解,这一原则可阻止攻击者执行扩大其攻击范围的操作。这种“互不信任”的机制有助于限制危害的范围。
运行具有已知出处的代码的受信任机器,以便服务身份只能使用经过授权的代码和配置,并且只能在经过验证的授权环境中运行。
用于跨服务强制执行一致政策的关卡。例如,一个用于验证访问用户数据的请求的关卡,以确保服务的访问来自于获得授权的最终用户发出且经过验证的请求,并且管理员的访问需要提供正当的理由。
简单、自动化、标准化的更改发布,以便相关人员轻松审核基础架构更改对安全性的影响,并且可以在几乎不影响生产环境的情况下发布安全补丁程序。
在共享操作系统的工作负载之间进行隔离,使得某项服务在被破解的情况下也不会影响同一主机上运行的其他工作负载的安全性。这样可以限制潜在的破解“影响范围”。
在我们的整个基础架构中,我们的目标是实现不依赖于个人的自动化安全性。安全性的扩缩方式应该与服务的扩缩方式相同。默认情况下,服务应该是安全的;异常情况下,服务是不安全的 - 人为操作应该只在发生异常情况时进行,而不是作为日常事务,并且这种操作可以审核。然后,我们可以根据为某项服务部署的代码和配置(而不是部署该服务的人员)来对该服务进行身份验证。
总而言之,这些安全原则的实施意味着容器及其内部运行的微服务可以部署、互相通信以及并行运行,而不会削弱云原生架构的属性(即简单的工作负载管理、无运维扩缩和有效的封装)。所有这些都可以实现,而不会在底层基础架构的安全性和实现细节方面给个别微服务开发者带来负担。
Google 的内部安全服务
为了保护 Google 的云原生基础架构,我们设计并开发了多种内部工具和服务。下列安全服务共同致力于实现安全原则部分中定义的各项原则:
Google Front End (GFE):终止与最终用户的连接,并为强制执行传输层安全协议 (TLS) 最佳做法提供一个中心点。即使我们的重点已不再是基于边界的安全性,但 GFE 仍是我们保护内部服务免受拒绝服务攻击的重要策略部分。GFE 是用户连接到 Google 的第一个入口点;在我们的基础架构中,GFE 还负责根据需要在区域之间平衡负载和重新路由流量。在我们的基础架构中,GFE 是将流量路由到适当微服务的边缘代理。
应用层传输安全 (ALTS):用于远程过程调用 (RPC) 身份验证、完整性和加密。ALTS 是一种用于 Google 基础架构服务的相互身份验证和传输加密系统。身份通常绑定到服务,而不是绑定到特定的服务器名称或主机。这有助于实现跨主机的无缝微服务复制、负载平衡和重新调度。
适用于 Borg 的 Binary Authorization 和主机完整性分别用于微服务和机器完整性验证:
- 适用于 Borg 的 Binary Authorization (BAB):一种部署时强制执行检查,用于确保代码在部署之前满足内部的安全性要求。BAB 检查包括由另一位工程师审核更改的内容、将代码提交到我们的源代码库,以及在专用基础架构上以可验证的方式构建二进制文件。在我们的基础架构中,BAB 会限制未经授权的微服务的部署。
- 主机完整性 (HINT):通过安全启动过程验证主机系统软件的完整性,并基于受支持的安全微控制器硬件运行。HINT 检查包括 BIOS、BMC、引导加载程序和操作系统内核上的数字签名验证。
服务访问政策和最终用户上下文标签用于限制对数据的访问:
- 服务访问政策:限制服务之间的数据访问方式。当远程过程调用 (RPC) 从一项服务发送到另一项服务时,服务访问政策会定义访问接收服务数据所需的身份验证、授权和审核政策。这样会限制数据的访问方式、授予所需的最低访问权限级别,以及指定如何审核该访问权限。在 Google 的基础架构中,服务访问政策会限制一项微服务对另一项微服务数据的访问,并允许从全局级别分析访问控制措施。
- 最终用户上下文 (EUC) 标签:这些标签由最终用户身份验证服务发出,并为服务提供用户身份(独立于其服务身份)。这些是受到完整性保护、集中发放、可转发的凭据,用于证明发出服务请求的最终用户的身份。这样可以减少服务之间的信任需求,因为通过 ALTS 的对等方身份通常不足以授予访问权限,此类授权决策通常也基于最终用户的身份。
用于蓝绿部署的 Borg 工具3:此工具负责在执行维护任务时迁移正在运行的工作负载。除了现有的 Borg 作业之外,系统还会部署新的 Borg 作业,负载平衡器会逐渐将流量从一项作业转移到另一项作业。这样,在用户不知不觉中,系统就可以在不停机的情况下更新微服务。此工具用于在我们添加新功能时应用服务升级,以及在不停机的情况下应用重要的安全更新(例如,针对“心脏出血”Bug 和 Spectre/Meltdown 漏洞的安全更新)。对于影响 Google Cloud 基础架构的更改,我们会使用实时迁移来确保虚拟机工作负载不受影响。
gVisor,用于工作负载隔离。gVisor 使用用户空间内核来拦截和处理系统调用,从而减少与主机和潜在攻击面的交互。此内核提供了运行应用所需的大部分功能,并限制应用可访问的主机内核表面。在 Google 的基础架构中,gVisor 是用于隔离同一主机上运行的内部工作负载和 Google Cloud 客户工作负载的几种重要工具之一。
表 2 列出了我们在“安全性原则”部分中介绍的每个原则与我们在 Google 中用来实施该原则的相应工具的对应关系。
安全性原则 | Google 的内部安全工具/服务 |
在边缘保护网络 | Google Front End (GFE),用于管理传输层安全协议 (TLS) 终止和传入流量政策 |
服务之间没有固有的相互信任 | 应用层传输安全 (ALTS),用于远程过程调用 (RPC) 身份验证、完整性、加密和服务身份 |
运行具有已知出处的代码的受信任机器 | 适用于 Borg 的 Binary Authorization (BAB),用于代码出处验证 主机完整性 (HINT),用于机器完整性验证 |
用于跨服务强制执行一致政策的关卡 | 服务访问政策,用于限制服务之间的数据访问方式 最终用户上下文 (EUC) 标签,用于证明原始请求者的身份 |
简单、自动化、标准化的更改发布 | Borg 工具,用于蓝绿部署 |
在共享操作系统的工作负载之间进行隔离 | gVisor,用于工作负载隔离 |
表 2:用于在 Google 实现云原生安全性的原则和安全工具
综合应用
在本部分中,我们将介绍目前讨论过的组件如何在云原生环境中协同处理用户请求。我们将使用两个示例:第一个示例是跟踪从创建到传递至目的地的典型用户数据请求;第二个示例是跟踪从开发到生产的代码更改。此处列出的所有技术不会全部用于 Google 基础架构的所有部分,这取决于服务和工作负载。
访问用户数据
如图 1 所示,当 GFE 收到用户请求时(第 1 步),它会终止传输层安全协议 (TLS) 连接并通过 ALTS4 将请求转发到相应服务的前端(第 2 步)。应用前端使用中央最终用户身份验证 (EUA) 服务对用户的请求进行身份验证,如果成功,则接收短期加密的最终用户上下文 (EUC) 标签(第 3 步)。
图 1:Google 的云原生架构安全控制措施 - 访问用户数据
然后,应用前端通过 ALTS 向存储后端服务发出远程过程调用 (RPC),从而在后端请求中转发 EUC 标签(第 4 步)。后端服务使用服务访问政策,以确保:
- 系统授权前端服务的 ALTS 身份向后端服务发出请求并提供 EUC 标签;
- 前端的身份受到适用于 Borg 的 Binary Authorization (BAB) 的保护;
- EUC 标签有效。
然后,后端服务会检查 EUC 标签中的用户是否有权访问所请求的数据。如果这些检查中的任何检查失败,则请求会被拒绝。在许多情况下,存在一系列后端调用,并且每个中间服务都会对入站远程过程调用 (RPC) 执行服务访问政策检查,而在执行出站远程过程调用 (RPC) 时会转发 EUC 标签。如果这些检查通过,则数据会返回到获得授权的应用前端,并提供给获得授权的用户。
每台机器均具有通过 HINT 系统预配的 ALTS 凭据,并且只有在 HINT 已验证机器启动成功后才能解密。大多数 Google 服务作为微服务在 Borg 上运行,并且这些微服务各自具有自己的 ALTS 身份。Borgmaster5 根据微服务身份将这些 ALTS 微服务凭据授予工作负载,如图 1 所示。机器级 ALTS 凭据构成了预配微服务凭据的安全通道,只有成功通过 HINT 启动时验证的机器才能实际托管微服务工作负载。
更改代码
如图 2 所示,当 Google 员工更改受适当强度 BAB 保护的微服务时,必须将更改的内容提交到我们的中央代码库,该代码库会强制执行代码审核。获得批准后,更改的内容会提交到受信任的中央构建系统,该系统会生成一个包含已签名的可验证构建清单证书的软件包(第 1 步)。在部署时,BAB 会验证来自构建流水线的签名证书,从而验证是否执行了上述流程(第 2 步)。
图 2:Google 的云原生架构安全控制措施 - 更改代码
无论是常规发布还是紧急安全补丁程序,所有工作负载更新都是通过蓝绿部署处理的(第 3 步)。GFE 会将流量负载平衡到新部署,以确保操作的连续性。
所有工作负载都需要隔离。如果工作负载不太可信(例如工作负载是多租户类型,或者源代码来自于 Google 外部),则可能会部署到受 gVisor 保护的环境中,或使用其他隔离层。这种隔离功能可确保在应用的一个实例受到危害时,其他实例均不会受到影响。
应用 BeyondProd
全面实施
通过采用云原生架构并妥善保护该基础架构,Google 可以为其内部和外部 (Google Cloud) 工作负载提供非常强大的安全属性。
通过构建共享组件,个别开发者满足常见安全性要求的负担很轻。理想情况下,安全功能应该几乎不需要集成到各个应用中,而是作为封装和连接所有微服务的结构来提供。这通常称为服务网格。这也意味着可以与常规开发或部署活动分开管理和实施安全性。
更改云原生架构
Google 采用云原生架构时,需要对基础架构和开发过程这两个主要方面进行更改。我们同时完成了这些更改,但它们可以分离并单独完成。
更改我们的基础架构
我们首先构建了服务身份、身份验证和授权的强大基础。有了受信任服务身份作为基础,我们就可以实施更高级别的安全功能(例如服务访问政策和 EUC 标签),这些功能依赖于对这些服务身份进行验证。为了使新服务和现有服务的这种转换变得简单,我们首先提供了 ALTS,作为具有单个帮助程序守护进程的库。此守护进程在每项服务调用的主机上运行,并随着时间的推移逐步演变为使用服务凭据的库。ALTS 库无缝集成到核心远程过程调用 (RPC) 库中,这使得其更容易获得广泛采用,并且不会给个别开发团队带来沉重的负担。发布 ALTS 是发布服务访问政策和 EUC 标签的前提条件。
更改我们的开发流程
建立强大的构建和代码审核流程对 Google 来说至关重要。这样可以让我们确保正在运行的服务的完整性,并且确保 ALTS 所使用的身份有意义。我们建立了一个集中式构建流程,在该流程中,我们能够开始强制执行一些要求,例如要求在构建和部署时有两个人参与代码审核和自动化测试。(如需详细了解部署,请参阅适用于 Borg 的 Binary Authorization。)
完成这些基础工作以后,我们就开始着手满足在我们的环境中运行不受信任的外部代码的需要。为了实现此目标,我们开始进行沙盒测试 - 最初使用 ptrace,后来使用 gVisor。同样地,蓝绿部署在安全性(例如修补)和可靠性方面提供了明显的优势。
我们很快发现,如果服务从一开始就记录违反政策的行为(而不是阻止违反政策的行为),则我们的目标更容易实现。这一方法具有双重优势。首先,它让服务所有者有机会测试更改的内容并评估迁移到云原生环境对其服务产生的影响(若有)。其次,它使我们能够修复任何 Bug,并确定我们可能需要向服务团队提供的其他任何功能。例如,服务登录到 BAB 时,服务所有者会启用“仅限审核”模式。这有助于他们识别不满足要求的代码或工作流。解决了“仅限审核”模式所标记的问题后,服务所有者会启用强制执行模式。在 gVisor 中,我们首先将工作负载布置在沙盒中(即使沙盒功能存在兼容性问题),然后系统地解决这些兼容性问题以改善沙盒,从而达到我们的目的。
进行这一更改的好处
正如 BeyondCorp 帮助我们超越了基于边界的安全模型一样,BeyondProd 在生产环境安全性方面实现了类似的飞跃。BeyondProd 方法描述了一种云原生安全架构,该架构假定服务之间没有信任、隔离工作负载、验证是否仅部署了集中构建的应用、自动执行漏洞管理以及对重要数据强制执行有力的访问权限控制。基于 BeyondProd 架构,Google 开发了多个新的系统,以满足这些要求。
太多的时候,当迁移到新架构的决定已经作出之后,安全性才会最后进入工作日程。通过让您的安全团队尽早参与以及专注于新安全模型的优势(例如更简单的补丁程序管理和更严格的访问权限控制),云原生架构可为应用开发和安全团队带来明显的优势。如果将本文中介绍的安全原则应用到您的云原生基础架构,则可以加强您的工作负载的部署、保护您的工作负载通信的方式以及您的工作负载对其他工作负载的影响。
备注
1 Borg 是 Google 的集群管理系统,用于大规模调度和运行工作负载。Borg 是 Google 的首个统一容器管理系统,也是 Kubernetes 的灵感来源。
2“提前”指的是在软件开发生命周期中提前执行相关步骤,其中可能包括编写代码、构建、测试、验证、部署等步骤。生命周期图表通常从左向右绘制,因此,左侧表示较早的步骤。
3 蓝绿部署是一种在不影响传入流量的情况下发布工作负载更改内容的方法,以便最终用户在访问应用时不会遭遇停机。
4 如需更好地了解流量如何在 Google 的基础架构内部从 GFE 路由到服务,请参阅《传输加密》白皮书中的流量路由方式部分。