解密时机决定暴露窗口
把敏感值加密存放只是第一步,真正决定风险的是它在什么时刻、什么位置被解密成明文。解密越早、传播越广,明文存在的时间与位置就越多:解密后在执行节点写入临时文件,明文就会落到磁盘;解密后的变量被打印到日志或调试输出,明文就永久留在日志系统里。可控的做法是把解密点尽量贴近使用点,让明文只在内存里短暂存在,并在结束前从输出中清除。
基本信息
| 适用对象 | 配置管理、编排系统与持续交付中的加密变量 |
|---|---|
| 解密要素 | 解密位置、解密进程的身份、明文存活时长 |
| 暴露面 | 磁盘临时文件、进程命令行、任务输出、日志系统 |
| 控制手段 | 延迟解密、限制可见范围、输出抑制 |
| 配套要求 | 密钥本身需独立管理,不能与被加密内容放在同一处 |
常见暴露位置
- 早期解密:批量解密后再分发到各执行节点,明文在传输与暂存环节反复落盘
- 调试输出:打开详细输出后,变量展开结果会进入任务日志
- 命令行传参:作为命令参数传递的明文会出现在进程列表中
- 临时文件:脚本自行写出临时配置,异常退出时文件残留
- 失败重试记录:任务失败时保留的现场信息常包含明文
- 差异对比输出:编排工具的差异模式会打印变更内容,容易带出明文
降低暴露面的写法
降低暴露面的写法
set +x # 处理敏感值前关闭命令回显
export TOKEN="$(load_secret token)" # 运行时取用,不写入文件
umask 077 # 若必须落盘,先收紧默认权限
cleanup() { rm -f "$tmpf"; } # 保证异常路径也清理
trap cleanup EXIT INT TERM
unset TOKEN # 使用后立即从环境中移除
grep -c "$TOKEN" app.log # 事后核查明文是否意外进入日志解密时机与后果
| 时机 | 明文存在位置 | 主要后果 |
|---|---|---|
| 集中预热批量解密 | 控制端内存与暂存文件 | 单点泄露即全量泄露 |
| 执行前分发解密 | 各执行节点磁盘 | 节点数量放大暴露面 |
| 使用时即时解密 | 执行进程内存 | 暴露面最小,推荐 |
| 轮换期双份解密 | 旧值仍可用 | 轮换后需确认旧值失效 |
已有明文进入日志时的处置顺序是:先确认范围(哪些主机、哪些日志、谁可访问),再轮换受影响的凭据,最后才清理日志。顺序颠倒会让人以为已经处理完,实际凭据仍然可用。
解密密钥若与被加密内容存放在同一套配置里,等于把锁和钥匙挂在同一面墙上。至少要把解密能力与读取配置的权限分开,让能看内容的人无法自行解密。