安全检查表
此检查表旨在提供基本指南列表,并链接到每个主题的更全面文档。它并不声称是详尽无遗的,并且会不断发展。
关于如何阅读和使用本文档
- 主题的顺序不反映优先级顺序。
- 一些检查表项在每个部分的列表下面的段落中详细说明。
注意
检查表不足以单独实现良好的安全状态。良好的安全状态需要持续关注和改进,但检查表可以成为迈向安全防范永无止境的第一步。此检查表中的一些建议对于您的特定安全需求可能过于严格或过于宽松。由于 Kubernetes 安全性并非“一刀切”,因此应根据其本身的优缺点评估每类检查表项。身份验证和授权
- 引导后,
system:masters
组不用于用户或组件身份验证。 - kube-controller-manager 在启用
--use-service-account-credentials
的情况下运行。 - 根证书受到保护(离线 CA 或具有有效访问控制的托管在线 CA)。
- 中间证书和叶子证书的到期日期不超过 3 年。
- 存在定期访问审查流程,并且审查间隔不超过 24 个月。
- 遵循基于角色的访问控制良好实践以获取与身份验证和授权相关的指南。
引导后,用户和组件都不应以 system:masters
身份向 Kubernetes API 进行身份验证。同样,应避免将所有 kube-controller-manager 作为 system:masters
运行。实际上,system:masters
应该只用作应急机制,而不是管理员用户。
网络安全
- 使用的 CNI 插件支持网络策略。
- 入口和出口网络策略应用于集群中的所有工作负载。
- 每个命名空间内的默认网络策略都已到位,选择所有 Pod,拒绝所有内容。
- 如果适用,则使用服务网格加密集群内的所有通信。
- Kubernetes API、kubelet API 和 etcd 未在 Internet 上公开。
- 从工作负载到云元数据 API 的访问被过滤。
- LoadBalancer 和 ExternalIPs 的使用受到限制。
许多容器网络接口 (CNI) 插件插件提供了限制 Pod 可以与其通信的网络资源的功能。这最常通过网络策略来完成,网络策略提供了命名空间资源来定义规则。默认网络策略阻止每个命名空间中的所有出口和入口,选择所有 Pod,这对于采用允许列表方法很有用,确保不会遗漏任何工作负载。
并非所有 CNI 插件都提供传输中加密。如果所选插件缺少此功能,则另一种解决方案可能是使用服务网格来提供该功能。
控制平面的 etcd 数据存储应具有控制措施以限制访问,并且不应在 Internet 上公开。此外,应使用相互 TLS (mTLS) 与其进行安全通信。此证书颁发机构对于 etcd 应该是唯一的。
对 Kubernetes API 服务器的外部 Internet 访问应受到限制,以免公开 API。请注意,许多托管 Kubernetes 发行版默认情况下都会公开 API 服务器。然后,您可以使用堡垒主机访问服务器。
应限制对kubelet API 的访问,并且不应公开,默认的身份验证和授权设置(当未指定带有 --config
标志的配置文件时)过于宽松。
如果使用云提供商托管 Kubernetes,则还应限制或阻止从 Pod 到云元数据 API 169.254.169.254
的访问(如果不需要),因为它可能会泄露信息。
有关 LoadBalancer 和 ExternalIPs 使用限制,请参阅CVE-2020-8554:使用 LoadBalancer 或 ExternalIPs 进行中间人攻击和DenyServiceExternalIPs 准入控制器以获取更多信息。
Pod 安全
- 仅在必要时才授予对
create
、update
、patch
、delete
工作负载的 RBAC 权限。 - 适当的 Pod 安全标准策略适用于所有命名空间并得到执行。
- 为工作负载设置内存限制,限制等于或低于请求。
- CPU 限制可以设置在敏感工作负载上。
- 对于支持它的节点,Seccomp 已启用,并为程序配置了适当的系统调用配置文件。
- 对于支持它的节点,AppArmor 或 SELinux 已启用,并为程序配置了适当的配置文件。
RBAC 授权至关重要,但粒度不足以对 Pod 的资源(或对管理 Pod 的任何资源)进行授权。唯一的粒度是资源本身上的 API 动词,例如,Pod 上的 create
。如果没有额外的准入,则创建这些资源的授权允许直接无限制地访问集群的可调度节点。
Pod 安全标准定义了三种不同的策略:特权、基线和受限,它们限制了如何在 PodSpec
中设置字段以确保安全。可以使用新的Pod 安全准入(默认情况下启用)或第三方准入 webhook 在命名空间级别强制执行这些标准。请注意,与它所取代的已删除的 PodSecurityPolicy 准入相反,Pod 安全准入可以轻松地与准入 webhook 和外部服务结合使用。
Pod 安全准入 restricted
策略是Pod 安全标准集中限制最严格的策略,可以在多种模式下运行,warn
、audit
或 enforce
,以根据安全最佳实践逐步应用最合适的安全上下文。然而,应该单独调查 Pod 的安全上下文,以限制 Pod 在预定义安全标准之上可能拥有的特权和访问权限,以用于特定用例。
有关Pod 安全的动手教程,请参阅博客文章Kubernetes 1.23:Pod 安全升级到 Beta 版。
应设置内存和 CPU 限制,以限制 Pod 在节点上可以消耗的内存和 CPU 资源,从而防止来自恶意或被破坏的工作负载的潜在 DoS 攻击。此类策略可以通过准入控制器强制执行。请注意,CPU 限制将限制使用量,因此可能会对自动缩放功能或效率产生意外影响,即以尽力而为的方式运行进程,并使用可用的 CPU 资源。
注意
内存限制高于请求可能会使整个节点面临 OOM 问题。启用 Seccomp
Seccomp 代表安全计算模式,自 2.6.12 版以来一直是 Linux 内核的一项功能。它可用于对进程的特权进行沙箱处理,限制它可以从用户空间到内核进行的调用。Kubernetes 允许您将加载到节点上的 seccomp 配置文件自动应用于 Pod 和容器。
Seccomp 可以通过减少容器内可用的 Linux 内核系统调用攻击面来提高工作负载的安全性。seccomp 过滤器模式利用 BPF 创建特定系统调用的允许或拒绝列表,称为配置文件。
从 Kubernetes 1.27 开始,您可以启用 RuntimeDefault
作为所有工作负载的默认 seccomp 配置文件。有关此主题,请参阅安全教程。此外,Kubernetes 安全配置文件操作器是一个促进集群中 seccomp 的管理和使用的项目。
注意
Seccomp 仅在 Linux 节点上可用。启用 AppArmor 或 SELinux
AppArmor
AppArmor 是一个 Linux 内核安全模块,它可以提供一种简单的方法来实现强制访问控制 (MAC) 并通过系统日志更好地进行审计。默认的 AppArmor 配置文件在支持它的节点上强制执行,或者可以配置自定义配置文件。与 seccomp 一样,AppArmor 也通过配置文件进行配置,其中每个配置文件要么在强制模式下运行(阻止访问不允许的资源),要么在抱怨模式下运行(仅报告违规)。AppArmor 配置文件在每个容器的基础上通过注释强制执行,允许进程获得恰当的特权。
注意
AppArmor 仅在 Linux 节点上可用,并在某些 Linux 发行版中启用。SELinux
SELinux 也是一个 Linux 内核安全模块,它可以提供一种机制来支持访问控制安全策略,包括强制访问控制 (MAC)。SELinux 标签可以通过其 securityContext
部分分配给容器或 Pod。
注意
SELinux 仅在 Linux 节点上可用,并在某些 Linux 发行版中启用。日志和审计
- 如果启用了审计日志,则会对其进行保护,防止一般访问。
Pod 放置
- Pod 放置应根据应用程序的敏感度级别进行。
- 敏感应用程序应隔离运行在节点上,或使用特定的沙盒运行时。
不同敏感度级别的 Pod(例如,应用程序 Pod 和 Kubernetes API 服务器)应部署到不同的节点上。节点隔离的目的是防止应用程序容器突破后直接访问敏感度更高的应用程序,从而轻松地在集群内进行横向移动。应强制执行此隔离,以防止 Pod 意外部署到同一节点上。可以使用以下功能强制执行此操作
- 节点选择器
- 作为 Pod 规范的一部分,键值对指定要部署到的节点。可以使用 PodNodeSelector 准入控制器在命名空间和集群级别强制执行这些操作。
- PodTolerationRestriction
- 一种准入控制器,允许管理员限制命名空间内允许的 容忍。命名空间内的 Pod 只能利用命名空间对象注释键上指定的容忍,这些键提供了一组默认和允许的容忍。
- RuntimeClass
- RuntimeClass 是一种用于选择容器运行时配置的功能。容器运行时配置用于运行 Pod 的容器,并且可以以性能开销为代价提供或多或少的与主机的隔离。
密钥
- ConfigMap 不应用于存储机密数据。
- 已为 Secret API 配置静态加密。
- 如果适用,应部署并提供一种机制来注入存储在第三方存储中的密钥。
- 服务帐户令牌不应挂载到不需要它们的 Pod 中。
- 正在使用绑定服务帐户令牌卷,而不是非过期令牌。
Pod 所需的密钥应存储在 Kubernetes Secret 中,而不是 ConfigMap 等替代方案中。存储在 etcd 中的 Secret 资源应进行静态加密。
需要密钥的 Pod 应通过卷自动挂载这些密钥,最好是像使用 emptyDir.medium
选项 一样存储在内存中。还可以使用机制从第三方存储中注入密钥作为卷,例如 Secrets Store CSI 驱动程序。与为 Pod 服务帐户提供对密钥的 RBAC 访问权限相比,应该优先执行此操作。这将允许将密钥作为环境变量或文件添加到 Pod 中。请注意,与 Linux 中文件上的权限机制相比,由于日志中的崩溃转储和 Linux 中环境变量的非机密性,环境变量方法可能更容易泄漏。
服务帐户令牌不应挂载到不需要它们的 Pod 中。可以通过在服务帐户中将 automountServiceAccountToken
设置为 false
来配置此项,以应用于整个命名空间或特定于 Pod。对于 Kubernetes v1.22 及更高版本,请使用 绑定服务帐户 来获取有时限的服务帐户凭据。
镜像
- 尽量减少容器镜像中的不必要内容。
- 容器镜像配置为以非特权用户身份运行。
- 对容器镜像的引用应使用 sha256 校验和(而不是标签)进行,或者在部署时通过 准入控制 验证镜像的数字签名来验证镜像的来源。
- 容器镜像应在创建和部署过程中定期扫描,并修补已知的易受攻击的软件。
容器镜像应包含运行其打包程序所需的最低限度内容。最好只包含程序及其依赖项,并从尽可能小的基础镜像构建镜像。特别是,生产中使用的镜像不应包含 shell 或调试实用程序,因为可以使用 临时调试容器 进行故障排除。
通过在 Dockerfile 中使用 USER
指令 构建镜像,以直接以非特权用户身份启动。即使镜像清单中未指定,安全上下文 也允许使用 runAsUser
和 runAsGroup
以特定用户和组启动容器镜像。但是,镜像层中的文件权限可能使得无法在不修改镜像的情况下仅使用新的非特权用户启动进程。
避免使用镜像标签来引用镜像,尤其是 latest
标签,因为标签后面的镜像很容易在注册表中被修改。最好使用完整的 sha256
校验和,该校验和对于镜像清单是唯一的。可以通过 ImagePolicyWebhook 强制执行此策略。镜像签名也可以在部署时通过 准入控制器 自动 验证,以验证其真实性和完整性。
扫描容器镜像可以防止关键漏洞与容器镜像一起部署到集群中。在将容器镜像部署到集群之前,应完成镜像扫描,并且通常作为 CI/CD 管道中部署过程的一部分完成。镜像扫描的目的是获取有关容器镜像中可能存在的漏洞及其预防措施的信息,例如 通用漏洞评分系统 (CVSS) 分数。如果将镜像扫描的结果与管道合规性规则相结合,则只有正确修补的容器镜像才会最终进入生产环境。
准入控制器
- 应启用适当选择的准入控制器。
- Pod 安全策略应由 Pod 安全准入或/和 Webhook 准入控制器强制执行。
- 准入链插件和 Webhook 应进行安全配置。
准入控制器可以帮助提高集群的安全性。但是,它们本身也可能带来风险,因为它们扩展了 API 服务器,并且 应进行适当的安全保护。
以下列表提供了一些准入控制器,可以考虑使用这些控制器来增强集群和应用程序的安全状况。它包括本文档其他部分中可能引用的控制器。
第一组准入控制器包括 默认启用 的插件,除非您知道自己在做什么,否则请考虑保持启用它们
CertificateApproval
- 执行额外的授权检查,以确保批准用户有权批准证书请求。
CertificateSigning
- 执行额外的授权检查,以确保签名用户有权签署证书请求。
CertificateSubjectRestriction
- 拒绝任何指定
system:masters
“组”(或“组织属性”)的证书请求。 LimitRanger
- 强制执行 LimitRange API 约束。
MutatingAdmissionWebhook
- 允许通过 Webhook 使用自定义控制器,这些控制器可能会改变其审查的请求。
PodSecurity
- Pod 安全策略的替代品,限制已部署 Pod 的安全上下文。
ResourceQuota
- ResourceQuota
强制执行资源配额以防止资源过度使用。
- ValidatingAdmissionWebhook
允许通过 Webhook 使用自定义控制器,这些控制器不会改变其审查的请求。
第二组包括默认情况下未启用但处于正式发布状态的插件,建议使用这些插件来提高安全状况
- DenyServiceExternalIPs
拒绝所有对
Service.spec.externalIPs
字段的新使用。这是对CVE-2020-8554:使用 LoadBalancer 或 ExternalIPs 进行中间人攻击 的缓解措施。
- NodeRestriction
将 kubelet 的权限限制为仅修改它们拥有的 Pod API 资源或代表自身的节点 API 资源。它还可以防止 kubelet 使用 node-restriction.kubernetes.io/
注释,攻击者可以使用该注释访问 kubelet 的凭据,从而影响 Pod 放置到受控节点。
第三组包括默认情况下未启用但可以考虑用于某些用例的插件
- AlwaysPullImages
强制使用标记镜像的最新版本,并确保部署程序有权使用该镜像。
- ImagePolicyWebhook
允许通过 Webhook 对镜像强制执行其他控制。
- 下一步
- 通过 Pod 创建进行权限提升 警告您有关特定访问控制风险;请检查您是如何管理该威胁的。
- 如果您使用 Kubernetes RBAC,请阅读 RBAC 最佳实践,以获取有关授权的更多信息。
- 有关保护集群免受意外或恶意访问的信息,请参阅 保护集群。
- 有关多租户的配置选项建议和最佳实践,请参阅 集群多租户指南。