Simon Szustkowski

Ein Blog über alles, was mir gerade so durch den Kopf geht

Oct 17, 2018

Set up LUKS on a physical Hetzner Server with Debian

I have recently acquired a quite good-value physical server via Hetzner’s Serverbörse tool. An Intel i7 4770 with 32GB RAM and 2x2TB hard disk for 26€ per month isn’t so bad. However, like every lawful citizen i have nothing to fear from the authorities, and therefore wanted to encrypt the disks, just in case. I was successful after some attempts and want to describe what i have done.

The whole process consists of two parts:

  1. Migrating your existing disk layout made by Hetzner’s installimage script to encryption
  2. Setting up your initramfs with dropbear to be able to enter your decryption password on a reboot

First, setting up the encryption. After successful execution of the installimage script i ended up with a software RAID 1, which had two devices showing up: /dev/md0 is a plain partition where the kernel and the initramfs reside. It is mounted on /boot. /dev/md1 is a LVM setup instead, with a physical volume, and a volumegroup vg0. In this group there are several logical volumes which are mounted to different places in the directory tree. Further down this post i use my list of logical devices, you will most certainly have to modify this list for your own setup.

So, to begin with migrating your disk to encryption, copy the contents of /etc/fstab somewhere else, so that you have a handy overview which partitions you have, where they are mounted, and which file system they use. Go ahead and boot into the rescue system then.

Do the following steps inside the rescue system:

vgchange vg0 -a y
mkdir /oldroot
mount /dev/vg0/root /mnt
mount /dev/vg0/home /mnt/home
mount /dev/vg0/tmp /mnt/tmp
rsync -av /mnt/ /oldroot/
umount /mnt/{home,tmp}
umount /mnt

Now we have a backup of the data in /oldroot. Next, backup your vg0 configuration and delete the actual volume group.

vgcfgbackup vg0 -f vg0.freespace
vgremove vg0

After that we can activate encryption in the md1 device.

cryptsetup --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 6000 luksFormat /dev/md1
cryptsetup luksOpen /dev/md1 cryptroot
pvcreate /dev/mapper/cryptroot

We have also created a new physical volume on the encrypted raid device. We have to modify the backed up VG config so that it is applicable to the new PV. Read the UUID of the new PV with blkid /dev/mapper/cryptroot. Copy the backed up VG config to the location where LVM expects it: cp vg0.freespace /etc/lvm/backup/vg0 and open the file in the editor of your choice. Look into the physical_volumes section and change the old UUID to the new value what we gathered right now. Also, change the device property to /dev/mapper/cryptroot. After that, restore the config: vgcfgrestore vg0 and check for the new LVs: vgchange -a y vg0

You will have all LVs back in /dev/vg0/. Go ahead and create filesystems on them, e.g. mkfs.ext4 /dev/vg0/root.

Now we have to sync our previously backuped files back. First, mount the LVs.

mount /dev/vg0/root /mnt/
mkdir /mnt/tmp
mount /dev/vg0/tmp /tmp
mkdir /mnt/home
mount /dev/vg0/home /home
rsync -av /oldroot /mnt

So, now we have an encrypted file system, but no chance of unlocking it on boot. Therefore, we need to install a small SSH server, dropbear, link it into the initramfs and configure GRUB to assign an IPv4-address. This enables us to SSH into the initramfs on boot and enter the unlock password. To do this, we need to prepare the server for chroot.

mount /dev/md0 /mnt/boot
mount --bind /proc /mnt/proc
mount --bind /dev /mnt/dev
mount --bind /sys /mnt/sys
chroot /mnt

Now we can install busybox and dropbear via apt: apt install busybox dropbear. After that, configure the initramfs to include these two tools. Edit /etc/initramfs-tools/initramfs.conf and change BUSYBOX=auto to BUSYBOX=y. Also, add a line DROPBEAR=y to this file.

Add the public SSH key of your desktop machine to /etc/dropbear-initramfs/authorized_keys. Dropbear has created its own set of host keys, but they need to be converted to RSA format.

/usr/lib/dropbear/dropbearconvert dropbear openssh dropbear_rsa_host_key id_rsa
dropbearkey -y -f dropbear_rsa_host_key |grep "^ssh-rsa " > id_rsa.pub

Edit /etc/default/dropbear afterwards, and set the NO_START=1 to NO_START=0, so that dropbear is actually able to start. Since it shouldn’t run when the server is fully booted up, disable it via systemd: systemctl disable dropbear.

To prevent the alerts of host key mismatch when using SSH, let dropbear run on a different port. Edit /etc/dropbear-initramfs/config and change the DROPBEAR_OPTIONS with the port flag, e.g. DROPBEAR_OPTIONS="-p 21".

As the before-the-last step we need to both GRUB and initramfs to assign an IP to enable networking in the pre-boot environment. Edit /etc/initramfs-tools/initramfs.conf and set the DEVICE option to the actual network device of your system, e.g. enp2s0. Add a new line afterwards which says: IP=148.251.84.104::148.251.84.97:255.255.255.224::enp2s0:off. The first value is your static IP, the second value is your assigned gateway, the third value is your subnet mask. After that, the name of your network adapter, and whether you want to have autoconf. Set this to off. Be careful with the amount of colons between the values.

Edit /etc/default/grub and change the string after GRUB_CMDLINE_LINUX_DEFAULT. Add an ip= followed by the same colon-separated network string like in the initramfs.conf.

The last step of network configuration is to add a force-restart of the device at boot. Put this to /etc/rc.local:

/sbin/ifdown --force enp2s0
/sbin/ifup --force enp2s0

As the last step, we need to regenerate the initramfs and the GRUB config, and re-install GRUB.

update-initramfs -u
update-grub
grub-install /dev/sda1
grub-install /dev/sda2

Now, exit chroot, unmount everything and reboot:

exit
umount /mnt/{home,boot,tmp}
umount /mnt
sync
reboot

If everything was successful, you should be able to connect to your server with ssh -p 21 root@yourserver and get a busybox shell. Enter cryptroot-unlock and your password. The dropbear session should end, and the server should boot from its unlocked encrypted volumes.

If anything goes wrong, don’t panic. Boot the server into rescue, and execute the following commands to get back into chroot:

cryptsetup luksOpen /dev/md1 cryptroot
vgchange -a y

mount /dev/vg0/root /mnt
mount /dev/md0 /mnt/boot
mount /dev/vg0/tmp /mnt/tmp
mount /dev/vg0/home /mnt/home

mount --bind /proc /mnt/proc
mount --bind /dev /mnt/dev
mount --bind /sys /mnt/sys

chroot /mnt

After fixing what has to be fixed, exit chroot, unmount everything, sync and reboot like you did before. Don’t forget to call update-initramfs and update-grub after changing any of their config values.

Good luck with that, it’s a little hard since you cannot see any errors when the server isn’t booting properly, but you will have success after some time. Having an encrypted machine is totally worth the effort and makes you sleep better at night.