物理主机备份卷的 LUKS2 密钥轮换与只读恢复演练

物理主机备份卷的 LUKS2 密钥轮换与只读恢复演练

备份文件已经落盘,接收账户也完成隔离,但退役磁盘或离线副本中的数据是否仍可被直接读取,是另一条安全边界。卷加密适合保护未解锁的数据,不适合替代在线访问控制;密钥轮换适合撤销旧口令,却不能修复已经泄露的数据。本文用独立文件容器演练 LUKS2 换钥与恢复,不操作现有数据盘。

一、先界定加密保护的对象

OnuCloud 物理主机标配两块 1TB NVMe,各自直连,没有硬件 RAID。卷加密、磁盘冗余与异地备份解决不同问题:前者限制离线读取,后两者分别处理设备故障与独立副本。把两块盘都加密,不会自动产生可恢复的备份。

以下以 Ubuntu Server 24.04 LTS 为例,需要管理员权限、cryptsetup、e2fsprogs 和约 256 MiB 的实际可用空间。先通过发行版软件包安装所需工具,再进入专用管理员 shell;后续命令在同一 shell 中执行,避免变量丢失。

已解锁卷对拥有相应权限的进程仍然可读。卷加密不能阻止管理员权限被滥用,也不能让正在写入的数据库副本自动具备应用一致性。

正式落地前,应明确谁保管口令、谁能读取头部备份,以及人员变更时如何撤销访问。口令不要写进命令参数、脚本或工单正文。

二、建立不碰真实磁盘的演练卷

mktemp 创建独立工作目录,所有格式化操作只指向其中的新文件。执行前检查映射名 backup-drill 未被使用;如已存在,应停止并调查,不要关闭未知映射。示例使用交互式口令,初始口令放在槽位 0。

umask 077
work=$(mktemp -d /var/tmp/luks-drill.XXXXXX)
image="$work/backup.img"
mountpoint="$work/mnt"
mkdir "$mountpoint"
truncate -s 256M "$image"
cryptsetup luksFormat --type luks2 --key-slot 0 "$image"
cryptsetup open "$image" backup-drill
mkfs.ext4 /dev/mapper/backup-drill
mount /dev/mapper/backup-drill "$mountpoint"
printf 'backup-recovery-check\n' > "$mountpoint/probe.txt"
(
  cd "$mountpoint"
  sha256sum probe.txt
) > "$work/expected.sha256"
sync
umount "$mountpoint"
cryptsetup close backup-drill

每条命令成功后再执行下一条。尤其不能在解锁失败后继续格式化,也不能把文件路径替换为未经核对的 NVMe 设备名。稀疏文件的标称大小不等于实际占用;演练期间仍需确认承载文件系统有足够空间。

校验清单保存在容器外,便于恢复时独立对照。生产环境中的清单也需要可信来源;若数据和清单可被同时篡改,单纯匹配哈希不能证明来源可靠。

三、先验证新槽位,再撤销旧口令

先运行 cryptsetup luksDump "$image",确认类型为 LUKS2、槽位 0 已启用且槽位 1 空闲。真实卷的槽位布局可能不同,不能照搬编号。下面添加新口令时先输入旧口令完成授权,再按提示设置新口令。

cryptsetup luksAddKey --key-slot 1 "$image"
cryptsetup open --test-passphrase --key-slot 1 "$image"
cryptsetup luksDump "$image"

第二条命令输入新口令,退出码为 0 才算验证成功。--test-passphrase 只测试解锁,不创建映射;因此不会影响文件系统挂载状态。添加槽位不等于更换卷密钥,也不意味着全部数据重新加密。

确认新口令已由授权人员妥善保存后,再删除槽位 0。演练中删除时使用保留的新口令授权:

cryptsetup luksKillSlot "$image" 0
cryptsetup open --test-passphrase "$image"

最后一条先输入旧口令,预期失败;随后重新执行并输入新口令,预期成功。不要用自动重试掩盖失败,也不要只看槽位列表就宣布轮换完成。验收证据应包含槽位变化和两次测试结果,不包含口令本身。

四、头部备份也是敏感访问材料

LUKS 头部保存解锁所需的关键元数据。数据区尚在但头部损坏时,头部备份可能成为恢复条件;它不是数据副本,更不能和唯一的数据卷一起丢失。轮换成功后导出当前头部:

cryptsetup luksHeaderBackup "$image" \
  --header-backup-file "$work/header-current.bin"
chmod 600 "$work/header-current.bin"
cryptsetup luksDump "$image" > "$work/luks-layout.txt"

目录权限与文件权限只提供本机访问限制。正式头部副本应进入受控的独立保管位置,记录对应卷、轮换批次与授权人员,并与数据副本建立明确对应关系。不要把头部文件当普通诊断附件发送。

特别需要处理历史版本:旧头部可能保留已撤销的槽位,恢复旧头部可能让旧口令重新生效。因此,删除当前卷上的旧槽位,不代表所有历史材料中的访问能力都已撤销。若威胁涉及卷密钥泄露,单纯换口令不够,应另行规划重新加密或迁移。

五、只读恢复必须验到文件内容

演练卷已经干净卸载,可以重新建立只读映射,再以 ext4 的只读且不回放日志方式挂载。两层限制分别约束块设备和文件系统行为。

cryptsetup open --readonly --key-slot 1 "$image" backup-drill
mount -t ext4 -o ro,noload /dev/mapper/backup-drill "$mountpoint"
findmnt -no SOURCE,FSTYPE,OPTIONS "$mountpoint"
(
  cd "$mountpoint"
  sha256sum -c "$work/expected.sha256"
)
touch "$mountpoint/should-not-exist"

输入新口令后,挂载选项应包含 ro,校验应成功,最后的写入应失败。若写入成功,应立即停止验收并检查实际挂载目标,不能把它视为无关异常。noload 不适合用来掩盖脏文件系统;遇到未正常卸载的副本,应先保全原件,在工作副本上评估修复。

完成后依次卸载目录、关闭映射。确认没有挂载和映射残留,再处理演练目录;生产材料则按既定保管规则管理,不混入临时清理。

最终记录应能回答四个问题:新口令能否独立解锁,旧口令是否失效,头部副本是否受控,恢复出的文件是否与可信清单一致。四项都通过,才形成一次可复查的换钥与恢复演练。

常见问题

LUKS2 更换口令会重新加密整个备份卷吗?

本文的槽位轮换只改变解锁卷密钥的口令材料,不重新加密全部数据,也不更换卷密钥。应先添加并验证新槽位,再删除旧槽位。

旧口令已经撤销,历史头部备份还需要保护吗?

需要。历史头部备份可能保留旧槽位;恢复该头部后,旧口令可能重新获得解锁能力。应将头部备份按敏感密钥材料保护,并在轮换后导出新版本。

为什么只读恢复同时使用只读映射与 ro,noload?

只读映射阻止块设备写入,ext4 的 ro,noload 挂载同时避免日志回放。该方式适合读取干净卸载的演练卷,不代替文件系统修复或应用一致性检查。

AMD EPYC 7543P 独享物理主机

$472/月起

配置 OnuCloud 物理主机 核对 OnuCloud 租赁价格

物理主机配置,按负载登记

AMD EPYC 7543P 独享整机,存储冗余与数据备份由管理员自行规划。