全盘磁盘加密安全启动
免责声明:此指南仅供测试目的,请勿直接遵循。当 GRUB 2.12 rc1 可用于 LUKSv2、GRUB 和 FDE 时,此指南将会更新。
本指南逐步解释如何使用 LUKS2 和 LVM (一个物理卷分区和三个逻辑卷分区 (/ /boot 和 swap)) 在 NVMe 驱动器上,通过 UEFI 和安全启动,设置 Alpine Linux 全盘磁盘加密。本指南使用 Alpine Linux Std 3.16.1 编写,如果需要,请调整一些命令。
本指南的目标是遵循 KISS 原则,但也可以使用其他文件系统,如果建议的配置不满足您的要求,也可以添加 /home;/var/log 等的多个分区。
安装软件包
为了方便分区,我们将使用 gdisk
# apk add lsblk gptfdisk
对于加密,我们将使用 cryptsetup
# apk add cryptsetup
对于 LVM
# apk add lvm2
为了使用和管理 UEFI,需要多个软件包
# apk add efibootmgr e2fsprogs grub grub-efi
准备/覆盖磁盘
# apk add haveged
这可能需要很长时间,在我这边,对于 500GB 的 nVME 大约需要 30 分钟。
# haveged -n 0 | dd of=/dev/nvme0n1
磁盘分区
假设磁盘是 /dev/nvme0n1 并且没有分区,我们将创建两个分区
- 一个用于 UEFI
- 一个用于 LVM
# gdisk /dev/nvme0n1 GPT fdisk (gdisk) version 1.0.9.1 Partition table scan: MBR: not present BSD: not present APM: not present GPT: not present Creating new GPT entries in memory. Command (? for help): n Partition number (1-128, default 1): First sector (34-1000215182, default = 2048) or {+-}size{KMGTP}: Last sector (2048-1000215182, default = 1000214527) or {+-}size{KMGTP}: 512M Current type is 8300 (Linux filesystem) Hex code or GUID (L to show codes, Enter = 8300): ef00 Changed type of partition to 'EFI system partition' Command (? for help): n Partition number (2-128, default 2): First sector (34-1000215182, default = 1050624) or {+-}size{KMGTP}: Last sector (1050624-1000215182, default = 1000214527) or {+-}size{KMGTP}: Current type is 8300 (Linux filesystem) Hex code or GUID (L to show codes, Enter = 8300): 8309 Changed type of partition to 'Linux LUKS' Command (? for help): w Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING PARTITIONS!! Do you want to proceed? (Y/N): Y OK; writing new GUID partition table (GPT) to /dev/nvme0n1. The operation has completed successfully.
使用新分区填充 /dev
# partprobe /dev/nvme0n1
配置 LUKS
使用 luks2 (目前 GRUB 不支持)
# cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --pbkdf pbkdf2 --iter-time 1000 --use-random luksFormat /dev/nvme0n1p2
使用 luks1
# cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --iter-time 1000 --use-urandom --type luks1 luksFormat /dev/nvme0n1p2
WARNING! ======== This will overwrite data on /dev/nvme0n1p2 irrevocably. Are you sure? (Type 'yes' in capital letters): YES Enter passphrase for /dev/nvme0n1p2: Verify passphrase: Key slot 0 created. Command successful. # cryptsetup luksOpen /dev/nvme0n1p2 lvmcrypt
LVM : 物理卷和逻辑卷创建
# pvcreate /dev/mapper/lvmcrypt Physical volume "/dev/mapper/lvmcrypt" successfully created. # vgcreate vg0 /dev/mapper/lvmcrypt Volume group "vg0" successfully created # lvcreate -L 20G vg0 -n swap (I have a 16GB RAM laptop) Logical volume "swap" created. # lvcreate -l 100%FREE vg0 -n root Logical volume "root" created.
检查创建
# lvscan ACTIVE '/dev/vg0/swap' [20.00 GiB] inherit ACTIVE '/dev/vg0/root' [455.92 GiB] inherit
挂载点和文件系统
为 UEFI 分区创建 vfat 文件系统
# mkfs.vfat /dev/nvme0n1p1
为 / 分区创建 ext4 文件系统
# mkfs.ext4 /dev/vg0/root
激活 SWAP
# mkswap /dev/vg0/swap # swapon /dev/vg0/swap
将 / 分区挂载到 /mnt
# mount -t ext4 /dev/vg0/root /mnt
创建 /boot/efi
# mkdir /mnt/boot/efi -p
将 UEFI 分区挂载到 /mnt/boot/efi
# mount -t vfat /dev/nvme0n1p1 /mnt/boot/efi
检查分区方案
# lsblk nvme0n1 259:0 0 476.9G 0 disk ├─nvme0n1p1 259:1 0 511M 0 part /mnt/boot/efi └─nvme0n1p2 259:2 0 476.4G 0 part └─lvmcrypt 253:0 0 476.4G 0 crypt ├─vg0-swap 253:1 0 20G 0 lvm [SWAP] └─vg0-root 253:2 0 456.4G 0 lvm /mnt
安装 Alpine
# setup-disk -m sys /mnt/
mkinitfs 设置和模块
编辑 /mnt/etc/mkinitfs/mkinitfs.conf 文件,并将模块附加到 features 参数 (如果您的键盘不是 QWERTY,则只需要 keymap)
features="ata base ide scsi usb virtio ext4 lvm nvme keymap cryptsetup cryptkey resume"
重新生成 initram
# mkinitfs -c /mnt/etc/mkinitfs/mkinitfs.conf -b /mnt/ $(ls /mnt/lib/modules/)
Grub 设置
创建 crypto_keyfile.bin 以避免在启动过程中输入两次密码 (一个用于 Grub 分区,一个用于 Alpine 分区)
# touch /mnt/crypto_keyfile.bin # chmod 600 /mnt/crypto_keyfile.bin # dd if=/dev/random bs=512 count=4 | xxd -p -c999 | tr -d '\n' > /mnt/crypto_keyfile.bin # cryptsetup luksAddKey /dev/nvme0n1p2 /mnt/crypto_keyfile.bin
然后,让我们挂载并 chroot 到我们全新的安装
# mount -t proc /proc /mnt/proc # mount --rbind /dev /mnt/dev # mount --make-rslave /mnt/dev # mount --rbind /sys /mnt/sys # chroot /mnt
编辑 /etc/default/grub,并在 cryptdm=root 参数后添加 cryptkey,像这样
GRUB_TIMEOUT=2 GRUB_DISABLE_SUBMENU=y GRUB_DISABLE_RECOVERY=true GRUB_CMDLINE_LINUX_DEFAULT="modules=sd-mod,usb-storage,ext4,nvme cryptroot=UUID=XXXX cryptdm=lvmcrypt cryptkey quiet rootfstype=ext4"
XXXX 可以使用 blkid 命令找到
添加一个新的 GRUB_PRELOAD_MODULES 行,像这样
GRUB_PRELOAD_MODULES="luks cryptodisk part_gpt lvm"
最后,添加 cryptodisk 参数
GRUB_ENABLE_CRYPTODISK=y
让我们显示我们分区方案的 UUID
# lsblk -f
创建 /root/grub-pre.cfg,并将 <XXXX-UUID_WITHOUT_HYPHENS> 替换为您的加密 LVM 分区 UUID (此处为 /dev/nvme0n1p2),不带连字符,将 <YYYY> 替换为来自 vgdisplay 的 VG UUID,并将 <ZZZZ> 替换为来自 lvdisplay 的 /dev/vg0/root 的 LV UUID
set crypto_uuid=<XXXX-UUID_WITHOUT_HYPHENS> cryptomount -u $crypto_uuid set root='lvmid/<YYYY>/<ZZZZ>' set prefix=($root)/boot/grub insmod normal normal
配置安全启动
# apk add efi-mkkeys efibootmgr sbsigntool # efi-mkkeys -s "Your Name" -o /etc/uefi-keys
重新安装 Grub
# mkdir /boot/efi/EFI/AlpineLinuxSecureBoot # grub-mkimage -p /boot/grub -O x86_64-efi -c /root/grub-pre.cfg -o /tmp/grubx64.efi luks2 part_gpt cryptodisk lvm ext2 gcry_rijndael pbkdf2 gcry_sha512 # install -v /tmp/grubx64.efi /boot/efi/EFI/AlpineLinuxSecureBoot/ # sed -i 's/SecureBoot/SecureB00t/' /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi # cd /boot/efi/EFI/AlpineLinuxSecureBoot/ # sbsign --key /etc/uefi-keys/db.key --cert /etc/uefi-keys/db.crt --output grubx64.efi.signed grubx64.efi # grub-mkconfig -o /boot/grub/grub.cfg # efibootmgr --disk /dev/nvme0n1p1 --part 1 --create --label 'Alpine Linux Secure Boot Signed' --load /EFI/AlpineLinuxSecureBoot/grubx64.efi.signed --verbose
检查您的 .efi 是否已签名
# sbverify --cert /etc/uefi-keys/db.crt /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi.signed Signature verification OK # sbverify --list /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi.signed signature 1 image signature issuers: - /CN="Your Name" (db) image signature certificates: - subject: /CN="Your Name" (db) issuer: /CN="Your Name" (db)
将 db.auth、KEK.auth 和 PK.auth 文件从 /etc/uefi-keys 复制到 FAT 格式的文件系统。
重启并进入您的 UEFI (Fx 键取决于您的笔记本电脑)
导入密钥到 UEFI
这只是一个来自 XPS 笔记本电脑的例子,每个 UEFI 都是独一无二的。
- 进入 Boot Configuration > Secure Boot
- 将 Enable Secure Boot 更改为 ON
- 将 Secure Boot Mode 更改为 Deployed Mode
- 将 Enable Custom Mode 更改为 ON
- 进入 Custom Mode Key Management
- 重置所有密钥
- Select Key Database 选择 db > Replace from file > 选择您的闪存驱动器 > 选择 db.auth
- Select Key Database 选择 KEK > Replace from file > 选择您的闪存驱动器 > 选择 KEK.auth
- Select Key Database 选择 PK > Replace from file > 选择您的闪存驱动器 > 选择 PK.auth
- APPLY CHANGES > EXIT
检查安全启动状态
# apk add mokutil # mokutil --sb-state SecureBoot enabled
恭喜!
在加密的 LVM 交换分区上休眠
找到您的 vg0-swap UUID
lsblk -f
将 resume 参数添加到您的 /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT=....resume=UUID=<UUID of your vg0-swap partition>
在您的 /etc/fstab 中添加一行
/dev/vg0/swap none swap sw 0 0
在启动期间启用 swap 服务
rc-update add swap default
安装 zzz 并测试它
# apk add zzz zzz- Z
完成并恭喜!