这是本系列博客的第3篇,系列内容涵盖我们构建和运营SaaS服务所涉及的各个方面:
- 分布式 Kubernetes PaaS 的控制平面
- 面向分布式应用的全局服务网格
- 面向分布式基础设施、应用和数据的平台安全
- 分布式集群的应用和网络安全
- 覆盖全球分布式平台的可观测性
- 全球分布式平台的运维与SRE
- 面向分布式微服务的Golang服务框架
我最初的博客介绍了促使我们为分布式云构建新平台的需求背景。客户使用该平台构建各种复杂的应用,例如智能制造、用于公共安全的视频取证、算法交易和电信运营商5G网络。
由于其中许多应用都至关重要,客户希望我们不仅能提供多层安全防护,还能持续改进,以保障其分布式集群的安全。本篇博客将探讨如何应对跨多个集群保护基础设施、应用和数据所面临的挑战。
太长不看(摘要)
- 如何让用户和员工安全访问应用,已经有相对成熟的做法(我们每天访问银行账户或公司电子邮件时都会用到)。但对于应用间或应用到数据的访问,由于验证过程没有人工参与,要实现同样的安全访问并非如此简单。
- 要保护异构环境(边缘、多个云和网络PoP)中的应用和数据,需要解决一个多层次问题:身份、身份验证与授权、机密信息和密钥管理
- 尽管针对这四个问题已有许多单点解决方案(例如,各云提供商提供的多项服务、Hashicorp Vault、SPIFFE/Spire等),但目前尚无可跨云提供商运行,或能无缝整合这些服务以便于使用的集成式解决方案。
- 由于我们的开发和DevOps团队缺乏整合这些组件所需的专业知识,平台团队必须以易用的集成解决方案形式提供这些功能。不断变化的安全形势和新技术进一步增加了这些团队的难度,因为他们既缺乏必要的专业知识,也没有足够的精力跟进所有变化。
- 在提供多层平台安全防护的过程中,我们构建了新的软件组件,以全新方式解决了三个关键问题:安全引导通用身份,避免“层层追溯、永无根基”的问题;存储和分发机密信息,无需担心中央保管库遭入侵(“金矿”问题);以及通过分布式密钥管理,简化静态数据的安全保护。
安全问题背景
如上所述,如何保护用户对应用的访问(例如访问银行账户或电子邮件)已得到充分理解。然而,由于验证过程没有人工参与,要以同样的方式保护应用间或应用对数据的访问并非易事。
要让应用安全地访问其他资源,例如访问对象存储中的数据或调用其他应用的API,需要完成以下操作:
- 身份:请求方需要安全地获取可验证的身份,以便在访问所需资源时用于身份验证和授权。还需要为请求方安全地配置必要的信任锚,以验证对等方的身份。
- 身份验证:在访问指定资源的过程中,请求方和资源所有者需要安全地验证彼此的身份。根据对等方出示的身份来验证其所声明身份的过程称为身份验证。
- 授权:请求者通过身份验证后,检查其是否获准访问资源的过程称为授权。
在身份验证过程中,发出请求的应用程序可以使用PKI证书、机密信息(例如密码)或密钥来表明其身份。使用机密信息或密钥来表明身份时,需要解决两个问题:
- 不应将密钥和机密信息直接存储在代码中,因为这很容易成为攻击途径,而密钥泄露可能会造成严重问题。
- 如果将密钥存储在外部保管库中,应使用什么身份(通常是另一个密钥)来获取密钥?又该如何保护此身份,以便安全地获取密钥?
以可靠且可重复的方式执行这些安全操作(用于应用间交互)并非易事,原因有很多:
- 应用程序可以轻松克隆并生成新实例(例如微服务)。如何为每个克隆实例分配唯一身份,以满足取证、审计或可观测性方面的需求?
- 应用身份会因其运行环境而异。例如,同一应用在开发环境和生产环境中需要使用不同的身份。
- 如何建立信任,确保用于生成应用的基础设施不会在未被察觉的情况下窃取身份信息、机密信息和密钥?
- 如何保护中央保管库免受攻击,并确保其中存储的所有机密和密钥安全?
因此,在动态环境中保护基础设施、应用和数据是一项极具挑战性的任务。尽管云服务提供商已积极应对这一挑战,并提供了大量工具来解决这些问题,但由于以下原因,集成和维护这些工具并非易事:
- 复杂性:每家云提供商都要求客户配置和管理多项服务。例如,在AWS中,这些服务包括元数据服务、IAM角色、服务账户、RBAC、KMS和Secrets Manager。不同云提供商的这些服务在语义、API和监控方面存在很大差异。
- 互操作性:即使云提供商的服务已完成配置并投入运行,这些服务也都无法实现互操作。例如,在GCP中运行的虚拟机无法访问AWS中的资源,因为AWS资源无法识别使用GCP服务账号分配的身份。
- 异构环境:如果环境分布在公有云和私有云、多个公有云,甚至更棘手的边缘位置,就需要考虑如何以及在何处存储密码、密钥等机密信息,是集中存储还是分布式存储。
- 特定于环境:各云提供商采用的凭据轮换和/或撤销解决方案差异很大,而边缘集群尚无此类解决方案。
许多企业仅使用一家云服务提供商,因此投入资源来管理和增强该提供商的基础安全机制或许已足够。但我们在异构环境(混合云和边缘)中运营,必须构建新的解决方案来解决这些问题。
分布式平台安全解决方案
我们的团队负责为可能分布在图1所示分布式基础设施中的应用、基础设施和数据提供安全保障。

