保护集群

本文档涵盖与保护集群免受意外或恶意访问相关的主题,并提供有关整体安全性的建议。

准备开始

  • 你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具来与你的集群通信。建议在至少有两个不充当控制平面主机的节点的集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者你可以使用以下 Kubernetes 游乐场之一

    要检查版本,请输入 kubectl version

控制对 Kubernetes API 的访问

由于 Kubernetes 完全由 API 驱动,因此控制和限制谁可以访问集群以及允许他们执行哪些操作是第一道防线。

对所有 API 流量使用传输层安全性 (TLS)

Kubernetes 期望集群中的所有 API 通信默认都使用 TLS 加密,并且大多数安装方法都将允许创建必要的证书并将其分发给集群组件。请注意,某些组件和安装方法可能会通过 HTTP 启用本地端口,管理员应熟悉每个组件的设置,以识别潜在的不安全流量。

API 身份验证

为 API 服务器选择一种身份验证机制,以便在使用安装集群时匹配常见的访问模式。例如,小型、单用户集群可能希望使用简单的证书或静态 Bearer 令牌方法。较大的集群可能希望集成现有的 OIDC 或 LDAP 服务器,这些服务器允许将用户细分为组。

所有 API 客户端都必须进行身份验证,即使是基础设施的一部分(如节点、代理、调度程序和卷插件)也是如此。这些客户端通常是服务帐户或使用 x509 客户端证书,并且它们在集群启动时自动创建,或者作为集群安装的一部分进行设置。

有关更多信息,请参阅身份验证参考文档

API 授权

一旦通过身份验证,每个 API 调用也需要通过授权检查。Kubernetes 提供了一个集成的基于角色的访问控制 (RBAC)组件,该组件将传入的用户或组与捆绑在角色中的一组权限进行匹配。这些权限将动词(get、create、delete)与资源(pod、服务、节点)组合在一起,并且可以是命名空间范围的或集群范围的。提供了一组开箱即用的角色,这些角色根据客户端可能希望执行的操作提供合理的默认责任分离。建议你将节点RBAC授权器结合使用,并结合NodeRestriction准入插件。

与身份验证一样,简单而广泛的角色可能适用于较小的集群,但随着越来越多的用户与集群交互,可能需要将团队分成单独的命名空间,并使用更有限的角色。

对于授权,重要的是了解对一个对象的更新如何导致其他地方的操作。例如,用户可能无法直接创建 Pod,但允许他们创建 Deployment,Deployment 会代表他们创建 Pod,这将让他们间接创建这些 Pod。同样,从 API 中删除节点将导致计划在该节点上的 Pod 被终止并在其他节点上重新创建。开箱即用的角色代表了灵活性和常见用例之间的平衡,但应仔细审查更有限的角色,以防止意外升级。如果开箱即用的角色不符合你的需求,你可以根据你的用例创建特定的角色。

有关更多信息,请参阅授权参考部分

控制对 Kubelet 的访问

Kubelet 公开 HTTPS 端点,这些端点允许对节点和容器进行强大的控制。默认情况下,Kubelet 允许对此 API 进行未经身份验证的访问。

生产集群应启用 Kubelet 身份验证和授权。

有关更多信息,请参阅Kubelet 身份验证/授权参考

在运行时控制工作负载或用户的功能

Kubernetes 中的授权有意处于高层,专注于对资源的粗粒度操作。存在更强大的控制作为策略,以按用例限制这些对象如何对集群、自身和其他资源执行操作。

限制集群上的资源使用

资源配额限制分配给命名空间的资源数量或容量。这最常用于限制命名空间可以分配的 CPU、内存或持久磁盘的数量,但也可以控制每个命名空间中存在的 Pod、服务或卷的数量。

限制范围限制上述某些资源的最大或最小大小,以防止用户为常用保留资源(如内存)请求过高或过低的值,或者在未指定任何限制时提供默认限制。

控制容器运行的权限

Pod 定义包含一个安全上下文,允许它请求以节点上的特定 Linux 用户(如 root)身份运行、访问以特权方式运行或访问主机网络,以及其他否则允许它在主机节点上不受限制地运行的控件。

您可以配置Pod 安全准入,以在命名空间中强制使用特定的Pod 安全标准,或检测违规行为。

通常,大多数应用程序工作负载需要有限的访问主机资源的权限,以便它们可以成功地以 root 进程(uid 0)运行,而无需访问主机信息。但是,考虑到与 root 用户关联的特权,您应该编写应用程序容器以非 root 用户身份运行。同样,希望阻止客户端应用程序逃逸其容器的管理员应应用 BaselineRestricted Pod 安全标准。

防止容器加载不需要的内核模块

在某些情况下,例如当连接硬件或挂载文件系统时,Linux 内核会自动从磁盘加载内核模块。与 Kubernetes 特别相关的是,即使是非特权进程也可以通过创建适当类型的套接字来导致加载某些与网络协议相关的内核模块。这可能允许攻击者利用管理员认为未使用的内核模块中的安全漏洞。

要防止自动加载特定模块,您可以从节点卸载它们,或添加规则来阻止它们。在大多数 Linux 发行版上,您可以通过创建一个类似 /etc/modprobe.d/kubernetes-blacklist.conf 的文件来实现,内容如下:

# DCCP is unlikely to be needed, has had multiple serious
# vulnerabilities, and is not well-maintained.
blacklist dccp

# SCTP is not used in most Kubernetes clusters, and has also had
# vulnerabilities in the past.
blacklist sctp

