Skip to content

Instantly share code, notes, and snippets.

@vincentbernat
Created December 7, 2018 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vincentbernat/9f1f0093b553d659539abfaa42f553e4 to your computer and use it in GitHub Desktop.
Save vincentbernat/9f1f0093b553d659539abfaa42f553e4 to your computer and use it in GitHub Desktop.

Encrypted root in VM

#+filetags :exoscale:

The goal is to switch a VM to an encrypted root. There are several challenges:

  • add a /boot partition
  • convert the root partition to an encrypted one
  • boot the VM with the encrypted root

Preliminary steps

Installing Grub 2

apt-get install grub2
grub-install /dev/vda

Installing dropbear for initramfs access

apt-get install dropbear busybox e2fsprogs parted cryptsetup
cat <<EOF >> /etc/initramfs-tools/initramfs.conf
DROPBEAR=y
DEVICE=eth0
IP=dhcp
CRYPTSETUP=y
EOF
cp /root/.ssh/authorized_keys /etc/initramfs-tools/root/.ssh/authorized_keys
update-initramfs -u

On reboot, we can pause the initramfs by appending break=mount on the command line.

Creating the /boot partition

The root partition needs to be resized. We need to add additional tools to the initramfs for that. We put the following file in /etc/initramfs-tools/hooks/resizefs:

#!/bin/sh

. /usr/share/initramfs-tools/hook-functions

copy_exec /sbin/resize2fs sbin/resize2fs
copy_exec /sbin/parted sbin/parted
copy_exec /sbin/mkfs.ext2 sbin/mkfs.ext2

Then, in the initramfs, we have to reduce the filesystem size, then the partition. The trick is to ensure that we do not mess with the sizes.

export PATH=$PATH:/sbin:/usr/sbin
e2fsck -f /dev/vda1
resize2fs -M /dev/vda1
parted /dev/vda -- resizepart 1 -100MB
resize2fs /dev/vda1

Then, we can create the /boot partition and copy data to it.

parted /dev/vda -- mkpart primary ext2 -100MB -1s
mkfs.ext2 /dev/vda2
mkdir /target
mkdir /source
modprobe ext2
modprobe ext3
modprobe ext4
mount /dev/vda1 /source
mount /dev/vda2 /target
cp -a /source/boot/* /target/*
rm -rf /source/boot

Then, we need to configure the system to use this partition for boot.

mount --bind /dev /source/dev
chroot /source /bin/bash
echo "/dev/vda2 /boot ext2 defaults,noatime 0 2" >> /etc/fstab
mkdir /boot
mount /boot
mount -t proc proc /proc
mount -t sysfs sys /sys
grub-install /dev/vda
update-grub

It should be OK. We can reboot.

umount /sys
umount /proc
umount /boot
umount /dev
exit
umount /source
umount /target
sync
sync
echo b > /proc/sysrq-trigger

Encrypt the root file system

Back to the initramfs. We need to use luksipc this time.

We put this content in /etc/initramfs-tools/hooks/encrypt:

#!/bin/sh

. /usr/share/initramfs-tools/hook-functions

copy_exec /sbin/resize2fs sbin/resize2fs
copy_exec /sbin/luksipc sbin/luksipc

Now, we need to reboot into the initramfs, resize the root partition, encrypt it, restore the size, save the key and ensure a proper boot.

export PATH=$PATH:/sbin:/usr/sbin
e2fsck -f /dev/vda1
resize2fs -M /dev/vda1
modprobe dm_crypt
modprobe xts
modprobe aes
modprobe crc32c
modprobe sha256
luksipc -d /dev/vda1
cryptsetup luksOpen --key-file /root/initial_keyfile.bin /dev/vda1 cryptroot
resize2fs /dev/mapper/cryptroot

Then, to make the system bootable again:

mkdir /target
modprobe ext3
modprobe ext4
mount /dev/mapper/cryptroot /target
mount --bind /dev /target/dev
chroot /target /bin/bash
mount /boot
mount -t proc proc /proc
mount -t sysfs sys /sys
echo cryptroot /dev/vda1 /boot/cryptroot.key luks > /etc/crypttab
sed -i s+/dev/vda1+/dev/mapper/cryptroot+ /etc/fstab
update-grub
update-initramfs -u
umount /sys
umount /proc
umount /dev
exit
cp /root/initial_keyfile.bin /target/boot/cryptroot.key
umount /target/boot
umount /target
sync
sync
echo b > /proc/sysrq-trigger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment