安全清单
此检查清单旨在提供基本指南列表,并附带指向每个主题的更全面文档的链接。它不声称详尽无遗,并且旨在不断发展。
如何阅读和使用此文档
- 主题的顺序不反映优先级顺序。
- 某些检查清单项目在每个部分列表下面的段落中进行了详细说明。
注意
仅凭检查清单不足以实现良好的安全状况。良好的安全状况需要持续的关注和改进,但检查清单可以是通往永无止境的安全准备之旅的第一步。此检查清单中的某些建议可能对你的特定安全需求来说过于严格或过于宽松。由于 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 Security Graduates to Beta。
应设置 内存和 CPU 限制,以限制 Pod 在节点上可消耗的内存和 CPU 资源,从而防止恶意或被攻破的工作负载可能发动的 DoS 攻击。此类策略可以通过准入控制器强制执行。请注意,CPU 限制将限制使用,从而可能对自动扩缩功能或效率产生意想不到的影响,例如在可用 CPU 资源下以尽力而为的方式运行进程。
注意
如果内存限制高于请求,可能会导致整个节点出现 OOM 问题。启用 Seccomp
Seccomp 代表安全计算模式,自 Linux 内核版本 2.6.12 以来一直是其一项功能。它可用于沙箱化进程的权限,限制其能够从用户空间向内核进行的调用。Kubernetes 允许你将加载到节点上的 seccomp 配置文件自动应用于你的 Pod 和容器。
Seccomp 可以通过减少容器内可用的 Linux 内核系统调用攻击面来提高工作负载的安全性。seccomp 过滤模式利用 BPF 创建特定系统调用的允许或拒绝列表,称为配置文件。
自 Kubernetes 1.27 起,你可以将 RuntimeDefault
作为所有工作负载的默认 seccomp 配置文件。有关此主题的 安全教程 可用。此外,Kubernetes Security Profiles 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 的容器,并且可以以性能开销为代价提供或多或少的与主机的隔离。
Secret
- ConfigMap 不用于保存机密数据。
- Secret API 已配置静态加密。
- 如果适用,部署并提供了一种机制来注入存储在第三方存储中的 Secret。
- ServiceAccount Token 未挂载到不需要它们的 Pod 中。
- 使用 绑定 ServiceAccount Token 卷 代替不限期的 Token。
Pod 所需的 Secret 应存储在 Kubernetes Secret 中,而不是 ConfigMap 等替代方案。存储在 etcd 中的 Secret 资源应进行 静态加密。
需要 Secret 的 Pod 应通过卷自动挂载这些 Secret,最好存储在内存中,例如使用 emptyDir.medium
选项。也可以使用机制将第三方存储中的 Secret 作为卷注入,例如 Secrets Store CSI Driver。这应优先于为 Pod 的 ServiceAccount 提供对 Secret 的 RBAC 访问。这将允许将 Secret 作为环境变量或文件添加到 Pod 中。请注意,由于日志中的崩溃转储以及 Linux 中环境变量的非机密性质,环境变量方法可能更容易泄露,而文件上的权限机制则不同。
不需要 ServiceAccount Token 的 Pod 不应挂载这些 Token。这可以通过将 automountServiceAccountToken
设置为 false
来配置,无论是针对整个命名空间中的 ServiceAccount,还是专门针对某个 Pod。对于 Kubernetes v1.22 及更高版本,请使用 绑定 ServiceAccount 以获取有时限的 ServiceAccount 凭据。
镜像
- 最小化容器镜像中不必要的内容。
- 容器镜像配置为以非特权用户身份运行。
- 通过 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 Security Policy 的替代品,限制部署 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 最佳实践 以获取有关授权的更多信息。
- 保护集群 以获取有关保护集群免受意外或恶意访问的信息。
- 集群多租户指南 用于多租户的配置选项建议和最佳实践。
- 博客文章 “A Closer Look at NSA/CISA Kubernetes Hardening Guidance”,是关于强化 Kubernetes 集群的补充资源。