使用加密 /boot 的 Ubuntu 全盘加密

Nic*_*eda 16 encryption grub2

我正在尝试使用单独的/boot分区设置完整的加密磁盘,但遇到了一些麻烦。

我将写下我在 Ubuntu 15.04 Live DVD 会话中一直遵循的过程。

  • 用“随机数据”填充磁盘

    sudo dd if=/dev/urandom of=/dev/sda1 bs=4096   #ok
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建分区(使用 gparted)

    1. 创建分区表 - gpt 2。
      • /dev/sda1 ext2 1.5GB #boot
      • /dev/sda2 linux-swap 4GB #swap
      • /dev/sda3 ext4 15 GB #root
      • /dev/sda4 ext4 自由空间#home
  • 加密卷

    cryptsetup luksFormat --cipher twofish-xts-plain64 --key-size 512
                          --hash sha512 --iter-time 3000 /dev/sda1
    cryptsetup luksFormat --cipher twofish-xts-plain64 --key-size 512
                          --hash sha512 --iter-time 3000 /dev/sda2
    cryptsetup luksFormat --cipher twofish-xts-plain64 --key-size 512
                          --hash sha512 --iter-time 3000 /dev/sda3
    cryptsetup luksFormat --cipher twofish-xts-plain64 --key-size 512
                          --hash sha512 --iter-time 5000 /dev/sda4
    
    Run Code Online (Sandbox Code Playgroud)
  • 打开加密卷

    cryptsetup luksOpen /dev/sda1 boot
    cryptsetup luksOpen /dev/sda2 swap
    cryptsetup luksOpen /dev/sda3 root
    cryptsetup luksOpen /dev/sda4 home
    
    Run Code Online (Sandbox Code Playgroud)
  • 格式

    mkfs.ext2 /dev/mapper/boot
    mkswap /dev/mapper/swap
    mkfs.ext4 /dev/mapper/root
    mkfs.ext2 /dev/mapper/home
    
    Run Code Online (Sandbox Code Playgroud)
  • 安装(使用 Ubiquity)

    • /dev/sda 上的引导加载程序
    • /dev/sda1 - 用作 ext2 - 挂载点 /boot
    • /dev/sda2 - 用作 ext2 - 挂载点 /boot
    • /dev/sda3 - 用作 ext2 - 挂载点 /boot
    • /dev/sda4 - 用作 ext2 - 挂载点 /boot

    最后,安装程序警告 grub-install 失败(因为引导卷已加密),因此选择“不使用引导加载程序继续”。

  • 干净启动卷

    mkfs.ext2 /dev/mapper/boot
    
    Run Code Online (Sandbox Code Playgroud)
  • 挂载卷

    mkdir /mnt/root
    mount /dev/mapper/root /mnt/root
    mount /dev/mapper/boot /mnt/root/boot
    
    Run Code Online (Sandbox Code Playgroud)
  • 更新 fstab 和 crypttab

    sudo blkid
    
    [/dev/sr0: UUID="2015-10-21-16-17-40-00" LABEL="Ubuntu 15.10 amd64"
               TYPE="iso9660" PTUUID="429817b4" PTTYPE="dos"
    /dev/sda1: UUID="...#1" TYPE="crypto_LUKS" PARTUUID="..."
    /dev/sda2: UUID="...#2" TYPE="crypto_LUKS" PARTUUID="..."
    /dev/sda3: UUID="...#3" TYPE="crypto_LUKS" PARTUUID="..."
    /dev/sda4: UUID="...#4" TYPE="crypto_LUKS" PARTUUID="..."
    /dev/mapper/boot: UUID="..." TYPE="ext2"
    /dev/mapper/swap: UUID="..." TYPE="swap"
    /dev/mapper/root: UUID="..." TYPE="ext4"
    /dev/mapper/home: UUID="..." TYPE="ext4"]
    
    Run Code Online (Sandbox Code Playgroud)
  • #<file system>   <mount point>   <type>   <options>           <dump>   <pass>
    UUID=#1          /boot           ext2     defaults            0        2
    UUID=#2          none            swap     sw                  0        0
    UUID=#3          /               ext4     errors=remount-ro   0        1
    UUID=#4          /home           ext4     defaults            0        2
    
    Run Code Online (Sandbox Code Playgroud)
  • 密码表

    boot   UUID=#1   luks,cipher=twofish-xts-plain64,size=512,
                     hash=whirlpool, time=3000
    swap   UUID=#2   luks,swap,cipher=twofish-xts-plain64,size=512,
                     hash=whirlpool,time=3000
    root   UUID=#3   luks,cipher=twofish-xts-plain64,size=512,
                     hash=whirlpool,time=3000
    home   UUID=#4    luks,cipher=twofish-xts-plain64,size=512,
                      hash=whirlpool,time=5000
    
    Run Code Online (Sandbox Code Playgroud)
  • 更新 initramfs 映像

    cd /mnt
    sudo chroot root
    mount -t proc proc /proc
    mount -t sysfs sys /sys
    mount -t devpts devpts /dev/pts
    update-initramfs -u                      #ok
    
    Run Code Online (Sandbox Code Playgroud)
  • 配置引导加载程序 ( /etc/default/grub)

    GRUB_ENABLE_CRYPTODISK=y
    GRUB_PRELOAD_MODULES="luks cryptodisk"
    GRUB_CMDLINE_LINUX="cryptdevice=UUID#3:root root=/dev/mapper/root resume=/dev/mapper/swap 
                        crypto=whirlpool:twofish-xts-plain64:512:0:"
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建配置文件

    $ grub-mkconfig -o /boot/grub/grub.cfg
    [/usr/sbin/grub-probe: error: failed to get canonical path of `/dev/mapper/root'.]
    
    Run Code Online (Sandbox Code Playgroud)
  • 在外面试试

    $ exit
    $ grub-mkconfig -o /boot/grub/grub.cfg
    [/usr/sbin/grub-probe: error: failed to get canonical path of `/cow'.]
    
    Run Code Online (Sandbox Code Playgroud)

在此之前我是否犯了任何错误?如何继续正确配置和安装 grub?

Ale*_*sky 14

您犯了一些错误,但主要问题在于无处不在和 grub。基本上,当您设置/为加密分区并且不为 单独创建分区时/boot,grub 会给出如下错误消息:

我知道/boot是加密的。您需要GRUB_ENABLE_CRYPTODISK=y/etc/default/grub. 我不会为你做这件事,所以我会失败,你的安装会停止。

流程概览

  • 我们使用 EFI 模式。
  • 我们使用标准安装程序安装到未加密的/boot分区和加密的 btrfs /
  • 安装程序完成后,我们chroot进行一些重要的配置更改,并将 grub 重新安装到 EFI 系统分区并重新创建 initrd。

详细步骤

  • 从 Ubuntu 16.04 安装盘启动(用 Xubuntu 测试)。
  • 连接到 Internet 并运行sudo apt update && sudo apt upgrade以更新安装程序组件
  • 使用fdiskgparted或其他工具创建 3 个分区:
    • GPT 分区表
    • 我们将用于 EFI 系统分区的 200MB 分区
    • 我们最终将用作加密交换分区的多 GB 分区,但它将用作我们的临时未加密分区 /boot
    • 使用剩余空间的加密分区
  • 准备加密分区

    sudo cryptsetup luksFormat /dev/sda3
    sudo cryptsetup luksOpen --allow-discards /dev/sda3 sda3_crypt
    sudo mkfs.btrfs /dev/mapper/sda3_crypt
    
    Run Code Online (Sandbox Code Playgroud)
  • 安装 Ubuntu

    • 当询问安装类型时选择“其他”。
    • 配置/dev/sda1EFI System Partition
    • 配置/dev/sda2为ext2,格式化,挂载点为/boot
    • 配置/dev/mapper/sda3_crypt为 btrfs,挂载点为/
    • 继续安装。
    • 完成后,选择留在实时系统中(不重新启动)。
  • 复制内容/boot并做一个chroot

    sudo mount -o subvol=@ /dev/mapper/sda3_crypt /target
    sudo mount /dev/sda2 /mnt
    # (Watch those trailing slashes! rsync is very sensitive to them.)
    sudo rsync -aXAH /mnt/ /target/boot/
    sudo mount /dev/sda1 /target/boot/efi
    sudo mount --bind /dev /target/dev
    sudo mount --bind /proc /target/proc
    sudo mount --bind /sys /target/sys
    sudo chroot /target
    
    Run Code Online (Sandbox Code Playgroud)
  • (现在一切都chroot在您的新系统中发生。)

  • 添加行到 /etc/default/grub

    GRUB_ENABLE_CRYPTODISK=y
    
    Run Code Online (Sandbox Code Playgroud)
  • 添加行到/etc/crypttab. 您需要先运行sudo blkid以找到/dev/sda3(NOT /dev/mapper/sda3_crypt)的 UUID 。

    sda3_crypt UUID=<UUID of /dev/sda3> none luks,discard
    
    Run Code Online (Sandbox Code Playgroud)
  • 编辑/etc/fstab并删除/boot. 其他条目是正确的。

  • 将 grub 安装到 EFI 系统分区,生成新的 grub.cfg,并准备 initrd。

    sudo grub-install --target=x86_64-efi --efi-directory /boot/efi --bootloader=ubuntu --boot-directory=/boot/efi/EFI/ubuntu --recheck
    sudo grub-mkconfig -o /boot/efi/EFI/ubuntu/grub/grub.cfg
    sudo update-initramfs -c -k all
    
    Run Code Online (Sandbox Code Playgroud)
  • 可选的双重检查:双重检查/boot/efi/EFI/ubuntu/grub/grub.cfg包含的行包括insmod lukscryptomount -u <UUID>、正确的引导条目等。并双重检查您的 initrd 是否包含cryptsetup二进制文件。如果缺少这些东西,那是因为 grub-mkconfig 和/或 update-initrd 无法弄清楚您在 fstab 中安装或指定的卷如何与 crypttab 中的加密卷相关。(他们做了很多神奇的自动配置。)如果您偏离本指南,例如使用 ZFS 或尝试对 sda3_crypt 进行分区,则可能会发生这种情况。

  • (如果使用 ZFS 而不是 btrfs) grub-mkconfig 和 update-initrd 将无法识别 ZFS。解决方法包括(在 chroot 期间,在 grub-mkconfig/update-initrd 之前)编辑/usr/sbin/grub-mkconfig添加|| true到第 139 行(以 开头GRUB_DEVICE=)、添加GRUB_DEVICE="/dev/mapper/sda3_crypt"/etc/default/grub、创建/usr/share/initramfs-tools/conf-hooks.d/forcecryptsetup包含内容的export CRYPTSETUP=y文件/etc/initramfs-tools/conf.d/cryptroot和包含内容的文件target=sda3_crypt,source=UUID=<UUID of sda3>,key=none,discard。如果您不加密 ZFS 分区(例如在实时系统和 chroot 期间安装 zfs 用户空间实用程序并删除安装/在 fstab 中的行),所有这些都是您将要采取的步骤的补充。

  • 退出 chroot 并重新启动到新系统

    exit
    sudo umount /target/boot/efi
    sudo umount /target/dev
    sudo umount /target/proc
    sudo umount /target/sys
    sudo umount /target
    sudo reboot
    
    Run Code Online (Sandbox Code Playgroud)
  • 您应该会看到 grub 要求您输入密码。然后你会得到启动菜单。选择 Ubuntu 后,系统会再次要求您输入密码。然后你就会进入你的系统。阅读更多关于Ubuntu 如何使用 BTRFS 的信息

  • TODO:创建加密交换(提示:它涉及编辑 crypttab、fstab 和重新运行update-initrd)。

  • 待办事项:保存您的密码,这样您只需在 grub 中输入一次。这是详细here

升级

  • 每次安装新内核时,都应该运行自定义grub-mkconfig命令。
  • 每次更新 grub 时,都应该运行自定义grub-install命令。

其他注意事项

  • 创建单个加密卷并对其进行分区以创建交换分区(可能还有其他分区)很诱人,但这不起作用。grub-mkconfig 和 update-initrd 都会出现错误行为。但是,我还没有尝试过 LVM。
  • 在 btrfs 之上使用交换文件可能很诱人,但由于性能原因,这可能是一个坏主意。