LabHub
学习 学习路径 课程

KCSA — Kubernetes 安全助理

全集群的 RBAC 审计

在 LabHub 中继续学习

目标

实际审计整个集群的 RBAC。找出拥有通配符权限和危险动词的 ClusterRole,用 kubectl auth can-i 测量 ServiceAccount 的有效权限,创建新的最小权限 Role 并证明边界确实生效,最后编写包含证据的审计报告。

为什么重要

RBAC 审计困难,是因为只阅读清单无法得到最终答案。一个主体可能绑定多个角色、通过组继承权限,内置 ClusterRole 还可能通过 aggregation 合并。不要在脑中计算,直接询问 apiserver。kubectl auth can-i --list --as= 就是这个工具。

单独统计通配符是有原因的。resources: ["*"] 不只允许当前资源,还允许未来通过 CRD 添加的资源。因此“现在是安全的”并不能成为反驳理由。

escalatebindimpersonate 是尤其危险的元权限。这些动词代表“授予权限的权限”,只要拥有其中一项,就可能把自己变成管理员。它们是 RBAC 审计首先应查找的对象。

最后是第 6 步。最小权限不是“给了所需权限”,而是**“不需要的权限确实不可用”**。只确认可以读取就结束,只完成了一半。还要确认无法删除、无法跨命名空间操作,才能证明边界。

步骤

  1. 创建目录 /root/kcsa-audit 和命名空间 kcsa-audit,在该命名空间创建两个 ServiceAccount:auditorprobe。本步骤中不要给它们绑定任何权限。
  2. 在集群所有 ClusterRole 中,找出同一条规则内 verbsresources 都为 * 的角色,将名称逐行保存到 /root/kcsa-audit/wildcard-clusterroles.txt
  3. 执行 kubectl auth can-i --list,并使用 --as=system:serviceaccount:kcsa-audit:probe-n kcsa-audit,将全部输出不经处理地原样保存到 /root/kcsa-audit/probe-can-i.txtprobe 是实验结束前都不绑定任何角色的对照基线,之后也不能给它权限。
  4. 在集群所有 ClusterRole 中,找出 verbs逐字包含任意一个 escalatebindimpersonate 的角色,将名称逐行保存到 /root/kcsa-audit/dangerous-verbs.txt
  5. system:serviceaccount:kcsa-audit:default 询问三项权限,将结果保存到 /root/kcsa-audit/default-sa.txt,内容为三行 키=값create-pods=(在命名空间 kcsa-audit 中 create Pod)、get-secrets=(在命名空间 kcsa-audit 中 get secrets)、list-nodes=(集群范围 list nodes)。值原样填写 yes/no
  6. 在命名空间 kcsa-audit 中创建 Role configmap-reader:规则正好一条,apiGroups 只有核心组,resources 只有 configmaps,verbs 只有 getlistwatch。再通过 RoleBinding auditor-configmap-reader 绑定给 SA auditor。创建后用 auth can-i 确认:(a) 能在 kcsa-audit 中 list configmaps;(b) 不能在同处 delete;(c) 在 default 命名空间连 list 也不能执行。
  7. 编写 /root/kcsa-audit/rbac-audit-report.md。以下四行必须原样作为章节标题:## 와일드카드 권한## 위험 동사## 기본 서비스어카운트## 최소 권한 적용。正文必须提到以下五个词:cluster-adminescalateimpersonateconfigmap-readerauditor。并以一行 wildcard-count=<숫자> 写入第 2 步统计的通配符 ClusterRole 数量。

参考

准备审计工作区

创建目录 /root/kcsa-audit 和命名空间 kcsa-audit,在该命名空间创建两个 ServiceAccount:auditorprobe。本步骤中不要给它们绑定任何权限。

创建产物目录、命名空间和两个 ServiceAccount。一个稍后接收最小权限角色,另一个始终不获得权限,作为对照基线。没有基线,就无法说明“权限增加了”。

查找拥有通配符权限的 ClusterRole

在集群所有 ClusterRole 中,找出同一条规则内 verbsresources 都为 * 的角色,将名称逐行保存到 /root/kcsa-audit/wildcard-clusterroles.txt

查找同一条规则中 verbs 和 resources 都为 * 的情况。rules 是数组,一个 ClusterRole 可能有多条;只要任一条满足条件,就把角色加入列表。组合 jq 的 select 和 any 可一行完成。

记录无权限 ServiceAccount 的基线

执行 kubectl auth can-i --list,并使用 --as=system:serviceaccount:kcsa-audit:probe-n kcsa-audit,将全部输出不经处理地原样保存到 /root/kcsa-audit/probe-can-i.txtprobe 是实验结束前都不绑定任何角色的对照基线,之后也不能给它权限。

auth can-i 除逐项询问外,也能输出完整列表。用 --as 指定主体,并带 -n 查看命名空间范围权限。不要用 grep 或排序处理输出,直接原样保存。这些行就是“无权限账户”的基线,始终不要给它绑定角色。

检测拥有危险动词的 ClusterRole

在集群所有 ClusterRole 中,找出 verbs逐字包含任意一个 escalatebindimpersonate 的角色,将名称逐行保存到 /root/kcsa-audit/dangerous-verbs.txt

回想三个动词各自允许什么,就能理解为何一起检查。这里只统计逐字写出的动词;通配符已经在前一步单独统计。

默认 ServiceAccount 能做什么

system:serviceaccount:kcsa-audit:default 询问三项权限,将结果保存到 /root/kcsa-audit/default-sa.txt,内容为三行 키=값create-pods=(在命名空间 kcsa-audit 中 create Pod)、get-secrets=(在命名空间 kcsa-audit 中 get secrets)、list-nodes=(集群范围 list nodes)。值原样填写 yes/no

每个命名空间都会自动拥有 default ServiceAccount,Pod 未指定 SA 时就使用它。请直接询问该账户能做什么并原样转录答案。查询集群范围资源时无需命名空间选项。

创建最小权限 Role 并证明边界

在命名空间 kcsa-audit 中创建 Role configmap-reader:规则正好一条,apiGroups 只有核心组,resources 只有 configmaps,verbs 只有 getlistwatch。再通过 RoleBinding auditor-configmap-reader 绑定给 SA auditor。创建后用 auth can-i 确认:(a) 能在 kcsa-audit 中 list configmaps;(b) 不能在同处 delete;(c) 在 default 命名空间连 list 也不能执行。

一条规则中只放必要权限。核心 API 组名称是空字符串。创建后不仅要确认所需操作可用,还要确认不需要的操作不可用,尤其是在其他命名空间不可用,才能称为最小权限。

汇总成审计报告

编写 /root/kcsa-audit/rbac-audit-report.md。以下四行必须原样作为章节标题:## 와일드카드 권한## 위험 동사## 기본 서비스어카운트## 최소 권한 적용。正文必须提到以下五个词:cluster-adminescalateimpersonateconfigmap-readerauditor。并以一行 wildcard-count=<숫자> 写入第 2 步统计的通配符 ClusterRole 数量。

根据前面步骤的产物编写一份文档。章节标题必须保持指定形式,还要有一行以数字写出第 2 步的统计数量;评分时会重新计算并比较。