Because adding (more) cryptography solves all the problems.
GNU Grub 2 is an interestingly flexible piece of software, and supports several different variations on the theme of "read disk, load kernel, boot operating system". It has a feature where it can decrypt and read partitions on disks which are encrypted using the Linux kernel's LUKS scheme. This allows you to have an encrypted /boot
partition, which may be a desirable feature to have on your computer. Adelie Linux can be configured to support such a configuration, so I decided to reinstall the MacBook (again) to try this out.
I've tried to write this post in a tutorial-style manner so that other people can use it as a reference, and though I've written it in relation to installation on my MacBook, I'll make reference to the Adelie install guide throughout, as my MacBook is a bit weird and requires some special handling. Also, I'm installing in PC BIOS mode (more MacBook weirdness) -- if you wish to do this in UEFI mode, then you'll need to adapt these instructions for a UEFI installation.
The intended configuration is to partition the hard disk into two partitions: a smaller encrypted boot partition at the start of the disk for holding the kernel and initramfs, and an encrypted partition filling the rest of the disk containing an LVM2 volume group which contains the root filesystem and swap area. Suspend-to-disk should also be supported, and the bootloader and initramfs will be set up to enable this functionality. When the system boots, Grub will prompt for a password for the root directory, and the initramfs will prompt for the passwords for the boot partition and the LVM2 area.
Boot into an installation environment. Adelie has offical downloadable CD images for booting into a live environment for installation, but if you can't get those to boot (like I did with the MacBook), then find a live Linux image (such as the Arch Linux installation image) which does boot on your hardware, and download the Adelie root filesystem tarball onto removable media.
For the purposes of this post, the disk I'm installing onto is /dev/sda
. Change this if yours is different every time you see it.
Using your disk partitioning tool of choice (mine is fdisk(8)
), create two partitions -- I made the first one 500 MB in size, but that's a pretty arbitrary decision, so choose something sensible for your own system. The second partition should fill the rest of the disk. Set the bootable flag on the first partition.
Now, create the encrypted volumes. Both invocations of cryptsetup will prompt for passwords -- use something sensible and don't forget them.
# cryptsetup luksFormat /dev/sda1
# cryptsetup luksFormat /dev/sda2
Open the encrypted volumes so they can be used. More prompting for passwords will occur.
# cryptsetup open --type luks /dev/sda1 adelie-boot
# cryptsetup open --type luks /dev/sda2 adelie-lvm
Next, the LVM2 area is configured on the second, larger partition on the disk.
# vgcreate adelievg /dev/mapper/adelie-lvm
# lvcreate -L 4G adelievg -n swap # Adjust "4G" to match the amount of swap needed by your machine
# lvcreate -l 100%FREE adelievg -n root
Now filesystems can be set up and mounted. Note that I'm mounting the filesystems at /mnt
, while if you're using the Adelie installation image, you should use /target
.
# mkfs.ext4 /dev/mapper/adelie-boot
# mkfs.ext4 /dev/mapper/adelievg-root
# mkswap /dev/mapper/adelievg-swap
#
# mount /dev/mapper/adelievg-root /mnt
# mkdir /mnt/boot
# mount /dev/mapper/adelie-boot /mnt/boot
If you're in the Adelie installer, then at this point you should follow the steps given in the official installation guide down to the bootloader configuration. If not, then you should configure your host environment with an internet connection, extract the Adelie rootfs tarball over the mountpoint for the new filesystems, e.g. 'bsdtar -xvf adelie-rootfs-x86_64-1.0-beta-1-20180914.txz -C /mnt', chroot()
from your boot environment into the new installation and configure the hostname, networking and user accounts. In both cases, you should add fstab(5)
entries for your boot partition, root filesytem and swap area (using absolute paths like /dev/mapper/adelievg-root
is fine; typing out UUID's isn't necessary).
At this point, it's assumed that you've chroot()
ed into the new installation and have configured everything except for the bootloader. Install the required packages using apk add dracut-lvm dracut-crypt grub-bios
.
Next, the system will be configured to mount the encrypted boot partition when the system starts. Create the directory /etc/cryptkeys
(using mkdir -m 700 /etc/cryptkeys
or similar) and enter the passphrase for your boot partition into /etc/cryptkeys/boot
. Note that this file's entire contents is used as the key, so any trailing newline characters must be stripped from the file; it may be simplest to run echo -n "boot partition password" > /etc/cryptkeys/boot
to achieve this. The boot-time device-mapper support can now be configured by adding the following lines to /etc/conf.d/dmcrypt
:
target=adelie-boot
source=/dev/sda1
key=/etc/cryptkeys/boot
Execute rc-update add dmcrypt boot
and rc-update add swap boot
to open the encrypted boot partition and enable the use of the swap area at boot-time.
The initramfs can now be created. Adelie uses dracut for initramfs generation, the full configuration details for which can be found in dracut.conf(5)
. In particular, you can add additional kernel modules to the initramfs by creating a file (whose name should end in .conf
) in /etc/dracut.conf.d
containing lines like this:
add_drivers+="nouveau"
This example adds the nouveau
driver into the initramfs, which I need for my MacBook's GPU; the list of kernel modules here should be space-separated. The initramfs can now be generated by simply running dracut
, although if you've booted using a different kernel version from the one which has been installed into the new Adelie system (which is likely if you aren't using the Adelie installer image), then you'll need to add the --kver
option to the dracut invocation to instruct it to use the modules for the appropriate kernel version.
Now, Grub can be configured and installed. Enter something like the following into /etc/update-extlinux.conf
:
default_kernel_opts="resume=/dev/mapper/adelievg-swap rd.auto=1"
modules="nouveau"
root=/dev/mapper/adelievg-root
GRUB_DISTRIBUTOR=Adelie
The line starting "modules" is a list of any extra modules you explicitly wish to be loaded into the kernel at boot time -- I've specified the nouveau
module here again, however you may have modules which you don't require in the initramfs which you do wish to be loaded when the root filesystem has been mounted and the system is starting. The "resume" option is necessary to tell the kernel which device to attempt to unhibernate from, and the "rd.auto" option instructs the initramfs to automatically scan for and open any encrypted disks and LVM2 volumes. Next, create the file /etc/default/grub
and enter:
GRUB_ENABLE_CRYPTODISK=y
Grub can now be installed using grub-install --target=i386-pc --boot-directory=/boot /dev/sda
, and the configuration file generated with grub-mkconfig -o /boot/grub/grub.cfg
.
This finishes the installation, so you can now exit the chroot()
and reboot into the Adelie system. You should be prompted for the passphrase for the boot partition by Grub before it loads the boot menu, and when booting into Adelie, the initramfs should prompt for the passwords for both the boot partition and the root partition.
Hibernate and suspend support can be enabled by installing the pm-utils
package, which includes the pm-hibernate
and pm-suspend
command line utilities.