跳到内容

Knative 威胁模型

Knative 通过为用户提供面向开发者的无服务器抽象来扩展 Kubernetes。因此,Knative 威胁模型需要保护 Knative 特定的服务以及底层的 Kubernetes 基础设施。

Knative 旨在支持来自单个组织的应用团队在共享集群的资源内工作。这些团队共享由 Knative 管理的控制平面、集群和节点资源,以及由 Kubernetes 管理的控制平面、集群和节点资源。这被称为 服务即命名空间 (Namespace-as-a-Service) 的多租户模型。每个团队 (命名空间中的用户) 都应与其他在不同命名空间中运行的团队的故意或无意的违规行为隔离开来并受到保护,同时还要免受集群外部的任何第三方的侵害。Knative 用户以及同一集群中其他 Kubernetes 资源的用户不应能够影响其控制范围之外的命名空间中应用程序的配置、可用性或完整性,包括获取或删除来自另一个命名空间的私有信息。

Knative 构建在 Kubernetes 集群的功能之上,并暴露了 Kubernetes 控制平面资源 (由 Kubernetes RBAC 管理的 CRD) 以及集群本身的数据平面网络和计算资源。在许多情况下,Knative 依赖内置的 Kubernetes 功能来缓解这些威胁;因此,假定遵循 Kubernetes 安全实践 是基础。此外,Knative 为核心路由组件 (如 HTTP 代理,例如 Istio、Contour 和 Gateway API 实现) 或事件传输 (例如 Kafka、RabbitMQ、NATS) 提供了可插拔的底层架构;还必须使用最佳实践来保护所选的路由组件,并且 **可能** 使用路由级别保护来保护 Knative 用户工作负载。在需要额外小心保护安全工作负载的情况下 (例如,Knative Serving 路由和 Kubernetes NetworkPolicy),将会特别指出。

术语

  • 应用程序:在一组 Knative 资源 (Serving 和 Eventing 资源定义) 在命名空间中部署,以实现用户期望的功能。一个应用程序可能由 Knative 和非 Knative 资源的混合组成 (例如,一个 Knative Service 和一个由单独的 Operator 部署为 StatefulSet 的数据库,或一个将事件传递给非 Knative Deployment 的 Eventing Broker)。
  • 用户:管理 Kubernetes 命名空间中应用程序配置和部署的个人或进程。
  • 管理员:负责配置平台级服务的个人或团队,例如 Knative、Kubernetes 或外部服务 (如 GitHub)。

威胁参与者

参与者 描述
外部攻击者 未经验证的攻击者,无权访问 Kubernetes 控制平面,只能访问集群的 **公共** 网络资源。
恶意或受损的开发人员 (内部用户) 经过身份验证的用户,能够在特定命名空间中创建 Pod 和其他资源 (大致相当于 Kubernetes 的 `edit` 权限),但没有集群级别的访问权限。请注意,“恶意或受损的开发人员”也可能包括意外操作,例如执行针对用户无权访问的命名空间的删除命令。
外部事件源管理员 能够配置和管理用作事件源的外部资源的用户的身份,但没有直接访问集群的经过身份验证的权限。
恶意容器 / 供应链攻击 能够篡改内部用户运行的容器映像的用户,但没有访问集群的经过身份验证的权限。

组件架构

通用

控制平面

Knative 运行多个 控制器 来管理 Knative 自定义资源。其中一些控制器提供其他软件的运行指令 (例如,配置消息队列),而其他控制器则直接在系统或用户命名空间中创建资源,例如 Kubernetes Deployment、Pod 或 Service。其预期目的为在集群内的系统或用户选择的命名空间中部署用户控制或配置的 Pod 的控制器 (例如,Knative Revision 或 Job 事件接收器) 将必然拥有允许攻击者跨越命名空间边界并可能破坏系统组件的权限。这些控制器必须设计为避免允许用户在用户命名空间之外创建用户控制的 Pod 的操作。

Webhooks

对于多个自定义资源,Knative 实现了 验证和修改 Admission Control Webhook。这些 Webhook 允许 Knative 防止创建无效资源,并向用户提供关于无效资源性质的即时反馈。虽然验证和修改 Webhook 提供了比延迟报告用户错误更好的用户体验,但它们能够阻止或更改对 Kubernetes API 服务器的请求,这可能使它们能够影响所有命名空间中的资源。例如,拥有 ConfigMap Admission Webhook 控制权的攻击者可以在每次存储 Webhook 时添加或删除配置子句。

Eventing

事件源 (Event Source)