因此,我们的平台团队决定构建新的软件服务,整合以下四个方面,为边缘、任意云环境和我们的网络PoP提供平台安全保障:
- 身份管理:我们将介绍如何为应用和基础设施提供基于PKI、采用加密技术保护且不可伪造的身份。相关基础设施分布在异构环境中(包括多个云、我们的全球PoP以及分布于不同地理位置的边缘站点),并在多种环境中运行(例如开发人员计算机、单元测试环境和生产环境等)。
- 身份验证和授权:我们的基础设施基于微服务构建。这些微服务使用基于PKI的身份,并对所有通信进行双向身份验证,无论采用何种通信协议。我们还将授权与身份验证解耦,以便使用通用授权引擎处理各种授权决策,并统一策略结构。
- 密钥管理系统:我们的软件和客户工作负载需要多种类型的密钥(如TLS证书、密码、令牌等)。最简单的方法或许是采用集中式保管库来存储所有密钥,但这种方法的缺点是,一旦保管库遭到入侵,所有密钥都会泄露。我们将介绍一种已经实施的不同方法,通过牺牲一定的简便性来提高安全性。
- 密钥管理系统(KMS),数据安全对我们的分布式系统至关重要,因此团队必须交付一个可跨云提供商无缝运行的KMS。KMS必须对密钥进行管理、版本控制和轮换,这些密钥用于静态数据的对称加密和解密、CSRF令牌的HMAC,以及对二进制文件进行数字签名。我们将探讨如何使用此KMS为安全敏感型操作提供支持,并使用机密管理系统为延迟敏感型操作提供支持。
基础设施和应用的不可伪造身份
身份是一个根本性问题,因为解决身份问题后,许多安全挑战都能更轻松地应对。然而,要解决身份问题,我们需要明确身份的含义,以及如何以可靠的方式签发身份。密码学极客喜欢对一切提出自己的独到见解,身份的定义也不例外:
由可信机构通过不可委托的安全协议进行加密认证,且共同构成个人或事物已知或被认定身份的独特、完整的不可伪造且可通过密码学验证的特征集合。
本质上,需要以安全方式交付不可伪造且可通过密码学验证的身份。签发此类身份面临两项挑战:1)身份引导;2)信任根
在身份领域,经常讨论的方案包括SPIFFE和Hashicorp Vault。需要说明的是,SPIFFE是一种命名方案,可在我们的系统中用作身份文档(X.509证书);但这种格式不适用于某些包含二进制数据的身份属性。虽然Vault可用于签发身份文档,但无法解决身份引导和信任根方面的难题:
- 身份引导:在现实生活中,一个人出生时,其身份由出生证明确定。从逻辑上讲,这一过程完成了个人身份的引导。凭借该证明,可以进一步获取或申请护照、驾驶证等更多身份证明。同样,在计算领域,每次启动应用程序(或微服务)时,都需要引导建立身份。为了能够与其他服务交互,建立身份是任何运行中代码首先需要执行的步骤之一。此外,由于同一应用程序代码可能会多次启动,并在不同环境中运行(开发人员笔记本电脑、单元测试环境或生产环境),因此每次启动还需要分别建立独立的引导身份。
- 信任根:虽然签发引导身份看似简单,但问题在于由谁来配置该身份。例如,在现实世界中,身份配置始于医院确认某个孩子在特定日期和时间由特定人员所生,并假定医院在经过适当核验后签发出生记录,且该记录无法伪造。因此,出生记录可用作事实依据(或信任根)。同样,当应用程序由人工或自动化代码启动时,需要有一个信任根,以可验证的方式确认所启动应用程序的身份。随后,可依据此确认信息为应用程序生成身份文档。
例如,在AWS中启动VM时,系统会为其提供引导身份,并由AWS元数据服务充当信任根。该身份证明文档(由AWS使用其自有加密密钥签名)大致如下:

