Decrypt NixOS via SSH at boot
2023-07-22
In my NixOS setup I have my root and swap partitions fully encrypted. This is the default setup when you set the “encrypt system” checkbox on the graphical installer.
During boot I’m asked for the decryption password. This isn’t idea as the box runs headlessly under my desk and may also require rebooting when I’m not in the same physical location. Therefore, I need a way to remotely supply the password. This can be done by configuring NixOS to allow SSH access before the machine fully boots.
Create key pair
It’s best to create a new key pair specifically for this pre-boot SSH setup.
$ ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key
Determine the network card driver you need
To ensure the right drivers are installed in the minimal boot state, it needs
to be specified in the available kernal modules (see below). The driver required
can be found with lspci
.
$ nix-shell -p pciutils
$ lspci -v
# Therell be some output similar to this
26:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 04)
...
Kernel driver in use: r8169 # In this case, 'r8169' is the value I want
Kernel modules: r8169
Configure minimal network setup for initrd
# configuration.nix
boot.initrd = {
network = {
enable = true;
ssh = {
enable = true;
port = 2222; # Use a separate port to prevent conflict in your known
# hosts
hostKeys = [ "/etc/ssh/initrd_ssh_host_ed25519_key" ];
authorizedKeys = config.users.users.<root|user>.openssh.authorizedKeys.keys;
};
};
availableKernelModules = [ "r8169" ];
};
networking.useDHCP = false;
networking.interfaces.enp6s0.useDHCP = true; # network interface found in
# hardward-configuration.nix
Now, when rebooting, we can see the sshd daemon starting before the prompt for the luks password appears. Connect to be able to access the boot partition.
$ ssh root@<host-ip> -p 2222
Once logged in the partition can be decrypted.
I’ve seen examples where cryptroot-unlock
or cryptsetup open
were used to
unlock the partition, but none of these worked for me. Tabbing around I found
the cryptsetup-askpass
command.
$ cryptsetup-askpass
Passphrase for /dev/disk/by-uuid/b0b4a2bf-12e4-4e62-985a-f48f722c3789:
That’s it. Once entered, the port 2222 sshd is stopped and the boot continues as normal.
Automatic password prompt
For a slightly less interactive version, set an alias as suggested by Daniel Wayne Armstrong.
# ~/.ssh/config
Host unlock-<host>
Hostname <host-ip>
User root
Port 2222
RequestTTY yes
RemoteCommand cryptsetup-askpass
Now just ssh in and you’ll be asked for the password. Once boot is complete your session will be closed.
$ ssh unlock-host
Passphrase for /dev/disk/by-uuid/b0b4a2bf-12e4-4e62-985a-f48f722c3789:
Waiting 10 seconds for LUKS to request a passphrase.......Connection to 192.168.88.97 closed by remote host.
Connection to 192.168.88.97 closed.
Elsewhere
- My server setup with ssh enabled at boot (Commit 90f1063 at time of writing, things may have changed since then)
- Early boot remote decryption
- Early boot remote decryption on NixOS
- Remotely unlock a LUKS-encrypted Linux server using Dropbear
- Remote LUKS Unlocking