Sooua
登录
返回文章列表
云原生安全··12 分钟阅读

Kubernetes 准入控制与 RBAC 的实战加固:从权限爆炸到策略即代码

OWASP Kubernetes Top 10 2025 将'过度 RBAC 权限'和'不严格的工作负载权限'列为前两位风险。本文从真实集群的权限审计出发,深入分析 Kubernetes RBAC 的隐性风险、准入控制器的工程化部署,以及策略即代码(Policy as Code)在持续交付中的落地实践。

一、被低估的权限面:一个真实集群的 RBAC 审计

2025 年 OWASP 发布的 Kubernetes Top 10 中,K03"过度 RBAC 权限"(Overly Permissive RBAC)位列第三[^4],但笔者在多个企业集群的安全评估中发现,这个问题的实际危害往往被严重低估。原因有二:一是 RBAC 的权限继承和聚合机制复杂,人工审计极易遗漏;二是 Kubernetes 的默认配置倾向于"宽松"而非"严格",以降低上手门槛。

以下是一个经过脱敏处理的真实集群 RBAC 审计结果(基于 kubectl auth can-i --listrakkess 工具输出):

# 审计 default namespace 内所有 ServiceAccount 的权限
$ rakkess -n default --sa
 
NAME               CREATE  DELETE  DELETECOLLECTION  GET  LIST  UPDATE  BIND  ESCALATE
app-backend        
app-frontend       
ci-deployer        
monitoring-agent   

问题立即显现:ci-deployer ServiceAccount 拥有 bindescalate 权限,这意味着它可以将任意 Role/ClusterRole 绑定到自身或其他主体,包括 cluster-admin。这相当于在集群中放置了一个"权限放大器"——任何能够冒充 ci-deployer 的攻击者都可以瞬间获取集群完全控制权。

app-backendmonitoring-agent 的问题同样严重:它们拥有对 secrets 资源的 deletecollection 权限,可以批量删除 namespace 内的所有 Secret。在生产环境中,这不仅是数据丢失风险,更可能因为误删 TLS 证书或数据库凭据导致级联故障。

Kubernetes 官方 RBAC 最佳实践文档明确警告:应避免使用通配符权限(*)、避免授予 escalatebind 权限、最小化 createdelete 的适用范围[^2]。但在实际工程中,这些原则常常被以下因素破坏:

  1. "先跑起来再优化"的交付压力:开发团队为了快速上线,直接套用社区 Helm Chart 的默认 RBAC 配置
  2. 权限需求的模糊性:"这个服务可能需要访问 ConfigMap" → 实际授予了对所有资源的读写权限
  3. 缺乏持续审计机制:RBAC 配置是一次性设置的,后续的权限膨胀无人追踪

二、RBAC 的隐性风险:从通配符到令牌泄露

RBAC 的风险不只是"权限给多了"这么简单。Kubernetes 的权限模型有几个容易被忽视的设计特性,这些特性在攻击者的手中会变成权限提升的阶梯。

2.1 通配符的级联效应

以下是一个常见的"开发友好型"Role 定义:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer-role
  namespace: dev
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]

表面上这只是"只读"权限,但 apiGroups: ["*"]resources: ["*"] 的组合意味着该主体可以读取 namespace 内的所有资源类型,包括 Secret。如果开发者的 kubeconfig 泄露,攻击者可以读取所有数据库密码、API 密钥和 TLS 私钥。

