4. Secrets安全威胁建模
在Kubernetes中,Secret是承载敏感信息的一等公民对象,但它本身并不是“安全保险箱”。理解Secret的安全威胁,需要先明确它的攻击面:Secret从创建到被消费,会经过API Server、etcd、kubelet、容器运行时、节点文件系统、环境变量、镜像层、日志与CI/CD流水线等多个环节。每一个环节都可能成为攻击者获取明文或间接推断敏感信息的入口。威胁建模的目标,就是把这些入口系统化地识别出来,并评估其被利用后可能造成的权限提升与横向移动风险。
一、攻击面分析:Secret的生命周期暴露点
Secret的典型生命周期是:用户或控制器通过kubectl、API或GitOps工具提交Secret对象 → API Server鉴权并写入etcd → 调度器将Pod调度到节点 → kubelet从API Server拉取Secret → kubelet将其写入节点本地存储(tmpfs或磁盘) → 容器运行时以volume或环境变量方式注入容器 → 应用读取并使用。这个链条上,攻击面可以归纳为四类:控制面暴露(API Server未授权访问、etcd未加密或备份泄露)、节点暴露(kubelet只读端口、节点本地Secret文件、容器运行时接口)、工作负载暴露(环境变量被进程转储、日志打印、镜像层残留)、供应链暴露(CI/CD变量、Helm values、Git仓库中的明文Secret)。
以etcd为例,默认情况下Secret以base64编码存储,并非加密。如果攻击者获得etcd的读权限或拿到etcd快照备份,所有Secret等同于明文。同样,如果API Server的--authorization-mode配置不当,或ServiceAccount被授予了过宽的get/list/watch secrets权限,攻击者可以直接读取整个命名空间的Secret。节点侧,kubelet会将Secret挂载到/var/lib/kubelet/pods/<pod-uid>/volumes/kubernetes.io~secret/下,若节点被入侵且未启用只读挂载或未限制节点访问,Secret文件可被直接读取。
二、常见泄露途径与权限提升风险
Secret泄露最常见的途径并不是“被黑客攻破”,而是“被自己人无意暴露”。第一类是环境变量泄露:许多应用在启动时将Secret注入环境变量,而崩溃转储、/proc/<pid>/environ、调试端点或错误日志都可能把环境变量完整打印出来。第二类是镜像与代码仓库泄露:开发人员把kubectl create secret生成的YAML直接提交到Git,或在Dockerfile中通过ARG传入密钥,导致镜像层中残留明文。第三类是日志与监控泄露:应用把包含Secret的请求体、连接字符串或配置对象写入日志,日志又被采集到ELK或云日志服务中。第四类是备份与快照泄露:etcd备份、PV快照、CI缓存中可能包含未加密的Secret数据。
泄露本身不是终点,权限提升才是攻击者的目标。一个典型的提升链是:攻击者通过某个Pod的环境变量拿到数据库密码 → 连接数据库获取更多业务数据 → 在数据库中发现云厂商AccessKey → 使用AccessKey访问云API → 获取Kubernetes集群的kubeconfig或创建新的ServiceAccount Token → 调用API Server创建特权Pod → 挂载宿主机文件系统 → 接管整个集群。这条链上,Secret是起点,RBAC配置和Token有效期决定了攻击者能走多远。如果ServiceAccount Token是长期有效的,且绑定了cluster-admin或过宽的secrets get/list权限,攻击者可以在几分钟内完成从单点泄露到集群接管的跨越。
三、STRIDE方法在Secret治理中的应用
STRIDE是微软提出的威胁建模框架,包含六类威胁:仿冒(Spoofing)、篡改(Tampering)、抵赖(Repudiation)、信息泄露(Information Disclosure)、拒绝服务(Denial of Service)、权限提升(Elevation of Privilege)。将STRIDE映射到Secret场景,可以系统化地发现遗漏的威胁。例如,仿冒对应攻击者伪造ServiceAccount Token或冒充合法客户端访问API Server;篡改对应攻击者修改Secret内容,向应用注入恶意凭据;抵赖对应没有开启审计日志,无法追溯谁读取或修改了Secret;信息泄露对应上述所有泄露途径;拒绝服务对应攻击者删除关键Secret导致Pod无法启动;权限提升对应从Secret到Token再到集群接管的链条。
在实际操作中,可以按以下步骤对Secret做一次STRIDE威胁建模:第一步,画出数据流图,标出Secret的创建、存储、分发、消费四个阶段;第二步,对每个阶段逐一问六个问题——谁能仿冒?什么能被篡改?操作能否被抵赖?什么信息会泄露?什么会导致不可用?如何提升权限?第三步,为每个识别出的威胁记录现有控制措施和残余风险;第四步,输出缓解措施并排优先级。例如,针对“信息泄露”,缓解措施包括启用etcd静态加密、使用secretKeyRef替代环境变量、禁止在日志中打印Secret、对Secret访问开启审计;针对“权限提升”,缓解措施包括最小权限RBAC、使用短期Token、限制create pod权限、启用Pod Security Admission。
get secrets权限。攻击者通过应用A的日志拿到一个数据库密码,进而获取云AccessKey。若该AccessKey具备eks:DescribeCluster权限,攻击者可获取集群访问入口;若集群中又存在绑定cluster-admin的ServiceAccount且Token未过期,攻击者即可创建特权Pod。这个示例说明:Secret治理不能只看Secret本身,必须结合RBAC、Token生命周期和云权限一起建模。
四、威胁建模输出示例
下表给出一个可直接参考的STRIDE威胁建模记录表,字段包括威胁类型、攻击面、攻击场景、现有控制、残余风险和缓解措施。实际使用时,可按命名空间或应用逐个填写。
| STRIDE类型 | 攻击面 | 攻击场景 | 现有控制 | 残余风险 | 缓解措施 |
|---|---|---|---|---|---|
| 仿冒 | API Server | 伪造SA Token访问API | Token短期有效 | 中 | 启用TokenRequest、绑定受众 |
| 篡改 | etcd / API | 修改Secret注入恶意凭据 | RBAC限制写权限 | 低 | 开启审计、使用准入控制 |
| 抵赖 | 审计日志 | 读取Secret后无记录 | 未开启审计 | 高 | 启用审计策略并集中存储 |
| 信息泄露 | 环境变量/日志 | env转储或日志打印Secret | 部分应用使用volume | 高 | 统一改用volume挂载、日志脱敏 |
| 拒绝服务 | Secret对象 | 删除关键Secret导致Pod失败 | 无备份 | 中 | GitOps备份、RBAC限制删除 |
| 权限提升 | SA Token / RBAC | Secret→Token→特权Pod | 部分SA权限过宽 | 高 | 最小权限、限制create pod、PSA |
威胁建模不是一次性活动。每当新增应用、调整RBAC、更换Secret管理方案或引入新的CI/CD流水线时,都应重新审视攻击面和STRIDE映射。只有把Secret放回整个Kubernetes权限体系与供应链中去看,才能真正识别出那些“看起来只是一个密码”背后的系统性风险。