基于角色的访问控制最佳实践
Kubernetes RBAC 是一个关键的安全控制措施,用于确保集群用户和工作负载仅拥有执行其角色所需的资源访问权限。在为集群用户设计权限时,重要的是确保集群管理员了解可能发生特权升级的区域,以降低过度访问导致安全事件的风险。
此处列出的良好实践应与一般 RBAC 文档 结合阅读。
一般良好实践
最小特权
理想情况下,应为用户和服务帐户分配最少的 RBAC 权限。应仅使用其操作明确需要的权限。虽然每个集群都将有所不同,但可以应用一些通用规则:
- 尽可能在命名空间级别分配权限。使用 RoleBindings 而不是 ClusterRoleBindings,以便仅在特定命名空间内授予用户权限。
- 尽可能避免提供通配符权限,特别是对所有资源的权限。由于 Kubernetes 是一个可扩展的系统,因此提供通配符访问权限不仅赋予所有当前存在于集群中的对象类型的权限,还赋予将来创建的所有对象类型的权限。
- 管理员不应使用
cluster-admin
帐户,除非有特殊需要。提供具有 模拟权限 的低特权帐户可以避免意外修改集群资源。 - 避免将用户添加到
system:masters
组。任何属于此组的用户都会绕过所有 RBAC 权限检查,并且始终拥有不受限制的超级用户访问权限,无法通过删除 RoleBindings 或 ClusterRoleBindings 来撤销。顺便说一下,如果集群正在使用授权 Webhook,那么属于此组的成员也会绕过该 Webhook(来自属于该组的用户请求永远不会发送到 Webhook)。
最小化特权令牌的分发
理想情况下,Pod 不应分配被授予强大权限的服务帐户(例如,特权升级风险 下列出的任何权限)。在工作负载需要强大权限的情况下,请考虑以下做法:
- 限制运行强大 Pod 的节点数量。确保运行的任何 DaemonSet 都是必要的,并且以最小特权运行,以限制容器逃逸的爆炸半径。
- 避免在不受信任或公开暴露的 Pod 旁边运行强大 Pod。考虑使用 污点和容忍、节点亲和性 或 Pod 反亲和性 来确保 Pod 不与不受信任或不太受信任的 Pod 运行在一起。请特别注意不太受信任的 Pod 未满足 **受限** Pod 安全标准的情况。
硬化
Kubernetes 默认提供访问权限,这些权限可能不是每个集群都需要的。审查默认提供的 RBAC 权限可以提供安全硬化机会。通常,不应更改提供给 system:
帐户的权限,但有一些硬化集群权限的选项:
- 审查
system:unauthenticated
组的绑定并尽可能删除它们,因为这会授予任何可以从网络级别联系 API 服务器的人访问权限。 - 通过设置
automountServiceAccountToken: false
来避免默认自动挂载服务帐户令牌。有关更多详细信息,请参见 使用默认服务帐户令牌。为 Pod 设置此值将覆盖服务帐户设置,需要服务帐户令牌的工作负载仍然可以挂载它们。
定期审查
定期审查 Kubernetes RBAC 设置,以查找冗余条目和可能的特权升级至关重要。如果攻击者能够创建与已删除用户同名的用户帐户,他们会自动继承已删除用户的全部权限,特别是分配给该用户的权限。
Kubernetes RBAC - 特权升级风险
在 Kubernetes RBAC 中,存在许多特权,如果授予这些特权,可以允许用户或服务帐户在集群中升级其特权或影响集群外部的系统。
本节旨在提供有关集群操作员应注意的区域的可视性,以确保他们不会无意中允许比预期更多的集群访问权限。
列出机密
通常很清楚,允许对机密的 get
访问权限将允许用户读取其内容。同样重要的是要注意,list
和 watch
访问权限实际上也允许用户泄露机密内容。例如,当返回列表响应时(例如,通过 kubectl get secrets -A -o yaml
),响应包括所有机密的内容。
工作负载创建
在命名空间中创建工作负载(Pod 或 管理 Pod 的工作负载资源)的权限隐式授予对该命名空间中许多其他资源的访问权限,例如可以在 Pod 中挂载的机密、ConfigMap 和持久卷。此外,由于 Pod 可以以任何 服务帐户 运行,因此授予创建工作负载的权限也隐式授予该命名空间中任何服务帐户的 API 访问级别。
可以运行特权 Pod 的用户可以使用该访问权限来获得节点访问权限,并可能进一步提升其特权。如果您不完全信任用户或其他主体创建足够安全和隔离的 Pod 的能力,您应该执行 **基线** 或 **受限** Pod 安全标准。您可以使用 Pod 安全准入控制 或其他(第三方)机制来实施该执行。
出于这些原因,应使用命名空间来隔离需要不同信任级别或租户的资源。仍然被认为是最佳实践遵循 最小特权 原则,并分配最少权限集,但应将命名空间内的边界视为薄弱环节。
持久卷创建
如果有人(或某个应用程序)被允许创建任意持久卷,则该访问权限包括创建 hostPath
卷,这将意味着 Pod 将获得对关联节点上底层主机文件系统(s)的访问权限。授予该能力是一个安全风险。
具有对主机文件系统的无限制访问权限的容器可以通过多种方式升级特权,包括读取其他容器中的数据,以及滥用系统服务的凭据,例如 Kubelet。
您应该只允许访问为以下人员创建持久卷对象:
- 需要此访问权限以完成工作的用户(集群操作员),并且您信任他们。
- 基于为自动供应配置的持久卷声明创建持久卷的 Kubernetes 控制平面组件。这通常由 Kubernetes 提供商或在安装 CSI 驱动程序时由操作员进行设置。
在需要持久存储访问权限的情况下,受信任的管理员应创建持久卷,受限用户应使用持久卷声明来访问该存储。
访问节点的 proxy
子资源
有权访问节点对象的 proxy 子资源的用户具有对 Kubelet API 的权限,这允许在他们有权访问的节点上的所有 Pod 上执行命令。此访问权限会绕过审计日志记录和准入控制,因此在授予对此资源的权限之前应谨慎。
升级动词
通常,RBAC 系统会阻止用户创建比用户拥有的权限更多的集群角色。对此的例外是 escalate
动词。如 RBAC 文档 中所述,拥有此权限的用户可以有效地升级其特权。
绑定动词
与 escalate
动词类似,授予用户此权限将允许绕过 Kubernetes 内置的特权升级保护,允许用户创建绑定到他们没有的权限的角色。
模拟动词
此动词允许用户模拟集群中其他用户的身份并获得其权限。在授予此权限时应谨慎,以确保无法通过其中一个模拟帐户获得过多的权限。
CSR 和证书签发
CSR API 允许拥有 CSR 的 create
权限的用户和 certificatesigningrequests/approval
的 update
权限(其中签名者为 kubernetes.io/kube-apiserver-client
)来创建新的客户端证书,这些证书允许用户对集群进行身份验证。这些客户端证书可以具有任意名称,包括 Kubernetes 系统组件的重复名称。这将有效地允许特权升级。
令牌请求
对 serviceaccounts/token
拥有 create
权限的用户可以创建令牌请求来为现有服务帐户发出令牌。
控制准入 Webhook
控制 validatingwebhookconfigurations
或 mutatingwebhookconfigurations
的用户可以控制可以读取任何被准入到集群中的对象的 Webhook,并且在 mutating Webhook 的情况下,还可以修改被准入的对象。
命名空间修改
拥有对命名空间对象执行 **修补** 操作权限的用户(通过命名空间内的 RoleBinding 与具有该访问权限的 Role 绑定)可以修改该命名空间的标签。在使用 Pod 安全准入的集群中,这可能允许用户为命名空间配置比管理员预期的更宽松的策略。在使用 NetworkPolicy 的集群中,用户可能被设置了间接允许访问管理员原本不允许访问的服务的标签。
Kubernetes RBAC - 拒绝服务风险
对象创建拒绝服务
拥有在集群中创建对象的权限的用户可能能够创建足够大的对象,以根据对象的大小或数量创建拒绝服务条件,如 Kubernetes 使用的 etcd 易受 OOM 攻击 中所述。这在多租户集群中可能特别相关,如果允许半信任或不受信任的用户有限访问系统。
缓解此问题的其中一种方法是使用 资源配额 来限制可创建的对象数量。
下一步
- 要了解更多关于 RBAC 的信息,请参阅 RBAC 文档。