Pop!OS Linux: Creating a Bootable Backup USB With Encryption

For my Pop!OS Linux workstation, I wanted to have a complete backup on an USB drive. Of course, it needs to be encrypted, in case the USB drive gets lots. And to allow me to quickly resume working in the case of an emergency, I wanted the USB backup to be bootable, too. Here’s how I set that up:

1
2
3
4
5
# find /dev/sd* mountpoint for USB drive
lsblk

# open GDisk partition editor
sudo gdisk /dev/sdX

In gdisk:

  1. Create GPT table: o (create new empty GUID partition table)
  2. Create EFI System Partition:
    • n (new partition)
    • Partition number: 1
    • First sector: Enter (default)
    • Last sector: +512M (or +1G for larger ESP)
    • Hex code: ef00 (EFI System)
  3. Create root partition:
    • n (new partition)
    • Partition number: 2
    • First sector: Enter (default)
    • Last sector: Enter (use remaining space)
    • Hex code: 8300 (Linux filesystem)
  4. Write changes: w
1
2
3
4
5
# Set up LUKS encryption
sudo cryptsetup luksFormat /dev/sdX2

# Open the encrypted partition
sudo cryptsetup luksOpen /dev/sdX2 usb_crypt
1
2
3
4
5
# Format EFI System Partition as FAT32
sudo mkfs.fat -F32 /dev/sdX1

# Format encrypted partition as ext4
sudo mkfs.ext4 /dev/mapper/usb_crypt

Let’s mount the newly created filesystems so that I can fill them with data:

1
2
3
4
5
sudo mkdir -p /mnt/backup_usb
sudo mount /dev/mapper/usb_crypt /mnt/backup_usb

sudo mkdir -p /mnt/backup_usb/boot/efi
sudo mount /dev/sdX1 /mnt/backup_usb/boot/efi

I used rsync to copy over all of my data:

1
sudo rsync -avhPHAXx --numeric-ids --exclude={"/mnt/*","/media/*","/lost+found","/swapfile"} / /mnt/backup_usb/

In case you cannot remember (like me), here’s a list of the options:

Option Long Form Description
a --archive Archive mode - equivalent to -rlptgoD. Preserves recursion, links, permissions, timestamps, group, owner, and devices/specials.
v --verbose Verbose output
h --human-readable Output numbers using K, M, G suffixes
P --partial --progress Keep partially transferred files and show progress during transfer
H --hard-links Preserve hard links
A --acls Preserve ACLs
X --xattrs Preserve extended attributes
x --one-file-system Prevent rsync from following mount points
  –numeric-ids rsync will transfer numeric group and user IDs rather than using user and group names and mapping them at both ends

To make things bootable, the fstab inside the USB drive needs to point to the correct partition UUIDs:

1
2
3
4
5
6
# Get UUIDs
sudo blkid /dev/sdX1  # EFI partition UUID
sudo blkid /dev/mapper/usb_crypt  # Root partition UUID

# Edit fstab inside USB OS root
sudo nano /mnt/backup_usb/etc/fstab

Update /mnt/backup_usb/etc/fstab with the new UUIDs:

1
2
UUID=<root-uuid> / ext4 defaults 0 1
UUID=<efi-uuid> /boot/efi vfat defaults 0 2

We also need a crypttab file so that the LUKS-encrypted FS can be decrypted automatically during boot:

1
2
3
4
# get the LUKS UUID
sudo blkid /dev/sdX2

sudo nano /mnt/backup_usb/etc/crypttab

Rename or add the LUKS mapping:

1
usb_crypt UUID=<luks-uuid> none luks

We can just rsync all the EFI files from Workstation into the backup:

1
sudo rsync -avhPHAXx --numeric-ids /boot/efi/ /mnt/backup_usb/boot/efi/

Pop!OS has systemd-boot which has a nice LUKS PW prompt, so install that via chroot:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Bind mount necessary filesystems
sudo mount --bind /dev /mnt/backup_usb/dev
sudo mount --bind /proc /mnt/backup_usb/proc
sudo mount --bind /sys /mnt/backup_usb/sys
sudo mount --bind /run /mnt/backup_usb/run

# Chroot into the USB system
sudo chroot /mnt/backup_usb

# Install systemd-boot
bootctl install

# Update initramfs
update-initramfs -u -k all

# Exit chroot
exit

That’s it. We need to unmount everything and then we’re ready for a test reboot into your bootable UEFI drive.

1
2
3
4
5
6
7
8
9
10
# Unmount filesystems
sudo umount /mnt/backup_usb/boot/efi
sudo umount /mnt/backup_usb/dev
sudo umount /mnt/backup_usb/proc
sudo umount /mnt/backup_usb/sys
sudo umount /mnt/backup_usb/run
sudo umount /mnt/backup_usb

# Close LUKS container
sudo cryptsetup luksClose usb_crypt