审计 Kubernetes 集群 RBAC 配置,识别过度宽松的角色、通配符权限、危险的 ClusterRoleBinding 及服务账号滥用
审计 Kubernetes Club RBAC.是一项面向实际任务的技能,主要用于When to Use. 当对Kubernetes Club(EKS、GKE、AKS或自我管理)进行安全评估时;当验证RBAC的政策执行最少的特权时。
从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;
若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。
不适用于网络策略审计(请使用 Cilium 或 Calico 网络策略工具)、容器镜像扫描(请使用 Trivy 或 Grype)或运行时安全监控(请使用 Falco 或 Sysdig Secure)。
kubectl krew install rbac-tool,或从 GitHub 下载二进制文件)pip install kubiscan)brew install kubeaudit,或从 GitHub Releases 下载)识别包含通配符权限、Secret 访问权限、Pod exec 权限或权限提升能力的角色。
# 列出所有具有通配符动词权限的 ClusterRole
kubectl get clusterroles -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for role in data['items']:
name = role['metadata']['name']
for rule in role.get('rules', []):
verbs = rule.get('verbs', [])
resources = rule.get('resources', [])
if '*' in verbs or '*' in resources:
print(f'ClusterRole: {name}')
print(f' Verbs: {verbs}')
print(f' Resources: {resources}')
print(f' API Groups: {rule.get("apiGroups", [])}')
print()
"
# 查找可读取 Secret 的角色
kubectl get clusterroles -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for role in data['items']:
name = role['metadata']['name']
for rule in role.get('rules', []):
resources = rule.get('resources', [])
verbs = rule.get('verbs', [])
if ('secrets' in resources or '*' in resources) and ('get' in verbs or 'list' in verbs or '*' in verbs):
if not name.startswith('system:'):
print(f'ClusterRole: {name} -> can access secrets (verbs: {verbs})')
"
# 查找具有 pod/exec 权限的角色(存在容器逃逸风险)
kubectl get clusterroles -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for role in data['items']:
name = role['metadata']['name']
for rule in role.get('rules', []):
resources = rule.get('resources', [])
if 'pods/exec' in resources or 'pods/*' in resources:
print(f'ClusterRole: {name} -> has pods/exec access')
"
审查绑定关系,识别拥有高权限访问的主体,并检测范围过宽的组分配。
# 列出所有 ClusterRoleBinding 及其绑定主体
kubectl get clusterrolebindings -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for binding in data['items']:
name = binding['metadata']['name']
role = binding['roleRef']['name']
subjects = binding.get('subjects', [])
for subject in subjects:
kind = subject.get('kind', '')
subj_name = subject.get('name', '')
ns = subject.get('namespace', 'cluster-wide')
print(f'{name} -> Role: {role} | {kind}: {subj_name} ({ns})')
" | sort
# 查找绑定至 cluster-admin 的 ClusterRoleBinding
kubectl get clusterrolebindings -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for binding in data['items']:
if binding['roleRef']['name'] == 'cluster-admin':
print(f"Binding: {binding['metadata']['name']}")
for subject in binding.get('subjects', []):
print(f" {subject.get('kind')}: {subject.get('name')} (ns: {subject.get('namespace', 'N/A')})")
"
# 查找向所有已认证用户授予权限的绑定
kubectl get clusterrolebindings -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for binding in data['items']:
for subject in binding.get('subjects', []):
if subject.get('name') in ['system:authenticated', 'system:unauthenticated']:
print(f"WARNING: {binding['metadata']['name']} grants {binding['roleRef']['name']} to {subject['name']}")
"
利用 rbac-tool 自动化执行 RBAC 分析,包括 who-can 查询及策略生成。
# 查询跨所有命名空间可读取 Secret 的主体 kubectl rbac-tool who-can get secrets # 查询可创建 Pod 的主体(存在容器逃逸风险) kubectl rbac-tool who-can create pods # 查询可 exec 进入 Pod 的主体 kubectl rbac-tool who-can create pods/exec # 查询可提升权限的主体(bind/escalate 动词) kubectl rbac-tool who-can bind clusterroles kubectl rbac-tool who-can escalate clusterroles # 生成 RBAC 策略分析报告 kubectl rbac-tool analysis # 可视化 RBAC 关系图 kubectl rbac-tool viz --outformat dot > rbac-graph.dot dot -Tpng rbac-graph.dot -o rbac-graph.png
使用 KubiScan 自动识别存在风险的服务账户、Pod 及 RBAC 配置。
# 运行 KubiScan 查找高危 Role python3 -m kubiscan -rroles # 列出高危 Role python3 -m kubiscan -rcr # 列出高危 ClusterRole python3 -m kubiscan -rrb # 列出高危 RoleBinding python3 -m kubiscan -rcrb # 列出高危 ClusterRoleBinding # 查找高危服务账户 python3 -m kubiscan -rs # 高危服务账户 # 查找使用高危服务账户运行的 Pod python3 -m kubiscan -rp # 高危 Pod # 检查权限提升路径 python3 -m kubiscan -pe # 权限提升向量 # 生成完整审计报告 python3 -m kubiscan -a # 执行全部检查项
检查是否存在不必要的服务账户 Token 挂载,此类配置可能在 Pod 被攻陷后导致横向移动。
# 查找启用自动挂载服务账户 Token 的 Pod
kubectl get pods --all-namespaces -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for pod in data['items']:
name = pod['metadata']['name']
ns = pod['metadata']['namespace']
sa = pod['spec'].get('serviceAccountName', 'default')
automount = pod['spec'].get('automountServiceAccountToken', True)
if automount and sa != 'default':
print(f'{ns}/{name} -> SA: {sa} (token auto-mounted)')
"
# 查找绑定非默认 Token Secret 的服务账户
kubectl get serviceaccounts --all-namespaces -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for sa in data['items']:
name = sa['metadata']['name']
ns = sa['metadata']['namespace']
secrets = sa.get('secrets', [])
if name != 'default' and len(secrets) > 0:
print(f'{ns}/{name}: {len(secrets)} secret(s) bound')
"
# 检查以特权模式运行或具有主机访问能力的 Pod
kubectl get pods --all-namespaces -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for pod in data['items']:
name = pod['metadata']['name']
ns = pod['metadata']['namespace']
for container in pod['spec'].get('containers', []):
sc = container.get('securityContext', {})
if sc.get('privileged', False) or sc.get('runAsUser', 1) == 0:
print(f'RISK: {ns}/{name}/{container["name"]} - privileged={sc.get("privileged",False)} runAsRoot={sc.get("runAsUser","not set")==0}')
"
执行 Kubeaudit,开展涵盖 RBAC 相关问题的综合安全检查。
# 运行全部 kubeaudit 检查项 kubeaudit all --kubeconfig ~/.kube/config # 运行特定 RBAC 相关检查项 kubeaudit privesc # 检查 allowPrivilegeEscalation 配置 kubeaudit rootfs # 检查 readOnlyRootFilesystem 配置 kubeaudit nonroot # 检查 runAsNonRoot 配置 kubeaudit capabilities # 检查危险 capabilities 配置 # 输出 JSON 格式结果便于后续处理 kubeaudit all --kubeconfig ~/.kube/config -f json > kubeaudit-results.json
| 术语 | 定义 |
|---|---|
| RBAC | Kubernetes 中的基于角色的访问控制(Role-Based Access Control),一种依据用户或服务账户角色来调节其对集群资源访问权限的机制 |
| ClusterRole | 集群范围内的角色定义,指定适用于所有命名空间的权限(对资源的动词操作) |
| ClusterRoleBinding | 在集群范围内将 ClusterRole 绑定至主体(用户、组、服务账户) |
| Service Account | 与 Pod 关联的身份标识,用于向 Kubernetes API Server 认证;默认自动挂载,除非显式禁用 |
| automountServiceAccountToken | Pod spec 中控制是否将服务账户 Token 自动挂载到 Pod 文件系统的字段 |
| Privilege Escalation | RBAC 中允许用户为自己或他人授予更高权限的动词(如 bind、escalate、impersonate) |
背景:一个共享 EKS 集群服务于四个开发团队。RBAC 在初始部署时配置完成,但过去 12 个月未进行复核。各团队反馈称可访问其他团队的命名空间。
应对方法:
system:authenticated 等宽泛主体授予权限的绑定kubectl rbac-tool who-can get secrets,查找可在跨命名空间读取 Secret 的主体edit 角色授予 system:authenticated,导致所有用户获得全集群写权限automountServiceAccountToken注意事项:移除 ClusterRoleBinding 可能破坏依赖集群范围权限的 CI/CD 流水线和 Operator。在删除前,务必审计哪些工作负载实际使用了这些绑定。EKS 通过 aws-auth ConfigMap 将 IAM 角色映射至 Kubernetes 用户组,因此 RBAC 更改需与 IAM 角色映射协同进行。
Kubernetes RBAC 审计报告 =============================== 集群:production-eks(EKS 1.28) 审计日期:2026-02-23 命名空间数量:12 RBAC 资源清单: ClusterRoles:48 个(18 个自定义,30 个系统内置) ClusterRoleBindings:32 个(12 个自定义,20 个系统内置) Roles(命名空间级):24 个 RoleBindings(命名空间级):36 个 服务账户:67 个 严重问题: [RBAC-001] ClusterRoleBinding 向 system:authenticated 授予 edit 权限 绑定名称:authenticated-edit 影响:所有已认证用户均可在全部命名空间中执行编辑操作 风险:任意用户均可修改任一命名空间中的资源 整改建议:替换为按团队划分的命名空间级 RoleBinding [RBAC-002] 自定义 ClusterRole 包含通配符权限 ClusterRole 名称:developer-admin 规则:verbs=["*"], resources=["*"], apiGroups=["*"] 绑定主体:4 名用户(通过 developer-admin-binding) 风险:功能等效于 cluster-admin,仅名称不同 整改建议:限定为实际所需的具体资源与动词 汇总统计: 拥有 cluster-admin 权限的主体:6 个(建议:≤ 3 个) 含通配符权限的角色:4 个 具备 Secret 访问权限的服务账户:12 个 启用自动挂载 Token 的 Pod:45 / 67 特权容器:8 个