Biboroku

Creating a Debian Boot Partition on a USB Flash Drive

Written by Taro Sato, on . Tagged: linux

Having a boot partition on a USB flash drive provides two major benefits. One is to have the USB flash drive work as a “security key” without which the computer cannot boot into an OS; effectively, the boot USB flash drive becomes a house key. Another is to provide the consolidated storage for an encryption key to encrypt the main SSD drive.

Bootstrapping a Debian system to boot in this particular way is done at an installation time. This document outlines that process. We will provide the detailed steps only for partitioning storage devices (i.e., the main SSD drive and the USB flash drive), but not for the entire Debian installation. This is to keep the document succinct, but also because they are the only part that is different from the standard Debian installation steps.

What You Need

  • A Debian install medium (likely a USB flash drive)
  • A computer on which Debian is being installed
  • One unused USB flash drive on which to put the /boot partition

The unused USB flash drive must be different from the one with the Debian install media.

Here is a note about the /boot partition size: I would recommend that the USB flash drive to have at least 500 MB of storage space. The ideal size depends on usage, but the very minimal size should be determined by how many kernel-related files you would want to keep in the boot partition at a time. The very minimum number of kernel versions to keep is two, one for the main use and another for fallback or backup. As of writing, each kernel would need about 80 MB (for config, initrd.img, and vmlinuz files), which might be larger or smaller depending on how much you customize the kernel. The idea is to have enough space to keep all the kernel versions that you need available on boot. In reality, it is increasingly rare to be found in retail USB flash drives with less than 8 GB of storage, and there is no harm in using that much space for your boot partition.

I now assume that you are in the process of Debian installation, and right before the step for partitioning the hard drive(s).

Creating a Boot Partition on a USB Flash Drive

Before getting to the “Detect disks” step of the Debian installer, make sure that the unused USB flash drive is already plugged into the computer.

When you get to the “Partition disks” step, choose “Manual” as “Partitioning method.”

Identify the device name for the unused USB flash drive, e.g., “SCSI (0,0,0) (sdb).”

Select that entire device to create a new empty partition table on it.

Create a new EFI System partition on its free space:

  • Partition size: 128 MB
  • Location for the new partition: Beginning
  • Partition settings:
    • Use as: EFI System Partition
    • Bootable flag: on

Create a new boot partition on its remaining free space:

  • Partition size: (use all the remaining free space)
  • Partition settings:
    • Use as: Ext2 file system
    • Mount point: /boot
    • Mount options: defaults
    • Label: none
    • Reserved blocks: 5%
    • Typical usage: standard
    • Bootable flag: off

The newly partitioned USB flash drive is now set up to be and hold the entire /boot partition.

Creating an Encrypted Partition on an SSD Drive

You will use the entirety of the SSD drive as an encrypted volume. Inside, the logical volumes for the / (root) partition and the SWAP partition will be created.

Throughout the current process, you may be asked a question “Write changes to disk and configure (something).” Be ready to answer “Yes” to this question. All the actions going forward are destructive, and all data on the SSD drive will be cleared.

Creating the Encrypted Volume

Select that entire SSD drive to create a new empty partition table on it.

Create a new partition on its free space with the following configuration:

  • Partition size: (use all the remaining free space)
  • Partition settings:
    • Use as: physical volume for encryption
    • Encryption method: Device-mapper (dm-crypt)
    • Encryption: aes
    • Key size: 256
    • IV algorithm: xts-plain64
    • Encryption key: Passphrase
    • Erase data: yes
    • Bootable flag: off

Choose “Configure encrypted volumes”:

  • Encryption configuration actions: Finish
  • Really erase the data on …: Yes
  • Type encryption passphrase: (choose wisely)

Configuring the Logical Volume Manager

Choose “Configure the Logical Volume Manager.”

Creating a volume group