事件源通常由一个控制器和一个或多个数据平面 Pod 组成,这些 Pod 通过推送或拉取模型从集群外部收集事件。数据平面 Pod 可能为多个命名空间实现事件传递,此时它们部署在事件源的系统命名空间中;或者,数据平面 Pod 可以按命名空间部署,成本更高,但隔离要求较低 (因为它们可以被视为用户控制的容器)。

路由器接收器 (Router Sinks)

Knative 事件路由构造 (Broker 和 Channel) 通常包含两个组件:一个 *sink*,它接收应该存储为底层传输中的消息,然后再路由到目标的消息;以及一个 *sender*,它从底层传输中消耗消息并将其发送到配置的目标。大致上,Broker 和 Channel 对象代表 sink 实现,而 Trigger 和 Subscription 代表 sender 实现。

与事件源一样,路由组件可以实现为多租户 (共享) 数据平面或独占 (每个命名空间) 进程;大多数现有的 Knative 路由实现出于效率原因而采用共享数据平面模型。在这两种情况下,用于配置数据平面资源的 Kubernetes 控制器都是一个共享的多租户组件。

路由器触发器 (Router Triggers)

有关 Knative 中发送者和接收者之间职责分配的信息,请参阅 路由器接收器。触发器 (和订阅) 代表 Knative 事件路由的发送端 — 它们以至少一次传递语义将一系列 CloudEvents 传递到 HTTP 目标。请注意,事件传递的至少一次语义意味着在某些情况下重复传递 (重放) 是预期行为,不一定是安全问题。

Serving

入口网关 (Ingress Gateway)

Knative Serving 需要一个入口网关来执行 HTTP 路由和其他功能,如 TLS 终止和流量分割,但它将入口网关的实现委托给外部软件,如 Istio、Contour 或 Gateway API 实现。因此,入口网关的具体安全行为是底层网关实现和 Knative 控制器向底层软件提供的配置的组合。入口网关实现通常是多租户的,并在整个集群中共享,尽管 Knative 架构不强制要求这样做。

激活器

Activator 组件是 Knative 使用的共享 (多租户) 数据平面组件,用于处理没有当前可用用户 Pod 来处理请求的情况。Activator 与 Autoscaler 协同工作,根据入口网关做出的流量路由决策来管理特定 Revision 的 Pod 数量。并非所有传入的请求都由 Activator 处理 — 当特定 Revision 拥有足够多的副本来处理突发流量时,入口网关将使用应用程序 Pod 的直接后端地址进行编程。

自动扩缩器

Autoscaler 是一个控制平面组件,它跟踪每个 Knative Revision 的当前请求数量和每秒请求数,并根据观察到的流量调整所需的 Pod 数量。与 Activator 一样,Autoscaler 是一项共享 (多租户) 服务。Autoscaler 从 Activator 和 Queue Proxy 收集流量测量数据,计算每个 Revision 所需的 Pod 数量,然后更新 Kubernetes API 服务器上所需的 Deployment 副本数量。

队列代理

Queue Proxy 作为 Sidecar 与每个用户容器 (在同一个 Pod 中) 一起运行。Queue Proxy 负责测量特定 Pod 上的请求负载,强制执行请求超时和优雅 Pod 关闭,以及管理到应用程序的请求并发 (如果需要)。Queue Proxy 只能接收来自入口网关或 Queue Proxy 的请求,并与用户容器在相同的安全域 (命名空间) 中运行。

攻击目标

一般来说,攻击者的目标是破坏其未控制的应用程序所管理数据的可用性、完整性或保密性。(破坏攻击者控制的应用程序的这些保证要容易得多,因为攻击者可以直接访问应用程序的配置,并可以运行任意代码并访问应用程序可以访问的所有资源)。

由于并非所有组件都参与处理请求,我们在每种情况下都声明了哪些 Knative 组件可能成为攻击者的目标以实现这些目标。有关已实施的防御措施和其他可以考虑的特定于集群的配置,请参阅 缓解措施

拦截或阻止对应用程序的请求

在此场景中,攻击者能够阻止或修改发送到应用程序的请求负载,无论是它们在进入集群之前,还是在 Knative 处理期间在到达应用程序之前。目标组件

组件:源 (sources)、Broker 接收器 (broker sinks)、触发器 (triggers)、网关 (gateways)、Activator (activator)、Queue Proxy (queue-proxy)

攻击者:外部 (external)、开发人员 (developer)、事件源 (event source)

绕过访问控制以伪造对应用程序的请求