虽然instanceId可表示已启动应用实例的唯一身份,但还需将其关联到一个其他应用用于与该实例通信的已知名称(myserver.acmecorp.com)。因此,即使是这份AWS引导身份文档也不够充分,但可用于签发另一个身份,供应用之间相互通信。
如前所述,我们必须提供一种身份,使应用能够跨云提供商和/或边缘位置进行通信和共享信息(图 2)。这意味着,我们必须构建一个适用于所有这些环境的系统,同时支持身份引导和信任根。

由于我们使用Kubernetes管理和编排应用(包括微服务和虚拟机),因此必须将为每个已启动Pod引导建立唯一身份的过程接入Kubernetes的Pod创建流程。图3展示了如何使用K8s webhook机制接入Pod创建流程。这个名为Voucher的webhook会将一个名为Wingman的安全边车注入集群中创建的所有Pod,并提供必要的加密签名信息,用作信任根。该webhook会提供一个短期有效的签名令牌,Wingman使用此令牌向Volterra SaaS后端的Identity Authority申请X.509证书。
Identity Authority通过强制执行身份签发规则,尽可能缩小某个K8s集群遭入侵时的“爆炸半径”。许多依赖通用根CA或K8s集群联合的其他解决方案无法限制爆炸半径,这是我们做出设计决策时考虑的一个主要因素。

