Upgrading some older full-disk encryption setups

As of 24.05, my older configs will install grub, but it fails to boot claiming it can’t find a cryptodisk.

Checking the wiki, it appears things have gotten quite a bit simpler. I likely have explicit options where implicit just works.

The headers on these disks are luks1. Evidently I should upgrade to luks2 headers? Since this will not work with my old generations, I want to check before committing. I only have so many working disks to experiment with. I intend to use GRUB, which seems to have gained luks2 support.

boot.loader.efi.efiSysMountPoint = "/boot/efi";

My boot partition is mounted to /boot/efi rather than /boot. Has this gone out of style?

The wiki is no longer listing a secret at all. Is the key implicitly available from having the partition unlocked for installation? Are key files only useful for recovering the encrypted data or do we still use them at all during rebuild?

If you didn’t change your config, whatever you had before should continue to work. So this is strange. At what point does it fail? Is it while Grub is booting, or while NixOS Stage 1 is booting?


But to answer your other questions, it seems like you have a setup where Grub is decrypting your disk. You probably have Grub installed to your ESP (/boot/efi) and have it decrypting the drive with your kernels and initrds on it. That drive probably also contains its own decryption key in the initrds so that you don’t have to re-enter the passphrase when you get into stage 1.

I do not recommend this configuration. Grub’s encryption implementation is slow, buggy, and usually lags behind modern features, and it doesn’t gain you any security. The wiki seems to be suggesting something more like what I would do. I prefer to just have the ESP mounted on /boot, allowing the system to install the kernels and initrds unencrypted on the ESP. The boot loader simply boots these without asking for a passphrase, and then NixOS’s stage 1 will ask you for your root file system’s decryption passphrase.

This is why the wiki is “no longer listing a secret”. In the former configuration, you have to tell it where the decryption key file is so that it can include it in the initrd which is stored on the encrypted drive; otherwise stage 1 would have to ask for your passphrase for a second time after Grub. In the latter configuration, the initrd has no secret key file at all and stage 1 just asks you for the passphrase for the root file system directly, because Grub never did.

Okay that all makes sense. Grub was failing to decrypt the drive, so before stage 1.

I’m mainly only interested in having time to rotate secrets if I lose a machine or drive. In practice I have seemed more likely to destroy all of my own data with full-disk encryption.

When I change the mount point in the configuration, will nixos-rebuild take care of the new mount configuration?

Do I still need to upgrade to Luks2?

More info:

lsblk
nvme0n1        259:0    0 953.9G  0 disk  
├─nvme0n1p1    259:1    0    33M  0 part  /boot/efi
└─nvme0n1p2    259:2    0 906.1G  0 part  
  └─nixos-root 254:0    0 906.1G  0 crypt 
    ├─vgz-root 254:1    0 317.1G  0 lvm   /nix/store
    │                                     /
    ├─vgz-home 254:2    0 559.5G  0 lvm   /home
    └─vgz-swap 254:3    0  29.5G  0 lvm   [SWAP]

Configs I had:

   boot.initrd.luks.devices = {
     nixos-root = {
       device = "/dev/disk/by-uuid/017a7009-78ea-46f3-aa98-528ba02ec85e";
       preLVM = true;
       keyFile = "/keyfile";
       allowDiscards = true;
     };
   };

  boot.loader.grub = {
    enable = true;
    efiSupport = true;
    device = "nodev";
    configurationLimit = 8;
    enableCryptodisk = true;
  };
  boot.initrd.secrets = {
    "keyfile" = "/etc/secrets/initrd/keyfile";
  };
  boot.loader.efi.efiSysMountPoint = "/boot/efi";

I tried to write out an explanation for migrating to my suggested configuration, but quite honestly this is a really delicate operation with a lot of pitfalls. I personally know how to do it, but explaining it in a discourse comment is very very difficult.

The short version is that you would redo the nixos config so that /boot is your ESP, but before you do any nixos-rebuild, you would sanitize things so that no disk decryption keys end up unencrypted on the ESP. This is tricky because even if you delete the boot.initrd.secrets bit, your old generations will still try to add the secret key file to their initrds on the unencrypted ESP. So you basically have to delete all your old generations before you even do a nixos-rebuild boot.

Well my ESP is presently too small for a kernel. I suspect it will be easier to transfer all the data than to resize in place with LVM on LUKS.

I did get the system to boot using Grub from 22.11, just substituted in via overlay. I am making some backup USB’s to boot externally for now.

Every Grub from 23.11 to unstable would report: error: no key data. I went ahead and updated the LUKS to version 2. 22.05 with the luks2 Grub module can unlock it just fine.

Playing with the extraGrubInstallArgs, I added some modules. What I noticed is that the newer Grubs could not even unlock my old backup disk that was still LUKS1, even after adding the LUKS1 module. Over and over, error: no key data.

This seems to have started after 23.05 because I updated my channel but evidently stopped upgrading to the latest channel for my system packages, meaning I ran into this a while ago but didn’t have time.

I may resort to manual loading with the keyfile sitting on the ESP. I don’t value encryption enough to solve this compared to exercising my secret rotation and re-encrypting it all after adjusting my disk layout.

Is TPM checking of the boot ESP files pretty well supported these days? I would like to look into that if it has other advantages.