If you have a encrypted root partition, it usually requires access to the console to enter the passphrase.
Even if you have the root partition unencrypted and have you sensitive data on a different encrypted partition, that you manually mount after SSH is available. You still have to deal with starting services after said manual mount.
There are a number of remote unlocking tools (luksrku, mandos, tang/clevis), which attempt to solve this problem, by having a service running a trusted network to provide the decryption key. While this may be suitable for larger environments, I needed something simplier, suited for a handful of machines.
Solution
I decided to use dropbear to run an SSH daemon in the initrd, then being able to SSH in and unlock all the devices in the initrd, before starting the root pivot.
This then allows the usual systemd init system to start services. Without needing to implement any custom service starting.
Implementation
Info
The following applies to Ubuntu 20.04, different distributions may vary.
Dropbear
The dropbear SSH daemon can be installed in the initrd by:
|
|
Password authentication is disabled, therefore you need to add your authorized_keys
to /etc/dropbear/initramfs/authorized_keys
Dropbear options can be added to DROPBEAR_OPTIONS
in /etc/dropbear/initramfs/dropbear.conf
. See man dropbear(8)
for more details.
Networking
Configuring networking in the initrd, is the same as documented for configuring NFS root booting. Upstream docs can be found at https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt , under the ip
parameter.
This matches the IP=
option placed in /etc/initramfs-tools/initramfs.conf
. e.g.
|
|
Networking persists to the OS booting, which is good if your configuration is the same.
In my case, the IP in the full OS should be on a bridge device (br0
), not eno1
as it is in the initrd. The simplest solution is to remove the networking configuration as the initrd pivots and let netplan bring up the new configuration as the OS boots.
To remove the initrd
networking, add the following script as /etc/initramfs-tools/scripts/init-bottom/remove-networking.sh
:
|
|
(change DEV
to match your network interface)
Unlock Script
The cryptsetup-initramfs
package, provides a convience wrapper for unlocking devices called cryptroot-unlock
, this is the script you would run via SSH to unlock all the devices and continue the boot.
This script will ask for the passphrase for every device. In my case, I have many devices, with the same passphrase. The following modifcation will try the previouisly used passphrase for the next device, any only prompt for a new passphrase if it fails to unlock:
|
|
Download the full modified version here: cryptroot-unlock-custom.gz.
Place this in /usr/share/cryptsetup/initramfs/bin
, either overwriting cryptroot-unlock or adding it a new file as cryptroot-unlock-custom. If you add a new file, you need to make sure it gets added to the initrd by adding the following to /usr/share/initramfs-tools/hooks/cryptroot-unlock
:
|
|
crypttab
Warning
Cryptab format varies between distros and programs (systemd / Debian initrd), therefore be wary of alternative formatting described elsewhere
Make sure all of your encrypted devices are in /etc/crypttab
. By default, the initrd
unlocking process only unlocks the devices to mount the root partition. This then causes systemd
to prompt for the passphrase on the console when booting the OS, which defeats our aim of remote unlocking. This can be solved by adding the initramfs
option to every entry in the crypttab
to force them to be unlocked during our initrd
remote unlocking process.
For example, my /etc/crypttab
might look like this:
|
|
Info
An alternative would be to have a LUKS keyfile on the encrypted root partition that could be used to unlock the other devices. I just decided not to go this route
Updating initrd
Don’t forget to regenerate you initrd
with:
|
|
Using
Since the SSH hostkeys will be different in the initrd
from the full OS, your client could easily think MITM attacks are occurring. You can avoid this by having a separate SSH config entry for SSHing in to the initrd, e.g.:
|
|
Upon rebooting, you should be able to SSH to the initrd
and run cryptroot-unlock
, after entering the correct passphrase(s), it will auto close the connection and continue the boot process.