对于K8s中的特定Pod,其属性在创建后可能发生变化。例如,Pod创建后可以关联到新服务。这意味着必须更新身份证书,以纳入新服务。Wingman会持续监视用于跟踪K8s API服务器的Voucher,以发现此类更新。
此机制为平台上运行的每个应用实例提供唯一且通用的全局身份,无论该实例属于我们的工作负载还是客户工作负载。随后,系统使用这一唯一身份和边车(Wingman)来保护分布式系统中的所有通信、访问以及密钥和机密信息。
身份验证和授权
为每个Pod分配唯一身份是一个良好的开端,因为这有助于简化通信服务之间相互身份验证的实施。我们的底层基础设施由许多不同的服务组成,这些服务使用gRPC、REST、IPSec和BGP等不同协议运行。团队从一开始就设定了目标:无论使用何种协议,都要为所有通信方实现相互身份验证和通信安全(加密通道)。这也意味着,我们不能将身份绑定到仅支持特定协议集(例如HTTP/TCP协议与基于IP的协议)的解决方案(例如Istio)。
由于我们的平台还允许客户运行自行选择的工作负载,因此这些工作负载可能会使用多种协议。平台不应提供仅限于特定协议集的身份,从而限制工作负载的能力。相反,身份验证通过Wingman与身份解耦,因此可以接入各种服务网格技术。我们的服务网格边车和数据平面(已在之前的博客中介绍)使用此身份为客户工作负载提供mTLS。
由于我们自己的许多基础设施服务都是使用Volterra Golang Service Framework编写的(将在后续博客中介绍),因此我们决定将使用Wingman所提供身份的逻辑直接内置到该框架中。这有助于开发人员无需依赖服务网格边车,即可直接使用mTLS保护服务间通信。
建立双向身份验证的安全通道后,下一步自然是进行授权,即由请求接收方(服务器)确定是否允许来自已识别调用方(客户端)的请求。拒绝请求的原因可能有很多,例如配额限制、权限等。由于这些原因及其阈值会动态变化,因此,我们的平台从一开始就不适合采用一套硬编码规则(策略)来进行授权。
我们决定以Open Policy Agent的引擎为起点,在Wingman边车中构建一个授权封装层。该封装代码会动态获取相关策略,并将其保持在就绪状态,以便快速评估。与身份验证类似,将授权引擎与身份(及身份验证)解耦后,我们可以在请求处理的多个阶段实施授权策略,包括深入业务逻辑的环节,而不只是在身份验证后立即实施。
由于Wingman已嵌入所有工作负载(包括客户的工作负载),因此我们的平台将授权引擎作为内置功能提供。尽管Open Policy Agent(OPA)基于一种名为Rego的强大语言构建,但我们希望对开发人员和客户隐藏其复杂性。平台上的所有策略也可以使用一种更易于理解且直观的策略结构来定义,用户(DevOps)无需学习Rego,从而避免出错。与身份验证配置类似,我们的Golang Service Framework通过自动调用Wingman执行授权,与Wingman的授权引擎集成,从而对开发人员隐藏授权的复杂性。
通过使用唯一身份(由Wingman颁发)进行身份验证,并使用可编程策略引擎(位于Wingman中)进行授权,我们能够利用mTLS保护通信,并通过稳健且可编程的策略控制每次访问。
无需集中式保管库的密钥管理
工程师每天都可能无意中将密钥和密码存储在代码中,导致这些敏感信息以某种方式进入公共代码或制品存储库。机密管理并不容易;如果缺少易用的工具包和明确的流程,开发人员往往会选择最省事的做法。因此,公司自成立之初,平台安全团队(不同于网络安全和应用安全团队)的使命就是确保开发人员不必再问:“机密应该存在哪里,是源代码、制品,还是其他地方?”
在开始构建平台时,我们评估了当时可用于密钥管理的两种常见方法,但这两种方法都存在一些不足:
- Kubernetes Secrets:虽然我们使用Kubernetes,且Kubernetes自带密钥解决方案,但由于多种原因,该方案的实用性有限:密钥未进行静态加密,策略机制不够全面,也无法解决多集群场景中的问题。
- 集中式Vault(例如Hashicorp或Cyberark Vault);另一种方法是使用Vault集中存储密钥,并将其提供给获得授权的请求方。密钥由一个加密密钥保护,该加密密钥用于对Vault进行加密存储。但这种方法的问题在于,密钥管理系统可以访问明文密钥(即使这些密钥以加密形式存储),一旦系统遭到入侵,所有密钥都可能泄露。
对于我们的SaaS服务,需要采用更稳健的方法来保护客户的机密,确保即使系统遭到入侵,也不会泄露这些机密。
因此,我们决定实施一项名为 Volterra Blindfold(商标)的新技术。该技术与安全边车 Wingman 协同工作,如图 4 所示。通过这种方法,秘密的所有者可以锁定(加密)秘密,使任何非预期方(包括解密服务器)都无法看到明文形式的秘密。秘密甚至不会存储在中央解密服务器中;从某些方面来看,这种设计大幅简化了服务器设计。

我们为用户提供了一个blindfold工具,可在完全离线的环境中加密机密(S),之后即可分发该机密。例如,可将机密与工作负载存储在一起,并上传到注册表。完成后,需要执行以下步骤:

