Kubernetes Secret 默认是明文?etcd 直连和 RBAC 都挡不住这风险
Kubernetes Secret 默认以明文形式存储于 etcd,仅靠 RBAC 无法阻断直接读取风险,必须配置静态加密作为安全基线。
Kubernetes Secret 默认加密吗?官方文档的残酷真相
官方文档明确指出,未开启额外配置的 Kubernetes Secret 在 etcd 中默认以未加密的明文形式存在,而非业界误传的自动加密状态。
很多人误以为只要把敏感数据塞进 Secret,集群就安全了。但官方文档抛出了一个冷峻的事实:Kubernetes Secret 在默认配置下,是以未加密(明文)形式存储在 API server 底层的 etcd 数据库中的 [1]。
这意味着什么?意味着只要有人能访问 API server 或者直连 etcd 存储层,就能直接读取甚至修改这些内容。Secret 本质上只是一个“受保护的数据载体”,而非绝对的安全边界。它依赖的是逻辑上的隔离,而非物理层面的加密。
为什么“受保护”不等于“已加密”
Kubernetes 将 Secret 定义为保存敏感信息的对象,但这只是逻辑上的概念。官方陈述描述的是默认行为,并不代表所有集群的实际状态 [1]。许多管理员误以为配置了 RBAC 权限控制就万事大吉,实际上这只能限制通过标准 API 的访问,无法阻止拥有 etcd 直接访问权的主体窃取数据。
这种认知偏差往往源于对“受保护”一词的误解。在 Kubernetes 语境下,“受保护”意味着需要特定权限才能操作,而“已加密”则要求数据在存储介质上必须经过加密处理。两者存在本质差异:前者依赖软件权限控制,后者依赖底层存储加密技术。如果不额外配置 静态加密 功能,你的集群中的 Secret 在 etcd 中就是裸奔的。
| 概念 | 实际含义 | 默认状态 |
|---|---|---|
| 受保护 | 需权限才能通过 API 访问 | 开启(RBAC) |
| 已加密 | 数据在 etcd 中为密文 | 关闭(明文) |
| 风险源 | API 泄露或 etcd 直连 | 均存在 |
要确认具体集群是否处于未加密状态,必须检查 API server 的加密配置和 etcd 的访问控制策略。不能仅凭官方文档的通用描述就断定所有环境都未加密,也不能因为某集群启用了加密就忽略其他风险点 [1]。
这里有一个常被争论双方忽略的关键前提:“谁有权访问 etcd”这个定义本身,在不同云厂商和运维体系中有着巨大的语义鸿沟。 在许多传统托管服务(如早期的 GKE、AKS 版本)中,所谓的“管理员”可能只拥有控制平面的管理权,却未必被明确授予直接读写底层 etcd 数据的权限;但在自建集群或某些特定的 IaaS 环境中,root 用户往往天然拥有对宿主机磁盘的直接控制权,从而能够直接挂载并读取 etcd 数据文件。这种架构上的不一致性,导致很多团队在讨论“谁可能窃取密钥”时,混淆了“拥有集群管理账号”和“拥有底层存储访问能力”这两个完全不同的攻击面。如果团队没有清晰界定内部运维人员的权限边界,单纯依赖“没人能连 etcd”的假设,往往会埋下巨大的隐患。
仅靠 RBAC 权限就能挡住 Secret 泄露吗?间接读取路径解析
即使严格限制 RBAC 权限,攻击者仍可通过创建 Pod 间接访问底层未加密的 etcd 数据,因此权限控制无法单独保障机密安全。
很多人以为只要收回了 get secret 的权限,机密就万无一失。事实是,RBAC 的边界往往比想象中更模糊。即便你严格限制了直接读取密钥的指令,只要有人能在同一命名空间内创建 Pod,风险链条就已经打开。
工作负载权限与机密访问的绑定关系
Kubernetes 的安全模型中,“允许创建工作负载”和“允许读取机密”从来不是两个独立的授权域。官方文档明确指出,在同一命名空间内,获准创建 Pod 的主体通常可以令该 Pod 引用该命名空间的 Secret[1]。这就像把一把钥匙交给别人,虽然没让他进保险柜,但他可以造一辆车,让车自带一个能开保险柜的装置。
当用户被赋予创建 Deployment 或 Pod 的权限时,他可以在 YAML 配置中通过 volumeMounts 或 envFrom 挂载 Secret。一旦 Pod 启动,容器内的进程就能以明文形式读取这些内容。这种通过工作负载形成的非显式读取路径,绕过了对 API 的直接调用拦截。
这就导致了一个常见的误判:管理员可能认为只禁用了 secrets/get 就安全了,却忽略了 pods/create 或 deployments/create 的存在。实际上,审查 Secret 访问权时,必须同步审查创建 Pod、Deployment 等工作负载的权限 [1]。
下表展示了两种常见授权场景下的实际风险差异:
| 授权场景 | 直接读取权限 (get secret) | 创建工作负载权限 (create pod) | 实际数据泄露风险 |
|---|---|---|---|
| 传统认知 | 无 | 无 | 低(认为安全) |
| 现实风险 | 无 | 有 | 高(可间接读取) |
| 防御误区 | 有 | 无 | 中(忽略间接路径) |
| 最小权限基线 | 无 | 无 | 低(需双重审查) |
| 外部存储方案 | 无 | 有 | 低(依赖外部控制) |
这种机制意味着,单纯依靠 RBAC 限制直接访问是远远不够的。实际可利用性虽受准入控制、服务账户及策略制约,但风险模型依然存在 [1]。如果不对工作负载创建权限进行严格约束,所谓的“权限隔离”在同一个命名空间内极易失效。
值得注意的是,这种间接读取的风险不仅存在于传统的开发测试环境,在多租户混合部署场景中更为隐蔽。例如,在某些采用 Namespace 隔离的 SaaS 平台中,如果租户 A 的用户拥有创建 Pod 的权限,而租户 B 的某个共享命名空间内恰好存放了用于调试的临时凭证,那么租户 A 完全可以通过创建一个恶意 Pod,将租户 B 的凭证挂载到本地并导出。这种跨租户的“侧信道”攻击,往往比直接的 API 越权更难被现有的审计工具捕获,因为它完全符合 Kubernetes 的正常逻辑流程。
从默认未加密到安全基线:必须配置的防护手段
解决默认明文存储风险需将静态加密、最小权限原则及外部存储集成纳入设计基线,而非依赖事后补救或单纯的权限管控。
很多人以为给集群开了 RBAC 权限,机密数据就万无一失。事实是,仅靠权限控制无法解决底层存储的裸奔风险。真正的安全基线,必须把 静态加密、最小权限和外部存储作为设计阶段的必选项,而非事后补救的补丁。
静态加密与权限控制的硬性要求
Kubernetes 官方文档明确指出,Secret 默认以未加密形式存储在 etcd 中 [1]。这意味着,任何能直接访问 etcd 或 API server 备份文件的主体,都能明文读取所有机密。要阻断这一路径,必须在 API server 启动参数中配置 --encryption-providers,启用对 Secret 字段的 静态加密 功能。这就像给保险柜换了把新锁,即便钥匙被复制,金库里的东西依然不可见。
同时,RBAC 策略不能只盯着“能否读取 Secret“。由于同一命名空间内允许创建 Pod 的主体通常能间接引用该空间的机密,审查权限时必须将工作负载创建权纳入考量 [1]。如果开发组拥有创建 Pod 的权限,却未被限制读取特定命名空间的 Secret,那么所谓的“最小权限”实际上是一纸空文。
外部存储与现状核验清单
对于高敏感场景,单纯依赖集群内部机制已显不足。将密钥移出集群管理,接入 HashiCorp Vault 等外部系统,是构建更可靠基线的有效手段 [1]。这种方案切断了应用与持久化存储的直接联系,大幅降低了泄露后的恢复成本。
如何落地执行?建议立即执行以下“三阶防御”操作:
- 强制启用静态加密:不要等待迁移计划,立即在 API server 配置中启用 AES-CBC 或 AES-GCM 加密提供者,并生成新的密钥轮换策略。这是防止 etcd 备份文件泄露的第一道防线。
- 实施“创建即审计”策略:利用 OPA Gatekeeper 或 Kyverno 等策略引擎,编写一条规则:任何尝试挂载
Secret的 Pod 模板,必须经过特定的审批标签或白名单校验。这将把“被动防御”转变为“主动拦截”。 - 建立外部密钥集成规范:对于生产环境的数据库密码、API Key 等核心资产,停止使用原生 Kubernetes Secret 存储,转而通过 CSI Driver 或 Sidecar 模式动态注入外部 Vault 密钥。
| 验证项 | 默认状态 | 安全基线要求 | 风险后果 |
|---|---|---|---|
| etcd 存储格式 | 明文存储 | 启用静态加密 | 管理员可直接读取所有密钥 |
| 权限控制范围 | 仅看 get secret | 包含创建 Pod 权限 | 普通用户可间接获取机密 |
| 机密存储位置 | 集群内部 | 按需移至外部系统 | 集群沦陷导致全盘泄露 |
只有当这三项指标全部达标,你才算真正跨过了从“默认未加密”到“安全基线”的门槛。
常见问题解答 (FAQ)
Q: 如果我升级了 Kubernetes 版本,Secret 会自动变成加密存储吗? A: 不会。Kubernetes 的版本升级不会自动改变存储层的加密状态。无论版本如何,默认行为依然是将 Secret 以明文形式存入 etcd。你必须手动在 API server 层面配置 静态加密 方案。
Q: 既然 etcd 默认不加密,我能不能只给 etcd 加密码? A: 这只能防止物理机被直接入侵,但无法解决逻辑漏洞。如果攻击者攻破了 API server 或拥有 etcd 直连权限(例如通过某些运维工具),他们依然可以直接读取明文数据。因此,Kubernetes Secret etcd 存储 的加密必须是在应用层(API server)进行的字段级加密。
Q: 使用外部密钥管理工具(如 Vault)后,还需要配置静态加密吗? A: 这是一个最佳实践组合。即使使用了外部存储,集群内部的 Secret 资源本身(即指向 Vault 的地址和令牌)仍然存储在 etcd 中。为了防止这些引用信息泄露,建议同时开启 Kubernetes 静态加密配置,实现纵深防御。