在此场景中,攻击者能够向应用程序传递一个请求负载,导致应用程序执行非期望的行为。例如,一个请求删除应用程序数据,或者记录一个未经授权的事件 (如金融交易)。

组件:控制器 (controllers)、Webhook (webhooks)、源 (sources)、Broker 接收器 (broker sinks)、触发器 (triggers)、网关 (gateways)、Activator (activator)

攻击者:外部 (external)、开发人员 (developer)、事件源 (event source)

阻止应用程序执行

在此场景中,攻击者阻止应用程序的 **所有** 执行 — 与“阻止请求”场景不同,攻击者可能能够选择性地阻止请求,而此攻击阻止应用程序的所有执行。这包括基于数量的资源耗尽或拒绝服务攻击,以及逻辑攻击,如阻止访问容器注册表。

组件:控制器 (controllers)、Webhook (webhooks)、Broker 接收器 (broker sinks)、触发器 (triggers)、网关 (gateways)、Activator (activator)、Autoscaler (autoscaler)

攻击者:外部 (external)、开发人员 (developer)、事件源 (event source)

在不同的用户命名空间中实现代码执行

在攻击者未经授权的命名空间中执行应用程序代码的能力,有潜力破坏应用程序的保密性和完整性 (例如,在“可乐”命名空间中运行代码,而未经身份验证或以“百事可乐”用户身份进行身份验证)。此攻击目标不包括应用程序级别的漏洞,如 SQL 注入或应用程序在收到无效请求时的错误行为,这些都由应用程序作者负责。通过 Knative 表面积进行的有效攻击的一个例子是使用共享节点网络触发 Queue Proxy 容器中的代码执行。

组件:控制器 (controllers)、Webhook (webhooks)、事件源 (event sources)、Broker 接收器 (broker sinks)、触发器 (triggers)、Queue Proxy (queue-proxy)

攻击者:外部 (external)、开发人员 (developer)、事件源 (event source)、供应链 (supply chain)

在系统命名空间中实现代码执行

系统命名空间是指实现集群底层多租户服务的命名空间。这包括与 Kubernetes API 服务器交互的控制器,以及在共享命名空间中运行的 Activator 或 Broker 接收器等数据平面路由元素。在这些命名空间中实现代码执行很可能会使攻击者能够执行许多先前的攻击,因为系统命名空间通常被认为是其安全功能实现中受信任的。

组件:控制器 (controllers)、Webhook (webhooks)、事件源 (event sources)、Broker 接收器 (broker sinks)、触发器 (triggers)、网关 (gateways)、Activator (activator)、Autoscaler (autoscaler)

攻击者:外部 (external)、开发人员 (developer)、事件源 (event source)、供应链 (supply chain)

安全边界

Knative 依赖底层集群安全 (控制平面、容器和网络隔离) 来实现许多应用程序安全功能。特别地,假定用户命名空间配置为使用 Kubernetes 安全机制阻止从应用程序容器升级到节点级软件 (kubelet、Linux 主机等)。同样,Kubernetes 命名空间之间的网络隔离通常应尽可能使用 NetworkPolicy 来限制一个应用程序与属于另一个应用程序的后端服务通信的能力。此外,假定 Kubernetes 身份验证和 RBAC 已正确配置,以阻止普通用户或服务帐户的跨命名空间或集群范围的资源请求。

网络隔离和 L7 路由

许多 Knative 服务使用共享基础设施上的 HTTP 路由来实现。在某些情况下 (例如,入口网关中的内部服务地址,或某些 Broker 接收器),使用 HTTP 主机名路由使得应用 Kubernetes NetworkPolicy (TCP/L4) 原语来限制应用程序命名空间之间的流量变得困难。Knative 推荐使用一种或多种以下技术来限制跨命名空间访问:

  • Knative Eventing EventPolicy 结合 Sender Identity
  • 使用服务网格,如 Istio。这可能需要 特定配置 来授权必要的路径。
  • 为每个命名空间使用单独的服务端口或 IP 地址,这一点得到了一些 Knative 组件的支持,但文档并不完善。

信任流分析

Knative Eventing

从组件 到组件 信任流级别
事件生产者 事件源 低到高
事件源 Broker 接收器 低到高
直接事件生产者 Broker 接收器 低到高
Broker 接收器 Broker 触发器 无变化
Broker 触发器 消费者 高到低

Knative Serving

从组件 到组件 信任流级别
互联网 入口网关 低到高
集群网络 入口网关 低到高
入口网关 activator 低到低
入口网关 queue-proxy 低到高
queue-proxy 用户容器 高到高

