自用一台 Lenovo Thinkpad X13 机器,打算给自己装 Windows 和 Linux 的双系统。为了安全,我打算安装 Gentoo Linux 的同时启用SecureBoot来保证启动的安全。
Gentoo系统的安装
- 安装 Gentoo Linux 之前,需要先关闭 BIOS 中的
SecureBoot选项,因为 Gentoo 官方的安装镜像并不直接支持SecureBoot,必须关闭之后才能正常引导。 - 参考官方的WIKI来安装 Gentoo 系统,需要注意两点:
- 需要使用带
systemd的 Profile,同时安装 BootLoader 的时候使用systemd-boot作为引导 - 确保能正常在非
SecureBoot情况下正常进入系统之后,才可以进行之后的配置
- 需要使用带
Gentoo使用SecureBoot的原理(可跳过)
Gentoo 等 Linux 系统想要使用SecureBoot机制,通用的办法是手动使用类似sbctl工具去修改 UEFI Firmware 证书配置等,并且对kernel和initramfs等签名来实现SecureBoot引导(具体步骤可参考 Gentoo Wiki - SecureBoot)。但是这一种方法有两个明显的问题,第一是比较复杂而且风险很大,出错的话容易导致 UEFI Firmware 整个出错,甚至无法开机等。第二是修改使用自签名的证书,没办法支持 Windows 和 Linux 的同时启动。
而通过预签名的shim的方式则相对简单得多,预签名shim是 Ubuntu 社区提供的,经过 Microsoft 签名的引导器,可以直接通过SecureBoot。通过向shim添加信任的证书,再通过证书链方式签名kernel和initramfs,可以更简单的使用SecureBoot。同时因为shim作为独立的引导器,并不会和 Windows 自带的引导冲突,所以可以轻松的实现双系统。
使用shim来启用SecureBoot
安装配置shim
1 | emerge --ask sys-boot/shim sys-boot/mokutil sys-boot/efibootmgr |
1 | bootctl install --no-variables |
1 | cp /usr/share/shim/BOOTX64.EFI /efi/EFI/systemd/shimx64.efi |
1 | cp /usr/share/shim/mmx64.efi /efi/EFI/systemd/mmx64.efi |
最后使用efibootmgr手动添加引导项。注意需要把/dev/boot-disk和boot-partition-id替换成自己对应的 boot 分区。比如我自己 boot 分区的是/dev/nvme0n1p1,所以对应/dev/nvme0n1盘第1分区。
1 | efibootmgr --create --disk /dev/boot-disk \ |
此时,重启并在不启用SecureBoot的情况下,通过Systemd-boot via Shim启动项来进入系统,此时shim安装完成。
配置SecureBoot证书
接下来,需要创建我们自己的证书,并且添加进入shim的信任链中,之后再通过这个证书签名内核。
创建证书
1 | # 注意,可以根据自己的实际情况适当修改参数,特别是`--subj`,可以对应修改`CN`以便于更方便区分证书。 |
因为shim需要证书是 PEM 格式,所以需要将生成才证书转换为 PEM。
1 | openssl x509 -outform DER -in MOK.crt -out MOK.der |
使用mokutil管理证书
shim的证书可以使用mokutil来管理,常用的mokutil命令包括:
1 | # 列出已经导入的证书 |
- 通过下面的命令导入
MOK.der证书:1
2# 可能会让你输入密码,这个密码仅用于重启后确认
mokutil --import MOK.der - 重启电脑并通过
shim引导启动,此时选择Enroll Key选项来添加证书。 - 添加完成重启进入系统之后,可以通过
mokutil --list-enrolled,检查是否添加成功。
修改make.conf和package.use
完成添加证书之后,需要修改/etc/portage/make.conf来实现自动使用证书来签名内核。
1 | # Path to MOK.key |
原则上,kernel,initramfs和module都需要使用证书签名之后才可以在shim中使用,但是这相对来说比较麻烦,此时,我们使用 UKI (Unified kernel image),会更加方便,只需要对生成的合并 Image 签名即可以在shim中正常引导。所以,我使用dracut和installkernel来自动生成 UKI,并且自动签名。
- 修改
/etc/portage/package.use/installkernel文件,添加 USE flag1
sys-kernel/installkernel dracut systemd-boot uki
- 安装
dracut和installkernel1
emerge -a sys-kernel/installkernel sys-kernel/dracut
- 修改
/usr/lib/kernel/install.conf1
2
3layout=uki
initrd_generator=dracut
uki_generator=dracut - 修改
/etc/dracut.conf来启用自动签名1
2
3
4# Path to MOK.crt
uefi_secureboot_cert="..."
# Path to MOK.key
uefi_secureboot_key="..." - 重新配置 kenerl,如果是手动编译的,可以使用
make install重新配置。如果通过 package 安装,可以通过emerge --config gentoo-kernel{,-bin}来重新配置 kernel。 - 在不启用
SecureBoot的条件下重启电脑,如果能正常进入Linux,则可以开启SecureBoot来测试是否正常。