更隐蔽的是,pods/exec 资源属于 core API group,如果 Role 中包含了 pods/*resources: ["*"],则意味着可以执行 kubectl exec 进入任意容器。这在只读权限的语义下是完全不可预期的——用户以为自己只能"看",实际上可以"执行"。

2.2 ServiceAccount 令牌的持久性与可投射性

Kubernetes 1.24 之前,ServiceAccount 会自动创建一个长期有效的 Secret 令牌。1.24 之后默认关闭了这一行为,但许多集群为了兼容性仍然保留了旧的令牌机制。这些令牌一旦泄露,其有效期与 ServiceAccount 的生命周期绑定,没有自动轮换机制。

即使使用了较新的 TokenRequest API(短期令牌),如果 Pod 的 serviceAccountToken 投射配置不当,攻击者仍可能通过文件系统读取 /var/run/secrets/kubernetes.io/serviceaccount/token 获取有效凭据。

2.3 危险的 ClusterRole:system:discovery 与 system:basic-user

Kubernetes 默认创建了一些"看似无害"的 ClusterRole,但在特定场景下可以被攻击者利用:

  • system:discovery:允许匿名用户或任何认证用户访问 /api/apis 端点。这泄露了集群的 API 版本和资源类型信息,是攻击者进行侦察的第一步。
  • system:basic-user:允许用户访问 SelfSubjectAccessReviewSelfSubjectRulesReview API。攻击者可以利用这些 API 自动化地枚举自己的权限,制定精准的权限提升路径。

微软 2025 年发布的 Kubernetes API Server 威胁矩阵明确将这些默认配置列为初始访问阶段的攻击面[^8]。建议在非开发环境中移除匿名用户的 system:discovery 绑定。

三、准入控制:在请求到达 etcd 之前的最后防线

RBAC 解决的是"谁可以做什么",准入控制(Admission Control)解决的是"做了什么之后是否合规"。RBAC 授权发生在 API Server 收到请求之后、写入 etcd 之前;准入控制则是在授权之后、持久化之前插入的一层"策略校验"。

准入控制器分为两类:

  • Mutating:可以修改请求内容。例如自动为没有资源限制的 Pod 注入默认的 resources.requestsresources.limits
  • Validating:只能批准或拒绝请求,不能修改。例如拒绝所有以 latest 为镜像标签的 Pod,或拒绝特权容器(privileged containers)。

3.1 内置准入控制器:Pod Security

从 Kubernetes 1.25 起,Pod Security Policies(PSP)被移除,取而代之的是内置的 Pod Security admission 控制器[^7]。它定义了三个安全级别:

级别限制程度适用场景
Privileged无限制系统级基础设施,如 CNI、CSI
Baseline防止已知的特权提升大多数应用工作负载
Restricted遵循 Pod 强化最佳实践安全敏感的多租户环境

在 Namespace 级别启用策略:

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

这一配置的工程价值在于零侵入 enforcement:应用开发者不需要修改任何 YAML,不合规的 Pod 提交会被 API Server 直接拒绝。auditwarn 模式允许在强制启用前进行灰度验证,观察哪些现有工作负载会触发策略违规。

然而,Pod Security admission 的局限也很明显:它只覆盖 Pod 和 PodTemplate 资源,无法对 Deployment、ServiceAccount、NetworkPolicy 等其他资源进行策略约束。对于更复杂的场景,需要引入外部准入控制器。

3.2 Kyverno:Kubernetes 原生的策略引擎

Kyverno 是一个 CNCF 沙箱项目,其最大特点是"Kubernetes 原生"——策略使用 Kubernetes 风格的 YAML 编写,无需学习 Rego 或其他 DSL[^5]。

以下是一个 Kyverno 策略示例,强制要求所有 Pod 必须指定资源限制,并且镜像必须来自内部仓库:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resources-and-registry
spec:
  validationFailureAction: Enforce
  rules:
  - name: check-resources
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Pod must specify CPU/memory requests and limits"
      pattern:
        spec:
          containers:
          - resources:
              requests:
                memory: "?*"
                cpu: "?*"
              limits:
                memory: "?*"
                cpu: "?*"
  - name: check-registry
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Only internal registry images are allowed"
      pattern:
        spec:
          containers:
          - image: "registry.internal.company.com/*"

Kyverno 的 validationFailureAction: Enforce 意味着策略违规会导致请求被直接拒绝;如果设为 Audit,则只会记录违规事件而不阻止请求。这种灵活的模式支持渐进式策略 rollout——先在审计模式下观察影响,再切换为强制模式。

Kyverno 还支持 mutategenerate 规则:

  • mutate:自动修改资源,如为缺少标签的 Namespace 注入团队标签
  • generate:自动创建关联资源,如在创建 Namespace 时自动生成默认 NetworkPolicy 和 ResourceQuota

3.3 OPA Gatekeeper:复杂策略的首选

当策略逻辑超出 YAML 的表达能力时,OPA Gatekeeper 是更强大的选择[^6]。它基于 Open Policy Agent(OPA)和 Rego 语言,支持复杂的条件判断、数据查询和外部数据源集成。

一个典型的 Gatekeeper 应用场景是"多租户隔离策略":确保每个 Namespace 的 ResourceQuota 总和不超过集群总容量的 80%,且每个 Pod 的 securityContext 必须满足特定条件(如 runAsNonRoot: truereadOnlyRootFilesystem: true)。

# Rego 策略示例:禁止 privileged 容器
package k8spspprivileged
 
violation[{"msg": msg}] {
  container := input.review.object.spec.containers[_]
  container.securityContext.privileged
  msg := sprintf("Privileged container is not allowed: %v", [container.name])
}

Gatekeeper 的约束模板(ConstraintTemplate)和约束(Constraint)两层模型,使得平台团队可以定义通用的策略模板,而应用团队只需实例化具体的约束。这种分离符合大型组织的治理需求。

四、策略即代码:将安全左移到 CI/CD

准入控制器解决了"运行时"的策略执行,但安全左移(Shift Left)要求策略在代码提交和构建阶段就被验证。策略即代码(Policy as Code)的核心思想是:将安全策略定义为版本控制的代码,通过 CI/CD 流水线自动验证。

4.1 Trivy 在 CI/CD 中的集成

Trivy 支持对 Kubernetes YAML、Helm Charts、Kustomize 配置进行静态扫描[^8]。在 CI 流水线中集成 Trivy 可以在资源部署到集群之前发现配置缺陷:

# GitLab CI 示例
stages:
  - security-scan
 
k8s-config-scan:
  stage: security-scan
  image: aquasec/trivy:latest
  script:
    - trivy config --severity HIGH,CRITICAL --exit-code 1 ./k8s/
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

Trivy 的 config 子命令会检查 Kubernetes 资源是否符合 CIS Benchmark 和最佳实践,如:

  • Pod 是否以 root 用户运行
  • Secret 是否以环境变量而非文件挂载方式传递
  • NetworkPolicy 是否定义了默认拒绝规则
  • 容器镜像是否使用了不可变标签(非 latest

4.2 准入控制与 CI/CD 的闭环

理想的安全闭环是:CI 阶段的 Trivy 扫描负责"预防已知问题",运行时准入控制负责"拦截未知违规",两者互补而非替代。

在这一架构中,安全策略被定义在三个层级:

  1. CI 门禁层(Trivy):扫描配置文件的静态合规性,阻塞已知的高危配置进入版本库
  2. 准入控制层(Kyverno/Gatekeeper):在部署时强制执行策略,拦截任何绕过 CI 扫描的违规请求
  3. 运行时监控层(Falco):检测运行中的异常行为,如特权提升、敏感文件访问、反向 shell 等[^9]

三层策略的定义应保持一致:如果 CI 扫描要求 Pod 必须设置 resources.limits,那么准入控制器也应强制同一规则,运行时监控则应告警资源使用量异常。这种一致性避免了"策略漂移"——即不同层级的安全要求相互矛盾或存在 gaps。

五、检测工程:RBAC 变更与异常行为的可观测性

准入控制防止了违规配置的进入,但安全运营还需要回答"谁改了什么"和"发生了什么异常"。Kubernetes 的审计日志(Audit Logs)是这一需求的基础数据源。

5.1 审计策略配置

以下是一个生产级的审计策略示例,重点记录 RBAC 变更、Secret 访问和特权操作:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: RequestResponse
    resources:
      - group: rbac.authorization.k8s.io
        resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
    omitStages:
      - RequestReceived
 
  - level: RequestResponse
    resources:
      - group: ""
        resources: ["secrets", "configmaps"]
    omitStages:
      - RequestReceived
 
  - level: Metadata
    resources:
      - group: ""
        resources: ["pods"]
    verbs: ["create", "update", "patch", "delete"]
    omitStages:
      - RequestReceived
 
  - level: None
    resources:
      - group: ""
        resources: ["events", "endpoints", "endpointslices"]

这一策略的关键设计是差异化记录级别:RBAC 和 Secret 访问记录完整的 Request/Response 内容,Pod 生命周期变更记录 Metadata(不含请求体,减少日志量),高频低敏事件(如 events)不记录。

5.2 关键检测规则

基于审计日志,可以构建以下检测规则:

检测场景审计日志特征告警级别
RBAC 权限提升创建/更新 RoleBinding/ClusterRoleBinding,绑定高权限角色Critical
Secret 批量导出短时间内大量 get secrets 请求,或 get secret 后接 list podsHigh
特权 Pod 创建创建包含 privileged: truehostNetwork: true 的 PodHigh
ServiceAccount 令牌异常使用非预期源 IP 使用 ServiceAccount Token 访问 API ServerHigh
匿名访问 APIuser.name="system:anonymous" 且非 /healthz 端点Medium

这些规则可以通过 Falco 的 Kubernetes 审计插件或 SIEM 的日志关联功能实现。Falco 的优势在于它将审计日志与系统调用监控关联,可以检测"从 API 操作到容器内执行"的完整攻击链[^9]。

六、最小可行加固:四周落地路线图

对于尚未建立 K8s 安全体系的企业,以下是一个可落地的四周路线图:

第一周: visibility

  • 使用 rakkesskubectl access-matrix 审计所有 ServiceAccount 的 RBAC 权限
  • 启用 API Server 审计日志,配置差异化记录策略
  • 部署 Falco 或类似工具,建立运行时行为基线

第二周: hardening

  • 移除匿名用户的 system:discovery 绑定
  • 为所有 Namespace 启用 Pod Security admission(从 warn 模式开始)
  • 扫描并清理通配符权限(*),替换为明确的资源列表

第三周: policy

  • 部署 Kyverno 或 Gatekeeper,实施 3-5 条核心策略(如强制资源限制、限制镜像来源、禁止 privileged 容器)
  • 在 CI/CD 中集成 Trivy 配置扫描,阻塞高危配置的合并请求

第四周: validation

  • 执行一次红队测试,验证 RBAC 和准入控制的有效性
  • 基于审计日志和 Falco 告警,调优检测规则的误报率
  • 建立月度 RBAC 审计和策略评审的 SOP

本文创建日期:2026-06-21 | 状态:draft | 标签:Kubernetes, RBAC, 准入控制, 云原生安全

分享

评论

登录 后参与讨论。

加载中…

相关文章