安全检查清单
本清单旨在提供有关每个主题的更全面文档的链接的基本指导清单。它不声称是详尽的,并且旨在不断发展。
关于如何阅读和使用本文档
- 主题的顺序不反映优先级顺序。
- 某些清单项在每个部分列表下面的段落中详细说明。
注意
清单本身 **不足以** 确保良好的安全态势。良好的安全态势需要持续关注和改进,但清单可以是迈向安全准备的漫漫征途的第一步。本清单中的一些建议可能对您的特定安全需求过于严格或过于宽松。由于 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 不会公开暴露在互联网上。
- 从工作负载访问云元数据 API 进行了过滤。
- 限制使用 LoadBalancer 和 ExternalIPs。
许多 容器网络接口 (CNI) 插件 插件提供限制 Pod 可以通信的网络资源的功能。这最常通过 网络策略 完成,它提供了一个命名空间资源来定义规则。默认的网络策略阻止每个命名空间中所有 Pod 的所有出站和入站流量,可以选择所有 Pod,这对于采用允许列表方法非常有用,可以确保没有工作负载被遗漏。
并非所有 CNI 插件都提供传输加密。如果选择的插件缺少此功能,则可以使用服务网格来提供该功能作为替代解决方案。
控制平面的 etcd 数据存储应具有控制措施来限制访问,并且不应公开暴露在互联网上。此外,应使用双向 TLS (mTLS) 安全地与其通信。为此,证书颁发机构应对 etcd 唯一。
应限制对 Kubernetes API 服务器的外部 Internet 访问,以防止公开暴露 API。请注意,许多托管的 Kubernetes 发行版默认情况下公开暴露 API 服务器。然后,您可以使用堡垒主机来访问服务器。
应限制对 kubelet API 的访问,并且不应公开暴露 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 安全标准 设置中限制性最强的 Pod 安全准入 restricted
策略,可以在几种模式下运行,warn
、audit
或 enforce
,以便根据安全最佳实践逐步应用最合适的 安全上下文。但是,应单独调查 Pod 的 安全上下文,以限制 Pod 在预定义安全标准之上可能具有的权限和访问权限,以适应特定用例。
有关 Pod 安全 的动手教程,请参阅博客文章 Kubernetes 1.23:Pod 安全升级为 Beta。
应设置 内存和 CPU 限制,以限制 Pod 在节点上可以消耗的内存和 CPU 资源,从而防止恶意或受损工作负载造成的潜在拒绝服务攻击。此类策略可以通过准入控制器强制执行。请注意,CPU 限制会限制使用,因此可能会对自动扩展功能或效率产生意想不到的影响,例如以最佳努力的方式运行该过程,使用可用的 CPU 资源。
注意
内存限制大于请求可能会使整个节点面临 OOM 问题。启用 Seccomp
Seccomp 代表安全计算模式,自 Linux 内核 2.6.12 版本起已成为一项功能。它可用于沙盒化进程的权限,限制它可以从用户空间调用到内核的调用。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)。可以 通过其 securityContext
部分 将 SELinux 标签分配给容器或 Pod。
注意
SELinux 仅适用于 Linux 节点,并在 一些 Linux 发行版 中启用。日志和审计
- 如果启用了审计日志,则应保护审计日志免受一般访问。
Pod 部署
- Pod 部署应根据应用程序的敏感性等级进行。
- 敏感应用程序应在节点上隔离运行,或使用特定的沙盒运行时。
敏感性等级不同的 Pod(例如,应用程序 Pod 和 Kubernetes API 服务器)应部署到不同的节点上。节点隔离的目的是防止应用程序容器突破,直接提供对敏感性等级更高的应用程序的访问权限,从而轻松地在集群内进行横向移动。应强制执行这种分离,以防止 Pod 意外部署到同一个节点上。这可以通过以下功能强制执行
- 节点选择器
- 作为 Pod 规范一部分的键值对,指定要部署到的节点。这些可以在命名空间和集群级别使用 PodNodeSelector 准入控制器强制执行。
- PodTolerationRestriction
- 一个准入控制器,允许管理员限制命名空间内允许的 容忍度。命名空间内的 Pod 只能使用在命名空间对象注释键上指定的容忍度,这些键提供了一组默认和允许的容忍度。
- RuntimeClass
- RuntimeClass 是一个用于选择容器运行时配置的特性。容器运行时配置用于运行 Pod 的容器,并且可以提供更多或更少的与主机的隔离,但会以性能开销为代价。
秘密
- 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 或调试实用程序,因为可以使用短暂调试容器 用于故障排除。
通过使用USER
指令在 Dockerfile 中,构建映像以直接以非特权用户启动。该安全上下文 允许容器映像以特定用户和组启动,使用 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 良好实践 以获取有关授权的更多信息。
- 保护集群,以获取有关保护集群免受意外或恶意访问的信息。
- 集群多租户指南,以获取有关多租户的配置选项建议和最佳实践。
- 博客文章“更深入地了解 NSA/CISA Kubernetes 加固指南”,以获取有关加固 Kubernetes 集群的补充资源。