问题描述
我的系统是Windows 10(sdb)和Manjaro(sda)安装在单独硬盘上的双重引导。 Windows系统驱动器使用bitlocker进行加密,而Manjaro通过LUKS上的LVM通过以下(lsblk)进行加密。
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 931.5G 0 disk
├─sda1 8:1 0 619M 0 part /boot/efi
├─sda2 8:2 0 232.8G 0 part
│ └─cryptroot 254:0 0 232.8G 0 crypt
│ ├─vg0-swap 254:1 0 32G 0 lvm [SWAP]
│ ├─vg0-system 254:2 0 20G 0 lvm /
│ └─vg0-data 254:3 0 180.8G 0 lvm /home
└─sda5 8:5 0 698.1G 0 part
sdb 8:16 0 232.9G 0 disk
├─sdb1 8:17 0 499M 0 part
├─sdb2 8:18 0 100M 0 part
├─sdb3 8:19 0 16M 0 part
└─sdb4 8:20 0 232.3G 0 part
我将grub2设置为默认的引导加载程序(安装在Manjaro上),它可以要求我通过菜单选择是启动Windows还是Manjaro。但是,问题是在给我该菜单之前,它会询问(LUKS FDE)密码。结果,由于Windows已经使用bitlocker进行了加密,因此我将不得不在LUKS密码之后输入Windows bitlocker密码,这非常不方便。 (令人惊讶的是,如果我想引导至Manjaro,则无需两次输入LUKS密码)
由于Windows和Manjaro安装在不同的物理硬盘驱动器上,并且启动分区未加密(如上所示),因此当我要启动到Windows时,grub不需要询问我LUKS的密码。它应该首先显示菜单,并且仅当我选择启动到Manjaro时才询问LUKS密码。但是我不确定如何配置它,也找不到很多资源。
这是我的grub配置文件(位于/etc/default/grub
)
GRUB_DEFAULT=saved
GRUB_TIMEOUT=10
GRUB_TIMEOUT_STYLE=hidden
GRUB_DISTRIBUTOR="Manjaro"
GRUB_CMDLINE_LINUX_DEFAULT="quiet udev.log_priority=3"
GRUB_CMDLINE_LINUX="cryptdevice=UUID=<uuid_is_hidden>:cryptroot"
# If you want to enable the save default function,uncomment the following
# line,and set GRUB_DEFAULT to saved.
GRUB_SAVEDEFAULT=true
# Preload both GPT and MBR modules so that they are not missed
GRUB_PRELOAD_MODULES="part_gpt part_msdos"
# Uncomment to enable booting from LUKS encrypted devices
GRUB_ENABLE_CRYPTODISK=y
# Uncomment to use basic console
GRUB_TERMINAL_INPUT=console
# Uncomment to disable graphical terminal
#GRUB_TERMINAL_OUTPUT=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command 'videoinfo'
GRUB_GFXMODE=auto
# Uncomment to allow the kernel use the same resolution used by grub
GRUB_GFXPAYLOAD_LINUX=keep
# Uncomment if you want GRUB to pass to the Linux kernel the old parameter
# format "root=/dev/xxx" instead of "root=/dev/disk/by-uuid/xxx"
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
GRUB_DISABLE_RECOVERY=true
# Uncomment and set to the desired menu colors. Used by normal and wallpaper
# modes only. Entries specified as foreground/background.
GRUB_COLOR_NORMAL="light-gray/black"
GRUB_COLOR_HIGHLIGHT="green/black"
# Uncomment one of them for the gfx desired,a image background or a gfxtheme
#GRUB_BACKGROUND="/usr/share/grub/background.png"
GRUB_THEME="/usr/share/grub/themes/manjaro/theme.txt"
# Uncomment to get a beep at GRUB start
#GRUB_INIT_TUNE="480 440 1"
解决方法
好的,经过大量研究,我想出了一个解决方案,但这可能不是最佳解决方案(请参见下面的注意事项)。
请注意lsblk
├─sda1 8:1 0 619M 0 part /boot/efi
/boot
分区实际上是加密的,但efi分区/boot/efi
除外。我记得这是安装manjaro时的推荐设置(可能是默认设置)。因为grub将从/boot/grub/grub.cfg
中读取菜单项,所以它必须首先解密LUKS卷(/boot/grub
已加密)。因此,如果我们希望grub在输入密码之前显示菜单项,则必须确保/boot/grub/grub.cfg
未加密。
执行此操作的一种方法是将sda1
挂载为/boot
而不是/boot/efi
。为此,我们首先需要在/etc/fstab
中进行更改以更改安装目标。然后,我们需要将所有文件从/boot
复制到sda1
。您可能需要在此过程中重新安装grub
并重新生成initramfs
。以下命令对此很有用。
sudo mkinitcpio -P
sudo grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=manjaro --recheck
sudo grub-mkconfig -o /boot/grub/grub.cfg
最后,您需要注释GRUB_ENABLE_CRYPTODISK=y
中的行/etc/default/grub
以禁用从grub解密。
完成所有操作后,运行以下命令以更新grub以写入更改。
sudo update-grub
几个警告
- 正如我在问题中提到的那样,原始设置不需要在grub中输入密码后再次输入LUKS密码。这是因为密钥文件已嵌入
initramfs
中,因此不需要密码即可解锁LUKS卷,有关详细信息,请参见here。由于在新设置中/boot
未加密,因此我们不能在initramfs
中包含此密钥文件。为此,请修改mkinitcpio
的配置文件(默认文件应为/etc/mkinitcpio.conf
)以删除密钥文件(在FILES=(...)
下),然后重新生成initramfs
。 - 从安全性的角度来看,挂载
/boot/efi
而不是/boot
的默认和推荐设置可提供更好的安全性,因为唯一未加密的部分是EFI二进制文件(grubx64.efi
)。但是,在我的设置中,initramfs
和linux内核映像(vmlinuz.img
)也未加密。攻击者可以将恶意代码注入这些文件中,这些文件在您输入密码后便会执行。
由于上述原因,我认为我的解决方案不是最好的,并且不确定是否存在其他解决方案而不牺牲太多安全性。
有用的链接:
https://wiki.manjaro.org/index.php/GRUB/Restore_the_GRUB_Bootloader https://wiki.archlinux.org/index.php/GRUB https://wiki.archlinux.org/index.php/Mkinitcpio#Image_creation_and_activation