安全检查清单
此检查表旨在提供一个基本的指导列表,其中包含指向每个主题更全面文档的链接。它不声称是详尽的,并且会不断发展。
关于如何阅读和使用本文档
- 主题的顺序并不反映优先级的顺序。
- 一些检查表项目在每个部分列表下方的段落中进行了详细说明。
注意
仅凭检查表不足以获得良好的安全态势。良好的安全态势需要持续的关注和改进,但检查表可以是在为安全做好准备的永无止境的旅程中的第一步。此检查表中的某些建议可能对您的特定安全需求而言过于严格或过于宽松。由于 Kubernetes 安全不是“一刀切”,因此应根据其优点评估每个类别的检查表项目。身份验证和授权
- 引导后,
system:masters
组不用于用户或组件身份验证。 - kube-controller-manager 在启用
--use-service-account-credentials
的情况下运行。 - 根证书受到保护(离线 CA 或具有有效访问控制的托管在线 CA)。
- 中间证书和叶证书的到期日期不超过未来 3 年。
- 存在定期访问审查的流程,并且审查的间隔时间不超过 24 个月。
- 遵循基于角色的访问控制最佳实践,以获取有关身份验证和授权的指导。
引导后,用户和组件都不应以 system:masters
的身份向 Kubernetes API 进行身份验证。同样,应避免以 system:masters
的身份运行所有 kube-controller-manager。实际上,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
为了限制 Pod 在节点上可以消耗的内存和 CPU 资源,并防止恶意或受损的工作负载发起潜在的 DoS 攻击,应该设置内存和 CPU 限制。这种策略可以通过准入控制器来强制执行。请注意,CPU 限制会限制使用量,因此可能会对自动缩放功能或效率产生意想不到的影响,例如,在可用的 CPU 资源下尽力运行进程。
注意
内存限制高于请求可能会使整个节点面临 OOM 问题。启用 Seccomp
Seccomp 代表安全计算模式,自 Linux 内核 2.6.12 版本以来一直是其特性。它可用于沙箱化进程的权限,限制其从用户空间向内核发出的调用。Kubernetes 允许您自动将加载到节点上的 seccomp 配置文件应用于您的 Pod 和容器。
Seccomp 可以通过减少容器内部可用的 Linux 内核系统调用攻击面来提高工作负载的安全性。seccomp 过滤器模式利用 BPF 创建特定系统调用的允许或拒绝列表,称为配置文件。
自 Kubernetes 1.27 起,您可以启用 RuntimeDefault
作为所有工作负载的默认 seccomp 配置文件。关于此主题的安全教程可用。此外,Kubernetes 安全配置文件 Operator 是一个有助于管理和使用集群中 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 的容器,并且可以以性能开销为代价提供或多或少的与主机的隔离。
Secrets
- ConfigMap 不用于保存机密数据。
- Secret API 配置了静态加密。
- 如果合适,会部署并提供一种机制来注入存储在第三方存储中的密钥。
- 服务帐户令牌不会挂载到不需要它们的 Pod 中。
- 绑定的服务帐户令牌卷正在使用中,而不是非过期的令牌。
Pod 所需的密钥应存储在 Kubernetes Secrets 中,而不是像 ConfigMap 这样的替代方案。存储在 etcd 中的 Secret 资源应静态加密。
需要密钥的 Pod 应通过卷自动挂载这些密钥,最好像 emptyDir.medium
选项那样存储在内存中。该机制还可用于从第三方存储中将密钥作为卷注入,例如 Secrets Store CSI Driver。与为 Pod 提供对密钥的服务帐户 RBAC 访问相比,这应该是优先选择的方式。这将允许将密钥作为环境变量或文件添加到 Pod 中。请注意,与文件上的权限机制相比,环境变量方法可能更容易由于日志中的崩溃转储以及 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
- 强制执行资源配额以防止过度使用资源。
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 良好实践以获取有关授权的更多信息。
- 保护集群,了解有关保护集群免受意外或恶意访问的信息。
- 关于多租户的配置选项建议和最佳实践,请参阅集群多租户指南。
- 关于加强 Kubernetes 集群的补充资源,请参考博文“深入了解 NSA/CISA Kubernetes 加固指南”。