Kubernetes RBAC如何最小权限

wen 网络安全 2

本文目录导读:

Kubernetes RBAC如何最小权限

  1. 从“完全拒绝”开始,只做“加法”
  2. 使用特定的 API 组和资源
  3. 使用动词的精确性
  4. 合理选择 Role 还是 ClusterRole
  5. 使用 Aggregated ClusterRole
  6. 特别注意 Secret 的权限
  7. 使用 SubjectAccessReview(SAR)进行审计
  8. 避免使用默认的 Cluster-Admin 和 Edit 角色
  9. 针对 ServiceAccount 的特殊管理
  10. 定期审计与自动化
  11. 实际示例:给 CI/CD 工具(如 Jenkins)最小权限
  12. 总结核心检查清单

Kubernetes RBAC(基于角色的访问控制)的最小权限原则核心是只授予一个身份(用户/ServiceAccount)完成其特定工作所需的最精确的操作(verbs)和资源(resources)

实现这个原则需要从角色定义角色绑定资源范围以及治理四个维度入手,以下是具体的最佳实践步骤:

从“完全拒绝”开始,只做“加法”

永远不要一开始就使用 通配符,不要给角色授予 (所有操作)或 get, list, watch, create, update, patch, delete 的全集。

  • 错误示例

    rules:
    - apiGroups: [“”]
      resources: [“pods”]
      verbs: [“*”]
  • 正确做法: 只列出必须的操作,如果某个组件只需要看日志(getlogs),就不要给 deletecreate

使用特定的 API 组和资源

避免使用 apiGroups: [“*”](匹配所有 API 组)。

  • 规则: 明确指定 apiGroups
    • 核心组:
    • Apps: “apps”
    • 批处理: “batch”
  • 子资源限制: 对于某些操作,需要指定子资源。
    • 查看日志resources: [“pods/log”],而不仅仅是 “pods”
    • 执行命令resources: [“pods/exec”]
    • 端口转发resources: [“pods/portforward”]

使用动词的精确性

动词的粒度决定了你能做什么,常见动词的权限范围如下:

动词 权限范围(结合get/list) 潜在风险
getlistwatch 读取 泄露敏感信息(如 Secret 内容)
updatepatch 修改 修改资源状态,如更改镜像、副本数
create 创建 创建新的 Pod/Service/Deployment
delete 删除 删除生产资源导致宕机
deletecollection 批量删除 毁灭性操作,通常应禁用

最小实践

  • 监控工具: 只需要 getlistwatch
  • CI/CD 部署工具: 对于 Deployment 需要 getlistupdatepatch;对于 Pod 可能只需要 getlist
  • 开发者调试: 只给 get 日志和 exec 进入容器的权限,不给 delete

合理选择 Role 还是 ClusterRole

  • Role(命名空间级别): 优先使用,绝大多数工作负载(如部署到某个 namespace 的应用)都应该使用 Role + RoleBinding
  • ClusterRole(集群级别): 仅在必要时使用。
    • 场景: 集群管理员、集群级别的监控(如查看所有 Node)、持久化卷(PV)管理、自定义资源定义(CRD)管理。
    • 注意: 即使使用 ClusterRole,也可以通过 RoleBinding 将其限制在特定 namespace 内(仅授予该 namespace 内资源的权限)。

使用 Aggregated ClusterRole

不要手动拼凑一堆权限,对于需要跨多个 API 组(如 apps/v1batch/v1networking.k8s.io/v1)的复杂角色(如“查看者”),使用聚合 ClusterRoleaggregationRule)。

  • 原理: 通过 Label Selector 自动组合多个 ClusterRole 的权限。
  • 示例
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: custom-viewer
      labels:
        rbac.example.com/aggregate-to-custom-viewer: “true”  # 关键标签
    rules: []  # 空规则,由聚合器填充
    ---
    # 其他 ClusterRole 添加该标签后会自动加入
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: pod-viewer
      labels:
        rbac.example.com/aggregate-to-custom-viewer: “true”
    rules:
    - apiGroups: [“”]
      resources: [“pods”]
      verbs: [“get”, “list”]

特别注意 Secret 的权限

