Ubuntu full disk encryption with encrypted /boot
I'm trying to setup a full encrypted disk with a separate /boot
partition and I'm having some troubles.
I'll write down the procedure I've been following on a Ubuntu 15.04 Live DVD session.
-
Fill the disk with 'random data'
sudo dd if=/dev/urandom of=/dev/sda1 bs=4096 #ok
-
Create the partitions (using gparted)
- Create Partition Table - gpt
2.
- /dev/sda1 ext2 1.5GB #boot
- /dev/sda2 linux-swap 4GB #swap
- /dev/sda3 ext4 15 GB #root
- /dev/sda4 ext4 FREESPACE #home
- Create Partition Table - gpt
2.
-
Encrypt volumes
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
-
Open cryptovolume
cryptsetup luksOpen /dev/sda1 boot cryptsetup luksOpen /dev/sda2 swap cryptsetup luksOpen /dev/sda3 root cryptsetup luksOpen /dev/sda4 home
-
Format
mkfs.ext2 /dev/mapper/boot mkswap /dev/mapper/swap mkfs.ext4 /dev/mapper/root mkfs.ext2 /dev/mapper/home
-
Install (using Ubiquity)
- boot loader on /dev/sda
- /dev/sda1 - use as ext2 - mount point /boot
- /dev/sda2 - use as ext2 - mount point /boot
- /dev/sda3 - use as ext2 - mount point /boot
- /dev/sda4 - use as ext2 - mount point /boot
At the end the installer warns that grub-install failed (because the boot volume is encrypted), so choose 'continue without bootloader'.
-
Clean boot volume
mkfs.ext2 /dev/mapper/boot
-
Mount volume
mkdir /mnt/root mount /dev/mapper/root /mnt/root mount /dev/mapper/boot /mnt/root/boot
-
Update fstab and 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"]
-
fstab
#<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
-
crypttab
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
-
Update initramfs image
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
-
Configure bootloader (
/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:"
-
create config file
$ grub-mkconfig -o /boot/grub/grub.cfg [/usr/sbin/grub-probe: error: failed to get canonical path of `/dev/mapper/root'.]
-
try outside
$ exit $ grub-mkconfig -o /boot/grub/grub.cfg [/usr/sbin/grub-probe: error: failed to get canonical path of `/cow'.]
Did I make any mistake before this? How can I continue to configure and install grub correctly?
Solution 1:
You made some mistakes, but the main problem is in ubiquity and grub. Basically, when you set /
to be an encrypted partition and don't create a separate partition for /boot
, grub gives an error message like:
I know
/boot
is encrypted. You need to setGRUB_ENABLE_CRYPTODISK=y
in/etc/default/grub
. I won't do it for you, so I'm going to fail and your installation will stop.
An overview of the process
- We use EFI mode.
- We install to an unencrypted
/boot
partition and an encrypted btrfs/
using the standard installer. - After the installer finishes, we
chroot
, make some important configuration changes, and re-install grub to the EFI System Partition and re-create initrd.
The detailed steps
- Boot from Ubuntu 16.04 install disk (tested with Xubuntu).
- Connect to the Internet and run
sudo apt update && sudo apt upgrade
to update the installer components - Use
fdisk
,gparted
, or another tool to create 3 partitions:- A GPT partition table
- A 200MB partition that we will use for the EFI System Partition
- A multi-gigabyte partition that we will eventually use as our encrypted swap partition, but which will function as our temporary unencrypted
/boot
- An encrypted partition that uses the rest of the space
-
Prepare the encrypted partition
sudo cryptsetup luksFormat /dev/sda3 sudo cryptsetup luksOpen --allow-discards /dev/sda3 sda3_crypt sudo mkfs.btrfs /dev/mapper/sda3_crypt
-
Install Ubuntu
- Choose "Something else" when asked about installation type.
- Configure
/dev/sda1
asEFI System Partition
- Configure
/dev/sda2
as ext2, formatted, with mount point of/boot
- Configure
/dev/mapper/sda3_crypt
as btrfs with mount point of/
- Continue with the installation.
- After it finishes, choose to stay in the live system (no reboot).
-
Copy the contents of
/boot
and do achroot
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
(Everything is now happening as
chroot
inside your new system.)-
Add line to
/etc/default/grub
GRUB_ENABLE_CRYPTODISK=y
-
Add line to
/etc/crypttab
. You will need to first runsudo blkid
to find the UUID of/dev/sda3
(NOT/dev/mapper/sda3_crypt
).sda3_crypt UUID=<UUID of /dev/sda3> none luks,discard
Edit
/etc/fstab
and delete the line for/boot
. The other entries are correct.-
Install grub to the EFI System Partition, generate a new grub.cfg, and prepare 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
Optional double-check: Double-check that
/boot/efi/EFI/ubuntu/grub/grub.cfg
contains lines that includeinsmod luks
,cryptomount -u <UUID>
, the correct boot entries, etc. And double-check that your initrd contains thecryptsetup
binary. If these things are missing, it is because grub-mkconfig and/or update-initrd couldn't figure out how the volumes that you've mounted or specified in fstab relate to the encrypted volume in crypttab. (There's a lot of magic autoconfiguration that they do.) This may happen if you diverge from this guide by, for example, using ZFS or by trying to partition sda3_crypt.(If using ZFS instead of btrfs) grub-mkconfig and update-initrd won't recognize ZFS. The workaround involves (during chroot, prior to grub-mkconfig/update-initrd) editing
/usr/sbin/grub-mkconfig
to add|| true
to line 139 (which starts withGRUB_DEVICE=
), addingGRUB_DEVICE="/dev/mapper/sda3_crypt"
to/etc/default/grub
, creating file/usr/share/initramfs-tools/conf-hooks.d/forcecryptsetup
with contentsexport CRYPTSETUP=y
and file/etc/initramfs-tools/conf.d/cryptroot
with contentstarget=sda3_crypt,source=UUID=<UUID of sda3>,key=none,discard
. All of this is in addition to steps that you would take if you were not encrypting the ZFS partiion (like installing zfs userspace utils in both the live system and during chroot and deleting the line that mounts/
in fstab).-
Exit chroot and reboot into your new system
exit sudo umount /target/boot/efi sudo umount /target/dev sudo umount /target/proc sudo umount /target/sys sudo umount /target sudo reboot
You should see grub asking for your password. Then you'll get the boot menu. After choosing Ubuntu you'll be asked for your password again. Then you'll be in your system. Read more about how Ubuntu uses BTRFS.
TODO: Create encrypted swap (hint: it involves editing crypttab, fstab, and re-running
update-initrd
).- TODO: Save your password so you only need to enter it once into grub. This is detailed here.
Upgrades
- Every time you install a new kernel, you should run the custom
grub-mkconfig
command. - Every time you update grub, you should run the custom
grub-install
command.
Other notes
- It's tempting to create a single encrypted volume and partition it to create the swap partition (and possibly others), but this does not work. Both grub-mkconfig and update-initrd will misbehave. However, I haven't tried LVM.
- It may be tempting to use a swapfile on top of btrfs, but it's probably a bad idea because of performance.