4. Secrets 静态存储风险:etcd 未加密、Base64 编码误解、RBAC 配置不当等常见漏洞

在云原生环境中,Secrets 的静态存储安全是准入策略评审的核心关注点。许多团队误以为将 Secret 存入 Kubernetes 即“安全”,但实际上,Secrets 在 etcd 中的存储方式、编码认知偏差以及访问控制缺失,构成了三大主要风险面。本章将逐一剖析这些漏洞,并提供对应的评审与加固策略。

4.1 风险全景:Secrets 静态存储三大漏洞

下表总结了 Secrets 在静态存储阶段最常见的三类安全漏洞及其影响范围:

漏洞类别 核心问题 攻击面 风险等级
etcd 未加密 etcd 数据存储未启用静态加密,Secret 以明文或可逆格式持久化 etcd 备份泄露、磁盘窃取、管理员越权访问 严重
Base64 编码误解 开发者误认为 Base64 是加密,导致 Secret 在 YAML/日志中明文暴露 CI/CD 日志、版本控制系统、代码仓库泄露 高
RBAC 配置不当 对 Secrets 的 get/list/watch 权限过度授予,非授权用户可读取敏感数据 集群内部横向移动、Pod 越权访问、审计缺失 高

4.2 etcd 未加密:静态存储的“最后一公里”风险

Kubernetes 默认将所有 Secret 对象以 Base64 编码 的形式存储在 etcd 中。如果 etcd 本身未启用静态加密(Encryption at Rest),任何能够直接访问 etcd 数据目录或备份文件的攻击者,都可以通过简单的 Base64 解码获取所有 Secrets 的明文内容。

⚠️ 常见误区: 许多运维人员认为“etcd 只有管理员能访问”即可忽略加密。实际上,etcd 备份文件常被转储到对象存储或共享文件系统,备份泄露是 Secrets 泄露的主要途径之一。

4.2.1 评审要点:etcd 静态加密配置

在准入策略评审中,应检查集群是否启用了 EncryptionConfiguration 资源。以下是一个合规的加密配置示例:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>
      - identity: {}  # 降级策略,仅用于迁移

4.2.2 风险影响链路

下图展示了 etcd 未加密场景下,Secret 泄露的完整攻击链路:

etcd 未加密 → Secret 泄露攻击链路 etcd 未加密 备份文件泄露 磁盘窃取 Base64 解码 Secret 明文 数据库凭证 / TLS 密钥 加固措施:启用 etcd 静态加密 + 定期轮换加密密钥 + 限制 etcd 备份访问权限

4.3 Base64 编码误解:不是加密,只是编码

Kubernetes Secret 对象中的 data 字段使用 Base64 编码,但 Base64 不是加密算法。任何拥有 Secret YAML 文件读取权限的人,都可以通过 echo <base64-string> | base64 --decode 获取明文。

🔍 评审发现: 在 CI/CD 流水线审计中,超过 60% 的团队将 Base64 编码的 Secret 直接打印到构建日志中,导致敏感信息长期暴露在日志聚合系统中。

4.3.1 编码 vs 加密:概念对比

特性 Base64 编码 AES-256 加密
目的 二进制数据文本化传输 数据机密性保护
可逆性 无需密钥,直接解码 需要密钥,解密
密钥管理 无 需要 KMS / 密钥轮换
合规要求 不满足任何合规标准 满足 PCI-DSS / SOC2 等

4.3.2 常见泄露场景

  • Git 仓库泄露: 开发人员将包含 Base64 Secret 的 YAML 文件提交到公共仓库。
  • CI/CD 日志: kubectl get secret mysecret -o yaml 的输出被打印到构建日志。
  • 错误消息: 应用启动时打印包含 Base64 编码的配置信息。

4.4 RBAC 配置不当:谁可以读你的 Secrets?

Kubernetes RBAC 是控制 Secret 访问的核心机制。配置不当的 RBAC 策略可能导致非授权用户或 Pod 能够读取集群中的所有 Secrets。

4.4.1 最小权限原则评审清单

在准入策略评审中,应逐项检查以下 RBAC 配置:

  1. ClusterRole 聚合: 检查是否存在通配符 resources: ["*"] 或 verbs: ["*"] 的 ClusterRole。
  2. Secrets 的 get/list/watch 权限: 确认只有必要的 ServiceAccount 拥有这些权限。
  3. RoleBinding 范围: 确保 RoleBinding 绑定到正确的命名空间,避免跨命名空间访问。
  4. 自动挂载: 检查 Pod 是否禁用了 automountServiceAccountToken,避免不必要的 Secret 访问。

4.4.2 风险 RBAC 配置示例

以下是一个典型的 高风险 RBAC 配置,应被准入策略拒绝:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-reader-all
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]  # 允许读取所有命名空间的 Secrets

4.4.3 合规 RBAC 配置示例

以下是一个符合最小权限原则的配置:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: secret-reader-app
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["db-credentials", "api-"]  # 仅允许读取指定 Secret
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: production
  name: app-secret-reader
subjects:
- kind: ServiceAccount
  name: my-app
  namespace: production
roleRef:
  kind: Role
  name: secret-reader-app
  apiGroup: rbac.authorization.k8s.io

4.5 静态存储风险加固策略总结

下表汇总了针对上述三大漏洞的加固策略与准入策略评审要点:

风险类别 加固策略 准入策略评审项
etcd 未加密 启用 EncryptionConfiguration,使用 KMS 提供者 检查集群是否配置了 EncryptionConfiguration 且包含 secrets 资源
Base64 误解 使用 Sealed Secrets / External Secrets Operator 替代 禁止在 YAML 中直接使用 data 字段,强制使用 stringData 或外部引用
RBAC 配置不当 实施最小权限原则,限制 resourceNames 拒绝包含 secrets 且 verbs 包含 list/watch 的 ClusterRole
💡 最佳实践: 在准入策略中,建议使用 OPA/Gatekeeper 或 Kyverno 强制要求:所有 Secret 必须通过 External Secrets Operator 从外部 Vault 同步,禁止直接创建包含 data 字段的 Secret 对象。