全集群的 RBAC 审计
目标
实际审计整个集群的 RBAC。找出拥有通配符权限和危险动词的 ClusterRole,用 kubectl auth can-i 测量 ServiceAccount 的有效权限,创建新的最小权限 Role 并证明边界确实生效,最后编写包含证据的审计报告。
为什么重要
RBAC 审计困难,是因为只阅读清单无法得到最终答案。一个主体可能绑定多个角色、通过组继承权限,内置 ClusterRole 还可能通过 aggregation 合并。不要在脑中计算,直接询问 apiserver。kubectl auth can-i --list --as= 就是这个工具。
单独统计通配符是有原因的。resources: ["*"] 不只允许当前资源,还允许未来通过 CRD 添加的资源。因此“现在是安全的”并不能成为反驳理由。
escalate、bind、impersonate 是尤其危险的元权限。这些动词代表“授予权限的权限”,只要拥有其中一项,就可能把自己变成管理员。它们是 RBAC 审计首先应查找的对象。
最后是第 6 步。最小权限不是“给了所需权限”,而是**“不需要的权限确实不可用”**。只确认可以读取就结束,只完成了一半。还要确认无法删除、无法跨命名空间操作,才能证明边界。
步骤
- 创建目录
/root/kcsa-audit和命名空间kcsa-audit,在该命名空间创建两个 ServiceAccount:auditor和probe。本步骤中不要给它们绑定任何权限。 - 在集群所有 ClusterRole 中,找出同一条规则内
verbs和resources都为*的角色,将名称逐行保存到/root/kcsa-audit/wildcard-clusterroles.txt。 - 执行
kubectl auth can-i --list,并使用--as=system:serviceaccount:kcsa-audit:probe和-n kcsa-audit,将全部输出不经处理地原样保存到/root/kcsa-audit/probe-can-i.txt。probe是实验结束前都不绑定任何角色的对照基线,之后也不能给它权限。 - 在集群所有 ClusterRole 中,找出
verbs中逐字包含任意一个escalate、bind、impersonate的角色,将名称逐行保存到/root/kcsa-audit/dangerous-verbs.txt。 - 以
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。 - 在命名空间
kcsa-audit中创建 Roleconfigmap-reader:规则正好一条,apiGroups 只有核心组,resources 只有configmaps,verbs 只有get、list、watch。再通过 RoleBindingauditor-configmap-reader绑定给 SAauditor。创建后用auth can-i确认:(a) 能在kcsa-audit中 list configmaps;(b) 不能在同处 delete;(c) 在default命名空间连 list 也不能执行。 - 编写
/root/kcsa-audit/rbac-audit-report.md。以下四行必须原样作为章节标题:## 와일드카드 권한、## 위험 동사、## 기본 서비스어카운트、## 최소 권한 적용。正文必须提到以下五个词:cluster-admin、escalate、impersonate、configmap-reader、auditor。并以一行wildcard-count=<숫자>写入第 2 步统计的通配符 ClusterRole 数量。
参考
- 使用
kubectl get clusterroles -o json | jq -r '.items[] | ... | .metadata.name'形式提取很方便。组合select和any遍历规则数组。 - 有些规则(如非资源 URL 规则)完全没有
verbs或resources,使用// []等默认值处理更安全。 - 核心 API 组名称是空字符串(
"")。 - 常见错误 1:第 2 步把只有
verbs为*的角色也包含进来。两个条件必须在同一条规则中同时满足。 - 常见错误 2:第 3 步用 grep 或排序处理后再保存。评分会重新执行同一命令比较,因此必须原样保存。
- 常见错误 3:第 6 步把 RoleBinding 目标设为
probe。probe是基线,一旦获得权限,第 3 步会再次失败。Role 应绑定给auditor。
准备审计工作区
创建目录 /root/kcsa-audit 和命名空间 kcsa-audit,在该命名空间创建两个 ServiceAccount:auditor 和 probe。本步骤中不要给它们绑定任何权限。
创建产物目录、命名空间和两个 ServiceAccount。一个稍后接收最小权限角色,另一个始终不获得权限,作为对照基线。没有基线,就无法说明“权限增加了”。
查找拥有通配符权限的 ClusterRole
在集群所有 ClusterRole 中,找出同一条规则内 verbs 和 resources 都为 * 的角色,将名称逐行保存到 /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.txt。probe 是实验结束前都不绑定任何角色的对照基线,之后也不能给它权限。
auth can-i 除逐项询问外,也能输出完整列表。用 --as 指定主体,并带 -n 查看命名空间范围权限。不要用 grep 或排序处理输出,直接原样保存。这些行就是“无权限账户”的基线,始终不要给它绑定角色。
检测拥有危险动词的 ClusterRole
在集群所有 ClusterRole 中,找出 verbs 中逐字包含任意一个 escalate、bind、impersonate 的角色,将名称逐行保存到 /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 只有 get、list、watch。再通过 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-admin、escalate、impersonate、configmap-reader、auditor。并以一行 wildcard-count=<숫자> 写入第 2 步统计的通配符 ClusterRole 数量。
根据前面步骤的产物编写一份文档。章节标题必须保持指定形式,还要有一行以数字写出第 2 步的统计数量;评分时会重新计算并比较。