威胁缓解措施

此威胁模型不具体涉及影响 Knative 和非 Knative 工作负载在集群中同等程度的可用性、保密性或完整性攻击;例如,阻止在集群上启动 Pod 的攻击会影响 Knative 和非 Knative 应用程序。专门阻止 Knative 自动缩放但不影响 Kubernetes Horizontal Pod Autoscaler 的攻击属于范围之内。

加固 (模糊测试) 的输入处理

Knative 在 2023 年进行了一项 外部安全审计。审计的重点之一是加固外部输入的解析器,包括加固 Knative 用于解析输入的上游库。此外,还为关键的解析路径实现了模糊测试。Knative 还使用内存安全语言 (Go) 编写,这降低了某些类型解析攻击的风险,如缓冲区溢出和释放后使用错误。

缓解措施:拦截或阻止请求、系统代码执行

外部 (可选内部) 网络接口的 TLS 配置

Knative 支持 为 Knative Service 自动配置 TLS 证书 以及 为 Broker 接收器配置证书。由于来自 Kubernetes 集群外部的流量可能需要通过互联网传输,集群管理员应启用外部 TLS 配置 (使用 Cert-Manager),以便为每个应用程序默认启用。虽然集群 CNI 可能为集群内流量提供传输安全保障,但对于流量和地址在集群内受到保护的应用程序来说,这是不可见的,因此也提供了对集群内部 TLS 的支持。

注意:Cert-Manager 必须安装在集群上,并且 在 Knative 中正确配置

缓解措施:拦截或阻止请求、绕过访问控制

验证集群内的事件源身份

Knative 支持使用 Kubernetes 服务帐户身份来认证传递到 Broker 接收器的事件,以及 强制执行 EventPolicy 来限制从经过身份验证的发送者接收的消息类型。Knative Serving 支持在互联网网关中对身份验证和访问策略进行外部配置,但具体能力因网关实现而异。

缓解措施:绕过访问控制

验证负载报告

Autoscaler 连接到 Activator 和 Queue Proxy 来收集负载报告。拨出到这些实例允许 Autoscaler 确信 (假设 CNI 可信) 发出这些报告的命名空间。在处理负载报告时,Autoscaler 会验证

缓解措施:阻止执行

支持与事件传输的 TLS 连接

Knative Eventing 路由层 (Broker、Channel) 连接到如 KafkaRabbitMQ 等传输层。Broker 和 Channel 实现支持使用 TLS 连接和存储在 Secret 中的每个应用程序 (命名空间) 的凭据来认证到底层消息传输。

注意:消息传输的管理员 **还必须** 在底层消息传输上设置适当的用户和访问控制规则来支持这种分离。

缓解措施:拦截或阻止请求、绕过访问控制

支持并鼓励 `restricted` Pod 安全标准 (Pod Security Standard)

Knative Serving 支持在适用的情况下以 `restricted` 配置文件 下运行应用程序 Pod,如果提交的 Pod 使用默认 (空) 值且与 `restricted` 配置文件不兼容,则会发出警告。

缓解措施:用户代码执行、系统代码执行

SLSA 构建和来源 (provenance)

Knative 对项目生成的 容器映像命令行二进制文件 进行签名,并附带 SBOM 和 SLSA 来源声明,描述其内容是如何构建的。通过允许管理员和用户验证其构件是否与 Knative 构建的构件相同,并验证关于临时和可重现构建的 SLSA 安全保证,这降低了供应链攻击的风险。

缓解措施:系统代码执行

本文档的使用

当向项目报告漏洞时,我们会查阅本文档以确定该报告是否描述了潜在的利用,如果是,则确定该利用的严重程度。当我们开发新功能时,我们会查阅本文档来考虑它们对威胁模型的影响。请注意,此威胁模型涵盖 Serving 和 Eventing;某些部分和威胁可能只适用于项目的某些组件。由于 Knative Functions 主要在应用程序开发者的基础设施上进行构建时执行,因此它需要一个不同的威胁模型,更侧重于供应链安全威胁 (它主要继承自 CNCF Buildpacks)。

多集群使用

Knative 并非专门为多集群或跨集群场景设计;在尝试将 **单个** Knative 安装跨多个集群扩展时可能存在额外风险,但如果此类场景中的每个集群都运行 Knative 组件的 **独立** 安装 (部分或全部组件),则此威胁模型应足够。

我们使用分析和 cookie 来了解网站流量。有关您使用我们网站的信息会与 Google 共享以达到此目的。了解更多。