Under “LVM configuration action,” choose “Create volume group”:

  1. Volume group name: vg
  2. Devices for the new volume group: /dev/mapper/* (choose encrypted device)

Creating logical volumes

Under “LVM configuration action,” choose “Create logical volume” for the swap space:

  1. Volume group: vg
  2. Logical volume name: swap
  3. Logical volume size: (roughly the same as RAM)

Under “LVM configuration action,” choose “create logical volume” for the root partition:

  1. Volume group: vg
  2. Logical volume name: root
  3. Logical volume size: (the remaining free space)

Under “LVM configuration action,” choose “Finish.”

Creating the Root and SWAP Partitions in Logical Volumes

Select the logical volume named “root” and configure the partition:

  • Partition settings:
    • Use as: Ext4 journaling file system
    • Mount point: /
    • Mount options: defaults
    • Label: none
    • Reserved blocks: 5%
    • Typical usage: standard

Select the logical volume named “swap” and configure the partition:

  • Partition settings:
    • Use as: swap area

Finally, choose “Finish partitioning and write changes to disk.”

  • Write changes to disks: Yes

Follow and complete the rest of the Debian installation. Before the very first reboot, keep the boot USB flash drive plugged in, but remove the USB flash drive with the Debian install media.

Upon reboot, make sure that you can boot into the Debian login screen using the encryption passphrase that you set up earlier.

Move on to the next section once you confirm that you may log in on the newly bootstrapped machine as root. The shortcut Alt + Ctrl + F2 may be useful for console login as root.

Storing SSD Drive Encryption Key File in the Boot USB Flash Drive

In this section, we replace the encryption passphrase with a key file and store it in the boot USB stick. The key file will be encrypted with a (possibly different) passphrase using GnuPG.

Boot off the boot USB flash drive, and use Alt + Ctrl + F2 to log in as root via console. All the shell commands below are meant to be executed as root.

Generate a random key file:

dd if=/dev/urandom of=/keyfile bs=512 count=16

Look in /etc/crypttab for a line that looks like this:

nvme0n1p1_crypt UUID=<uuid> none luks,discard

where <uuid> depends on your hardware. Take note of the device name here (nvme0n1p1), as it may be different for your machine. It should refer to the encrypted volume of the SSD. Change that line to:

nvme0n1p1_crypt UUID=<uuid> /boot/keyfile.gpg luks,keyscript=/lib/cryptsetup/scripts/decrypt_gnupg

Add the key file to the LUKS keyring:

/sbin/cryptsetup luksAddKey /dev/nvme0n1p1 /keyfile

When asked, type in the existing passphrase created for the encrypted volume during the Debian installation process.

Encrypt the key file with gpg:

gpg -c --cipher-algo AES256 /keyfile

When asked, enter a (new) passphrase. Keep in mind that it is for encrypting the key file, not the volume this time. Thus, it can be the same as the one for the encrypted volume used earlier, as eventually, we will only keep the passphrase created in the current step.

Move the GPG file just created to the boot USB flash drive at /boot/keyfile.gpg:

mv /keyfile.gpg /boot/keyfile.gpg

Update the initramfs:

/sbin/update-initramfs -u

Reboot.

Once the reboot is successful, notice that you will get prompted for a passphrase of the encrypted key file, not the encrypted volume this time. Log in as root again, and remove the raw encryption key file created for temporary use:

cryptsetup luksKillSlot /dev/nvme0n1p1 0 --key-file /keyfile
shred -n 30 -uvz /keyfile

At this point, the boot USB flash drive becomes the “key” and will be the only way to boot this machine.

Once the computer boots, you may unmount the boot partition

Removing the Boot USB Flash Drive

After the successful boot, you may want to remove the boot USB flash drive. (You don’t want your key left inserted!)

Unmount the boot partition as follows:

sudo umount /boot/efi
sudo umount /boot

Then, physically remove the boot USB flash drive.

Waking up from Hibernation

When hibernation is active, you will need the boot USB flash drive to wake up the computer to boot back into the hibernated session.

With regular sleep (suspend-to-RAM), you will not need the boot USB flash drive.

Don’t forget to bring along your boot USB flash drive when traveling with a computer in hibernation.

Creating Spare USB Flash Drives

Like any other (physical) keys, you might want to keep a spare in case you lose it. It is easy to create one as follows.

First, obtain the device paths pointing to the master USB flash drive and the spare USB flash drive:

fdisk -l

Say, you have the master at /dev/sda and the spare at /dev/sdb. Then use dd to create an image dump of the master, and use it to create a spare:

dd if=/dev/sda of=/tmp/boot-key.img bs=16M  # generate an image of the master
dd if=/tmp/boot-key.img of=/dev/sdb bs=16M  # create the spare from the image

Of course, both USB flash drives need not be present at the same time. Just be very, very careful with the device paths when you insert/remove the USB devices, as it is easy to misremember the device reference and destroy important data.

Handling Kernel Updates

A maintenance release of Debian sometimes includes a kernel upgrade. Since Linux kernel-related files are stored in the /boot directory, such an update must be done while the boot USB flash drive is mounted on the computer.

Check if a pending Debian update includes a kernel update:

sudo apt update
sudo apt list --upgradable

If the list includes packages named like linux-image-*, that kernel will be installed upon the next APT upgrade, and the relevant kernel files will be created under /boot. For each kernel version, the following files would exist:

  • System.map-<x.x.x-x>-amd64
  • config-<x.x.x-x>-amd64
  • initrd.img-<x.x.x-x>-amd64
  • vmlinuz-<x.x.x-x>-amd64

where <x.x.x-x> is the kernel version and its revision number.

Insert the boot USB flash drive, and mount the boot partition if not done so already:

sudo mount /boot
sudo mount /boot/efi

Then, perform APT upgrade:

sudo apt upgrade

Especially if you manage more than one boot USB flash drive, a nice thing to remember is how to reinstall a package. With a kernel image, the command would look like this:

sudo apt install --reinstall linux-image-<x.x.x-x>-amd64

The kernel reinstall would become necessary when you have more than one boot USB flash drive to keep in sync with each other. Essentially, you need to repeat the kernel upgrade process for each boot USB flash drive, and the apt install --reinstall command above is all that is necessary.

Finally, purging the kernel package will remove the kernel-related files from the /boot directory:

dpkg -l | grep linux-image-*  # list installed kernel versions
sudo dpkg -P linux-image-<x.x.x-x>-amd64  # perge specific kernel version

You may need to perform this cleanup occasionally if your boot partition is small.