要更通用地阻止模块加载,您可以使用 Linux 安全模块(例如 SELinux)完全拒绝容器的 module_request 权限,从而阻止内核在任何情况下为容器加载模块。(Pod 仍然可以使用手动加载的模块,或者内核代表某些更特权的进程加载的模块。)

限制网络访问

命名空间的网络策略允许应用程序作者限制其他命名空间中的哪些 Pod 可以访问其命名空间内的 Pod 和端口。许多受支持的 Kubernetes 网络提供商现在都遵守网络策略。

配额和限制范围也可以用于控制用户是否可以请求节点端口或负载均衡服务,在许多集群上,这可以控制这些用户的应用程序是否在集群外部可见。

可能还有其他保护措施可用于控制每个插件或每个环境的网络规则,例如每个节点的防火墙、物理隔离集群节点以防止串扰或高级网络策略。

限制云元数据 API 访问

云平台(AWS、Azure、GCE 等)通常会在本地向实例公开元数据服务。默认情况下,在实例上运行的 Pod 可以访问这些 API,并且可以包含该节点的云凭证或配置数据(例如 kubelet 凭证)。这些凭证可用于在集群内升级或升级到同一帐户下的其他云服务。

在云平台上运行 Kubernetes 时,请限制分配给实例凭证的权限,使用网络策略限制 Pod 对元数据 API 的访问,并避免使用配置数据来传递密钥。

控制 Pod 可以访问的节点

默认情况下,对哪些节点可以运行 Pod 没有限制。Kubernetes 提供了一套丰富的策略来控制将 Pod 放置到节点上以及可供最终用户使用的基于污点的 Pod 放置和驱逐。对于许多集群,使用这些策略来分离工作负载可以成为作者采用或通过工具强制执行的约定。

作为管理员,可以使用 beta 准入插件 PodNodeSelector 来强制命名空间内的 Pod 默认或需要特定的节点选择器,如果最终用户无法更改命名空间,这可以大大限制特定工作负载中所有 Pod 的放置。

保护集群组件免受破坏

本节介绍一些保护集群免受破坏的常见模式。

限制对 etcd 的访问

对 API 的 etcd 后端具有写入权限等同于获得整个集群的 root 权限,而读取权限可用于相当快地升级。管理员应始终使用来自 API 服务器的强大凭据来访问其 etcd 服务器,例如通过 TLS 客户端证书进行相互身份验证,并且通常建议将 etcd 服务器隔离在只有 API 服务器可以访问的防火墙后面。

启用审计日志

审计记录器是一项 beta 功能,它记录 API 执行的操作,以便在发生破坏时进行后续分析。建议启用审计日志并将审计文件存档在安全服务器上。

限制对 alpha 或 beta 功能的访问

Alpha 和 beta Kubernetes 功能正在积极开发中,可能存在导致安全漏洞的限制或错误。请始终评估 alpha 或 beta 功能可能提供的价值与可能对您的安全态势造成的风险。如有疑问,请禁用您不使用的功能。

频繁轮换基础设施凭证

密钥或凭证的生命周期越短,攻击者就越难利用该凭证。为证书设置较短的生命周期并自动化其轮换。使用可以控制已颁发令牌可用时长的身份验证提供程序,并尽可能使用较短的生命周期。如果您在外部集成中使用服务帐户令牌,请计划频繁轮换这些令牌。例如,一旦引导阶段完成,用于设置节点的引导令牌应被撤销或其授权被删除。

在启用第三方集成之前进行审查

许多第三方与 Kubernetes 的集成可能会更改集群的安全配置文件。启用集成时,请务必在授予扩展访问权限之前查看其请求的权限。例如,许多安全集成可能会请求访问以查看您集群上的所有密钥,这实际上是使该组件成为集群管理员。如有疑问,请尽可能将集成限制为在单个命名空间中运行。

如果组件可以在 kube-system 命名空间等命名空间内创建 Pod,则它们也可能具有出乎意料的强大功能,因为如果这些服务帐户被授予对允许的 PodSecurityPolicies 的访问权限,则这些 Pod 可以获得对服务帐户密钥的访问权限或以提升的权限运行。

如果您使用 Pod 安全准入并允许任何组件在允许特权 Pod 的命名空间内创建 Pod,则这些 Pod 可能能够逃脱其容器并利用此扩大的访问权限来提升其特权。

您不应允许不受信任的组件在任何系统命名空间(名称以 kube- 开头的命名空间)中创建 Pod,也不应在任何允许特权提升的命名空间中创建 Pod。

静态加密密钥

一般来说,etcd 数据库将包含通过 Kubernetes API 访问的任何信息,并且可能会使攻击者对您集群的状态具有显著的可见性。始终使用经过良好审查的备份和加密解决方案来加密备份,并考虑尽可能使用全磁盘加密。

Kubernetes 支持对 Kubernetes API 中的信息进行可选的静态加密。这使您可以确保当 Kubernetes 存储对象(例如,SecretConfigMap 对象)的数据时,API 服务器会写入对象的加密表示。这种加密意味着即使有人可以访问 etcd 备份数据,也无法查看这些对象的内容。在 Kubernetes 1.32 中,您还可以加密自定义资源;在 v1.26 版本中,自定义资源定义中定义的扩展 API 的静态加密已添加到 Kubernetes。

接收有关安全更新的警报和报告漏洞

加入 kubernetes-announce 组以接收有关安全公告的电子邮件。有关如何报告漏洞的更多信息,请参阅安全报告页面。

下一步

上次修改时间:2024 年 9 月 17 日下午 10:57(太平洋标准时间):添加专用的 seccomp 节点参考 (c2b49fee37)