关于 defending-kubernetes
defending-kubernetes 是用于审查和加固 Kubernetes 集群安全的技能,也适用于初步分流后的疑似入侵调查。它按优先级覆盖 RBAC、Pod 安全、网络、凭据和审计日志控制。
主要功能
- 01优先落实 RBAC 最小权限
- 02配置 Pod Security Admission
- 03建议网络策略默认拒绝
- 04减少令牌和密钥暴露
- 05识别审计日志检测信号
适用场景
- 01审查集群 RBAC 和准入配置
- 02加固网络与 Pod 安全控制
- 03将攻击发现转化为防御措施
- 04疑似入侵后检查审计覆盖
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trilwu/ secskills --skill defending-kubernetes安装后在 Claude Code 中输入/defending-kubernetes确认已加载。
详细介绍
防御 Kubernetes
Kubernetes 的问题不在于罕见漏洞,而在于实用的默认配置不安全。真正得手的攻击通常利用了授予过多权限的 RBAC、因缺少防护而以特权运行的 Pod、扁平的 Pod 网络,以及可访问整个集群的已挂载服务账号令牌。防御工作主要是按优先级逐一堵住这些缺口,并能够发现有人试图利用它们。
本文与 attacking-eks-gke-aks 和 exploiting-containers 配套:阅读前两者,了解攻击者会做什么;阅读本文,了解应强制执行哪些措施以及应监控什么。
适用场景
- 审查集群的安全状况或准入/RBAC 配置
- 响应疑似集群入侵事件(完成初步分诊后)
- 决定应强制执行哪些措施(Pod 安全、网络策略)以及应检测什么
- 将攻击性集群评估中的发现转化为具体控制措施
- 加固控制平面、kubelet 或 etcd 的暴露面
不适用场景
- 攻击集群——使用
attacking-eks-gke-aks - 专门处理容器逃逸和运行时内部机制——使用
exploiting-containers/escaping-hardened-containers了解技术;然后回到本文了解相应控制措施 - 集群周边的云 IAM 平面(IRSA、工作负载身份、节点角色)——请参阅
investigating-*-incidents/hardening-cloud-posture;GKE/EKS/AKS 事件通常需要同时检查这两个平面 - 判断告警是否构成安全事件——使用
triaging-security-alerts
按优先级实施防护
顺序很重要——以下项目按其缺口实际成为入侵路径的频率排序。
1. RBAC 最小权限
这是最常见的实际弱点。查找那些无论看起来多么无害,都能用于权限提升的绑定:
# Who can create pods anywhere? (→ mount any secret, run as any SA)
kubectl auth can-i create pods --all-namespaces --as=system:serviceaccount:ns:sa
# Subjects bound to cluster-admin
kubectl get clusterrolebindings -o json | \
jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects'
危险的动词不只有 *。create pods 允许主体在命名空间中以任意服务账号运行 Pod 并挂载任意 Secret,实际上等同于命名空间管理员权限。对角色拥有 escalate 和 bind 权限的主体可以授予自己超出现有权限的权限。对 pods/exec 拥有 create 权限,以及访问 secrets、serviceaccounts/token 和 nodes/proxy 的权限,都各自构成权限提升路径。应枚举主体能够执行的操作,而不是只看其角色名称。
2. Pod Security Admission
PodSecurityPolicy 已在 Kubernetes 1.25 中移除;内置替代方案是 Pod Security Admission,它通过命名空间标签强制执行三个 Pod Security Standards 级别——privileged、baseline、restricted:
# Namespace label: enforce the restricted profile, and warn/audit on violations
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/audit: restricted
restricted 会阻止那些容易导致逃逸和权限提升的 Pod 配置:特权容器、主机命名空间(hostPID、hostNetwork、hostIPC)、主机路径挂载、以 root 身份运行,以及添加额外能力。没有强制配置文件的集群,只需一个 securityContext.privileged: true 就可能被接管节点。如果需要超出这三个级别的策略(镜像来源验证、注册表允许列表),就需要外部准入控制器(Kyverno、OPA Gatekeeper)——请注明这一点,不要误以为 PSA 已涵盖这些内容。
3. 网络策略默认拒绝
默认情况下,每个 Pod 都可以访问其他所有 Pod。为每个命名空间配置默认拒绝入站流量的策略,并明确允许所需流量,才能阻止单个受感染的 Pod 演变为横向移动的跳板。确认 CNI 确实会强制执行 NetworkPolicy——某些配置会接受策略对象,却不执行任何限制;这比没有策略更糟,因为它会让人误以为防护已到位。
4. 服务账号令牌和 Secret
- 对不调用 API 的 Pod 设置
automountServiceAccountToken: false。已挂载的令牌加上宽松的 RBAC 绑定,是集群内横向转移的常见途径。 - 除非配置了静态加密,否则 Kubernetes Secret 在 etcd 中只是 Base64 编码,并未加密。请确认已启用静态加密。
- 检查是否有令牌和云凭据通过环境变量传递——它们会泄露到日志和崩溃转储中。
5. 控制平面和 kubelet 暴露
- API 服务器不应在未启用身份验证/授权的情况下暴露到互联网,并且最好限制网络访问。必须关闭匿名身份验证。
- kubelet 只读端口(10255)和经过身份验证的端口(10250)都不得被工作负载访问;
nodes/proxyRBAC 权限和暴露的 10250 端口是直接在节点上执行命令的途径。 - etcd 必须要求双向 TLS——访问 etcd 就意味着一切都完了,因为其中保存着所有密钥。
检测:启用审计日志
大多数集群都没有配置有效的审计策略,因此事后无从调查。未配置审计策略的集群,相当于关闭了 GCP 数据访问日志——活动根本不会被记录。
高价值审计信号:
- 对 Pod 执行
exec、attach和port-forward——交互式访问 - 大量执行 Secret
get/list,尤其是集群范围内的操作 - 对
clusterrolebindings和rolebindings执行create/update - 创建带有
privileged、主机命名空间或主机路径挂载的 Pod - 成功的匿名请求或
system:unauthenticated请求 - 通过
TokenRequestAPI 创建服务账号令牌
在托管集群上,审计日志会发送到云日志平台(GKE → Cloud Audit Logs,EKS → CloudWatch,AKS → Azure Monitor),调查工作会在此处与 investigating-*-incidents 技能衔接。
应拒绝的自我安慰
- “这个角色不叫 admin,所以没问题。” 名称无关紧要。在某个命名空间中拥有
create pods或secrets get权限,实际上就相当于该命名空间的管理员。应枚举权限,而非查看头衔。 - “我们强制执行了 Pod Security,所以容器是受限的。” 只有在配置文件为
restricted且确实强制执行时才成立,而不只是设置为warn。baseline或仅审计标签几乎无法阻止任何逃逸途径。 - “我们定义了 NetworkPolicy,所以网络已隔离。” 只有 CNI 实际执行这些策略时才成立。应验证是否执行,而非只确认对象是否存在。
- “Secret 存在 etcd 中,所以它们受到了保护。” 除非启用了静态数据加密,否则它们只是 base64 编码。任何能够读取 etcd 或执行
get secrets的人都能获取它们。 - “这是托管集群,服务提供商会负责安全。” 服务提供商负责其运行的控制平面;RBAC、Pod Security、网络策略和工作负载身份由你负责。共同责任不包括你的绑定配置。
- “没有触发任何警报。” 不要把沉默视为安全;在此之前,先检查是否配置了审计策略。
阅读外部来源
以 Markdown 格式获取公开公告、规范和供应商报告:
curl -sL "https://defuddle.md/<url>" # scheme in the path is optional
这会去除页面模板内容——对于以正文为主的页面,令牌数大约减少 78%——并返回全文而非摘要,因此你可以搜索内容,并相信未找到结果确实意味着不存在。
有三种情况不适用。获取 JSON 和 API 响应时应直接读取原始数据,因为可读性提取会破坏结构化数据。获取经过身份验证的页面或由 JavaScript 渲染的页面时也应直接访问,因为该工具会以匿名方式检索。此外,切勿通过它访问攻击者基础设施(钓鱼链接、C2、恶意软件托管站点)、客户自有主机或行动 URL——请求会离开你的机器并发送给第三方;对于正在运行的攻击者基础设施,这还会打草惊蛇。
有些网站会拦截提取器并返回错误信息,而不是页面内容——例如 freedesktop.org 返回的 {"error":"Failed to fetch: 418 I'm a teapot"}。这表示获取请求被拒绝,而不是来源内容不存在。在据此得出任何结论之前,应直接重新获取该 URL。
参考资料
attacking-eks-gke-aks— 这些控制措施要阻断的攻击路径exploiting-containers、escaping-hardened-containers— Pod Security 旨在阻止的逃逸技术hardening-cloud-posture— 集群周边的云 IAM 平面engineering-detections— 将上述审计信号转化为规则investigating-aws-incidents/investigating-gcp-incidents— 托管集群的审计轨迹指向何处