在 LUKS 上设置 ZFS
原生加密
ZFS 现在原生支持加密。与 LUKS 上的 ZFS 相比,这有许多优点,包括多磁盘、加密的 zfs send、跨 *BSD/Linux 的可移植性等。
有关使用原生加密的 Root on ZFS 指南,请参阅此处。
简介
本文档描述了如何设置使用 ZFS 的 Alpine Linux,其池位于加密分区中。为了加密分区,使用了设备映射器加密 (dm-crypt) 模块和 Linux 统一密钥设置 (LUKS)。
请注意,您必须将 /boot/
目录安装在未加密的分区上才能正确启动。
我们将使用 syslinux 引导加载程序和传统的 BIOS 引导。
要求
- Alpine 实例,位于您将从中启动的介质以外的介质上,请参阅官方安装指南。
注意:我们不能使用来自安装 ISO 的实时环境,因为我们将安装 ZFS 内核模块,而这对于只读 /boot(由 ISO 提供)是不可能的。
硬盘设备名称
以下文档使用 /dev/sda
设备作为安装目的地。如果您的环境对硬盘使用不同的设备名称,请在示例中使用相应的设备名称。
在 LUKS 分区之上设置使用 ZFS 的 Alpine Linux
要将 Alpine Linux 安装在 LUKS 加密分区之上的 ZFS 池中,您不能使用官方安装程序。安装需要您必须在 Alpine Linux Live CD 环境中运行的几个手动步骤。
准备安装环境
在您开始在您打算从中启动的介质上安装 Alpine Linux 之前,请准备您已有的安装
- 更新
apk
缓存
# apk update
- 安装设置 ZFS 和 LUKS 所需的以下软件包
# apk add cryptsetup e2fsprogs syslinux zfs zfs-$(uname -r | rev | cut -d'-' -f1 | rev) # modprobe zfs
创建分区布局
Linux 需要未加密的 /boot/
分区才能启动。您可以为加密的 ZFS 池分配剩余空间。
- 启动
fdisk
实用程序以设置分区
# fdisk /dev/sda
- 创建
/boot/
分区
- 输入
n
→p
→1
→1
→100m
以创建一个新的 100 MB 主分区。
- 输入
- 创建
- 设置
/boot/
分区为活动
- 输入
a
→1
。
- 输入
- 设置
- 创建 LUKS 分区
- 输入
n
→p
→2
以开始创建下一个分区。按Enter
选择默认起始柱面。输入分区大小。例如,512m
表示 512 MB,5g
表示 5 GB。或者,按Enter
设置最大可用大小。
- 输入
- 要验证设置,请按
p
。输出应类似于此
- 要验证设置,请按
Device Boot Start End Sectors Size Id Type /dev/sda1 * 2048 206847 204800 100M 83 Linux /dev/sda2 206848 41943039 41736192 19.9G 83 Linux
- 按
w
保存更改。
- 可选地,用随机值填充 LUKS 分区
# dd if=/dev/urandom of=/dev/sda2 bs=1M
注意:根据分区的大小,此过程可能需要几分钟到数小时。
加密 ZFS 分区
- 要加密稍后将包含 LVM PV 的分区
# cryptsetup luksFormat /dev/sda2
- 注意:Alpine Linux 在提示输入密码以在启动时加密分区时使用
en-us
键盘映射。如果您在临时环境中更改了键盘映射,则在此步骤中加密分区期间输入的密码可能与您在系统启动期间输入的密码不匹配。 - 如果您喜欢设置单独的哈希算法和哈希模式
- 要运行基准测试
# cryptsetup benchmark
- 要使用单独的设置加密分区,请输入,例如
# cryptsetup -v -c aes-xts-plain64 -s 256 --hash sha256 --iter-time 2000 --use-urandom luksFormat /dev/sda2
查阅 cryptsetup --help
以获取选项。
创建文件系统
- 打开 LUKS 分区
# cryptsetup open --type luks /dev/sda2 crypt
创建 ZFS 池
# zpool create -o ashift=12 -O normalization=formD -O atime=off -m none -R /mnt -O compression=lz4 tank /dev/mapper/crypt
zpool create
选项的含义
选项 | 含义 |
---|---|
zpool create | 创建 zpool |
-o ashift=12 | 4K 块 |
-O normalization=formD | 将默认 Unicode (UTF-8) 规范化设置为 'formD' |
-O atime=off | 禁用对文件访问时间的更新。这减少了对磁盘的写入,但可能会导致邮件程序(如 mutt )出现问题。 |
-m none | 无挂载点,因为我们稍后会处理它。 |
-R /mnt | 将 altroot 设置为 /mnt 。它就像池的临时挂载点。 |
-O compression=lz4 | 对池使用 lz4 压缩。通常建议使用。 |
tank | 池名称。tank 将在本指南中通篇使用。 |
/dev/mapper/crypt | ZFS 将使用的块设备的路径。 |
完成此操作后,确认池已创建
# zpool status
应返回类似以下内容
pool: tank state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM tank ONLINE 0 0 0 crypt ONLINE 0 0 0 errors: No known data errors
创建必需的数据集
# zfs create -o mountpoint=none -o canmount=off tank/ROOT # zfs create -o mountpoint=/ tank/ROOT/alpine
创建可选数据集(随意添加您自己的)
# zfs create -o mountpoint=/home tank/HOME # zfs create -o mountpoint=/var/log tank/LOG
创建 /boot
文件系统
# mkfs.ext4 /dev/sda1
挂载 /boot
文件系统
- 创建
/mnt/boot/
目录并在该目录中挂载/dev/sda1
分区
# mkdir /mnt/boot/ # mount -t ext4 /dev/sda1 /mnt/boot/
安装 Alpine Linux
在此步骤中,您将在 /mnt/
目录中安装 Alpine Linux,其中包含已挂载的文件系统结构。
- 安装 Alpine Linux
# setup-disk -m sys /mnt/
- 安装程序下载最新的软件包以安装基本安装。此外,安装程序还会自动在
fstab
文件中创建挂载点的条目(但我们稍后必须手动编辑它),这些挂载点当前挂载在/mnt/
目录中。
- 注意:在此步骤中,自动写入主引导记录 (MBR) 失败。稍后,您将手动将 MBR 写入磁盘。
- 要使操作系统能够在启动时解密 LUKS 分区,请创建
/mnt/etc/crypttab
文件。在文件中输入以下行,以使用luks
模块解密/dev/sda2
分区,并将其映射到lvmcrypt
名称
crypt /dev/sda2 none luks
- 删除
/mnt/etc/fstab
中的 zfs 条目,因为 ZFS 会自动挂载它们。您的 fstab 应类似于此
UUID=6b4f2c9c-0a0f-4a8c-a73b-d2b47920ad6f /boot ext4 rw,relatime,stripe=4,data=ordered 0 2
- 编辑
/mnt/etc/mkinitfs/mkinitfs.conf
文件,并将cryptsetup
和zfs
模块附加到features
参数
features="ata base ide scsi usb virtio ext4 lvm cryptsetup zfs"
- 重建初始 RAM 磁盘
# mkinitfs -c /mnt/etc/mkinitfs/mkinitfs.conf -b /mnt/ $(ls /mnt/lib/modules/)
- 该命令使用
mkinitfs.conf
文件中设置的设置(在-c
参数中)来生成 RAM 磁盘。该命令在/mnt/
目录中执行,并且 RAM 磁盘是使用已安装内核的模块生成的。如果不使用$(ls /mnt/lib/modules/
) 选项设置内核版本,则mkinitfs
尝试使用临时环境中安装的内核版本生成 RAM 磁盘,这可能与setup-disk
实用程序安装的最新版本不同。
- 编辑
/mnt/etc/update-extlinux.conf
文件,设置根 ZFS 数据集,并将以下内核选项附加到default_kernel_opts
参数
root=tank/ROOT/alpine default_kernel_opts="... cryptroot=/dev/sda2 cryptdm=crypt rootfstype=zfs"
cryptroot
参数设置包含根文件系统的设备的名称。cryptdm
参数设置先前在crypttab
文件中设置的映射的名称。rootfstype
选项将根文件系统类型设置为 zfs。
- 由于
update-extlinux
实用程序仅在/boot/
目录上运行,因此暂时将根更改为/mnt/
目录并更新引导加载程序配置
# chroot /mnt/ # update-extlinux # exit
- 忽略
update-extlinux
实用程序显示的错误。
- 将 MBR 写入
/dev/sda
设备
# dd bs=440 count=1 conv=notrunc if=/mnt/usr/share/syslinux/mbr.bin of=/dev/sda
卸载文件系统
- 卸载
/mnt/boot/
# umount /mnt/boot/
- 卸载所有 zfs 文件系统
# zfs unmount -a
- 导出所有 zfs 池
# zpool export -a
- 关闭
lvmcrypt
设备
# cryptsetup luksClose crypt
- 重启系统
# reboot
故障排除
通用步骤
如果您的系统无法启动,您可以验证设置并修复不正确的配置
- 加载 ZFS 内核模块
# modprobe zfs
# zpool import -R /mnt tank # mount -t ext4 /dev/sda1 /mnt/boot
- 验证您是否正确运行了安装 Alpine Linux部分中描述的步骤。如有必要,更新配置。

待办事项:LUKS 上的多磁盘 ZFS?