Secret 是 Kubernetes 中最敏感的数据,任何能 getlist Secret 的角色,实际上都等于拥有了该 Secret 中所有明文密码和 Token。

  • 最小原则: 除非绝对必要,否则不要在角色中包含对 secrets 资源的 getlistwatch 权限。
  • 替代方案: 如果应用需要读取挂载的 Secret,使用 Volume 挂载或环境变量注入(由 Kubelet 自动完成,不需要 RBAC 权限)。

使用 SubjectAccessReview(SAR)进行审计

在将新权限授予生产集群之前,可以使用 kubectl auth can-i 命令模拟检查。

# 检查用户 “dev-user” 能否在 namespace “prod” 中删除 Pod
kubectl auth can-i delete pods --as=dev-user --namespace=prod
# 检查 ServiceAccount “my-sa” 能否创建 Deployment
kubectl auth can-i create deployments --as=system:serviceaccount:my-ns:my-sa

避免使用默认的 Cluster-Admin 和 Edit 角色

  • cluster-admin永远不要直接绑定到用户或 ServiceAccount,除非是全职集群管理员。
  • edit: 不要直接绑定给开发者,因为它包含创建/修改 Secret、RBAC 规则的能力。
  • view: 相对安全,但会暴露所有 Pod 内的环境变量(可能含敏感信息)。

针对 ServiceAccount 的特殊管理

  • Docker 镜像拉取: 如果使用 imagePullSecrets,通常不需要给 ServiceAccount 额外权限(权限在 Secret 中)。
  • 自动化工具(如 Helm、ArgoCD): 为每个应用或每个环境独立创建 ServiceAccount,不要共享一个“万能” Account。
  • 自动挂载: 对于不需要与 API Server 通信的 Pod,显式设置 automountServiceAccountToken: false

定期审计与自动化

  • 工具
    • kubectl describe clusterrolebinding <name>:查看谁拥有什么权限。
    • 通用工具kubectl audit(Beta 功能)、kubectl rbac-lookup(第三方)或 kubectl neat 导出资源。
    • 策略引擎: OPA(Open Policy Agent)或 Kyverno,可以强制要求 RBAC 必须遵循最小权限(禁止使用通配符动词)。

实际示例:给 CI/CD 工具(如 Jenkins)最小权限

目标: 允许在 namespace app-team 中创建 Deployment、管理 Pod,但不能删除资源或修改 Secret。

创建 Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: app-team
  name: deployer
rules:
# 管理 Deployment
- apiGroups: [“apps”]
  resources: [“deployments”, “deployments/scale”]
  verbs: [“get”, “list”, “watch”, “update”, “patch”]  # 没有 delete 和 create(除非需要)
# 查看 Pod 状态和日志(便于调试)
- apiGroups: [“”]
  resources: [“pods”, “pods/log”]
  verbs: [“get”, “list”, “watch”]
# 允许更新 Service(但最好不要创建)
- apiGroups: [“”]
  resources: [“services”]
  verbs: [“get”, “list”, “watch”, “update”, “patch”]
# **没有 secrets 权限** - Jenkins 需要读取 Secret,使用 Volume 挂载或通过其他更安全的方式

绑定 ServiceAccount

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: jenkins-deployer
  namespace: app-team
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: deployer
subjects:
- kind: ServiceAccount
  name: jenkins-sa
  namespace: app-team

总结核心检查清单

检查项 行为 理由
1 避免 verbs: [“*”] 你是业务组件,不是管理员。
2 避免 apiGroups: [“*”] 不需要接触 autoscalingbatchnetworking
3 避免 resources: [“*”] 不需要影响 Secrets, Endpoints 或 Events。
4 必须显式定义 namespaced 的 Role 永远优先用 Role 而不是 ClusterRole。
5 针对敏感资源 对 Secret, ConfigMap 的 deletecreate 需特别审批。
6 定期审计 使用 kubectl describe role <role> 查看实际权限。

按这套方法实施,可以显著降低因 RBAC 配置不当导致的安全风险(如 Pod 被创建恶意容器、Secret 泄露、或横向移动权限提升)。

抱歉,评论功能暂时关闭!