这可确保集中式控制平面始终无法访问明文形式的机密(S),并且该机密仅在访问期间存在于Pod的运行时内存中。此外,还可应用访问策略来定义谁有权访问机密。策略可根据应用程序名称、位置、合规级别等身份属性进行定义。这样便可划分出任意复杂的工作负载子集,实现精细的访问控制。该策略通过加密机制融入加密、盲化、解密和去盲化流程,从计算角度看,规避该策略意图并不可行。
我们采用独特的Blindfold技术锁定每个密钥,并由Wingman根据策略和不可伪造的身份解封密钥,从而解决现有解决方案存在的问题,在分布式环境中实现密钥管理,无需担心集中存储的高价值密钥遭到泄露。
分布式系统的密钥管理
虽然机密信息管理和密钥管理听起来像是同一问题的两种不同说法,但两者之间存在细微差异(在实践中却很重要),具体取决于所咨询的对象以及解决方案的实施方式。
秘密是指应当保密且未经授权方无法获取的任何信息。从某种意义上说,密码密钥是秘密的一种特定形式。另一方面,密钥管理通常是指安全存储敏感密码密钥材料并控制其使用的系统。在某些情况下,密钥管理系统可能会向授权方提供密钥的原始字节,因此容易与秘密管理系统混淆。但在大多数情况下,密钥管理系统并不会实际提供密钥材料的原始字节,而是为获得授权的请求方执行操作,并且仅返回操作结果。许多密钥管理系统还使用硬件(例如硬件安全模块HSM)存储密钥材料,确保密钥绝不会以明文形式暴露给软件。
在分布式环境中,即使只使用一家云服务提供商,管理、同步和轮换加密密钥也极具挑战性。现有解决方案容易出错、效率低下,甚至存在安全隐患。例如,如果目前使用3个AWS区域,并希望在所有3个区域中使用同一加密密钥,就必须手动同步和轮换密钥。当环境横跨多个云服务提供商(公有云和/或私有云)时,问题会更加严重。即使完成上述所有工作,应用所有者仍需编写复杂的代码才能使用这些KMS功能。
我们的平台让Wingman sidecar承担所有繁重工作,并为应用提供简单的接口,用于发起加密、解密、HMAC、HMAC验证、数字签名、签名验证、获取密钥(如允许)等密钥管理请求,从而对应用隐藏密钥管理的全部复杂性。这让我们的基础设施服务和客户工作负载都能轻松管理密钥。
下图(图 5)展示了Volterra的KMS如何跨环境运行,并帮助工作负载将密钥管理和加密操作卸载到Wingman边车。根据配置,Wingman可以缓存密钥并刷新缓存,而应用程序对此毫无感知。实现这一点的关键在于前文介绍的通用且不可伪造的身份。无论位于何处,每个Pod都会获得全局唯一身份,因此Volterra KMS系统可以非常精准地对加密密钥以及加密、解密、HMAC、HMAC验证、数字签名和签名验证等特定操作应用访问策略。

由于所有密钥均通过Volterra的SaaS后端进行管理,在异构环境中运行的工作负载无需处理密钥同步、轮换、吊销等事务,只需了解简单的Wingman API,即可满足所有静态数据安全需求。
平台安全解决方案带来的收益
通过采用多层平台安全机制,我们得以用全新的方式为三个关键问题提供全面的解决方案。我们的系统能够安全地引导建立通用身份,避免陷入“无限递归”问题;管理可安全存储和分发的机密,无需担心“金矿”问题;并提供密钥管理,简化分布式环境中的静态数据保护。这为我们的内部团队和客户带来了以下收益:
- 安全与合规:不可伪造的通用身份、Blindfold,以及由平台完全集成并自动管理的安全边车(Wingman),可保护所有通信、授权每次访问,并管理分布式系统中的密钥和机密。借助这些技术进展,我们能够提供更稳健的安全解决方案,帮助我们和客户更轻松地满足合规要求。
- 生产力提升:通过使用集成到DevOps流程和服务框架中的安全解决方案,开发人员和DevOps团队可以专注于交付成果,无需担忧应用和数据安全的关键问题。
- 持续演进:不断变化的安全形势和新技术推动Blindfold、Wingman及我们的Golang Service Framework持续演进。因此,无需更改应用逻辑,平台即可自动推出新功能。
未完待续……
本系列博客将介绍我们如何构建和运营全球分布式SaaS服务,涵盖公有云中的众多应用集群、专用网络PoP和边缘站点等多个方面。下一篇将介绍应用和网络安全……
我们正在招募几位志愿开发者和解决方案架构师,帮助我们将这项能力作为开源项目推广到更广泛的社区。如有兴趣参与这项有趣的工作,请直接联系asingla@volterra.io。
相关博客文章
Thingbot正转变为攻击平台
Lori MacVittie重点介绍了F5 Labs对2018年1月至6月全球物联网设备攻击的研究,并指出了其中令人警醒的影响。物联网设备不仅持续遭到利用,还被转变为攻击平台,这意味着攻击者可以更充分地利用这个必然增长的市场。
借助F5全新Quick Start,在AWS上快速开展业务
在AWS re:Invent开幕前,我们很高兴与大家分享F5与AWS之间全新的Quick Start集成。F5的Tom Atkins将介绍该服务如何启动、配置和运行在AWS上部署工作负载所需的计算、网络、存储及其他AWS服务。