# Setup keyfile
boot.initrd.secrets = {
"/crypto_keyfile.bin" = null;
};
boot.initrd.luks.devices = {
r3t6crypt = {
device = "/dev/disk/by-uuid/ae7aefce-2ddd-44eb-aa4c-16a915ac6753";
keyFile = "/mnt-root/root/crypto_keyfile.bin";
};
};
My root hard disk is already getting decrypted by the autogenerated hardware-configuration.nix file, but for some reason I cannot for the life of me get subsequent hard disks decrypted. I’ve been tryingt his for hours to no avail, any clues?
3 Likes
So the problem is that NixOS’s initrd is scripted in distinct phases. It does all LUKS devices, and then it mounts file systems. So you can’t have a LUKS device whose key file is on any such file system. There’s a couple of ways to fix this today.
-
Firstly (and I recommend this one if it works for you), is just not decrypting the disk in initrd. If the file system being decrypted isn’t needed in initrd (i.e. if it isn’t one of these ones), then you can just use the regular ole stage 2 /etc/crypttab
instead of the NixOS initrd options.
environment.etc."crypttab".text = ''
r3t6crypt /dev/disk/by-uuid/ae7aefce-2ddd-44eb-aa4c-16a915ac6753 /root/crypto_keyfile.bin
'';
This doesn’t do decryption in initrd; it does it in stage 2 when the real OS is booting up. This is generally preferable if the FS isn’t needed in initrd because systemd
does quite a lot to make the boot process more robust and user friendly, so allowing it to manage the decryption and mounting of file systems, especially with the context of the real OS, is generally better.
-
But secondly, if the file system is needed in initrd (e.g. if the /nix/store
is on a separate encrypted disk from the root fs), you can try the experimental option boot.initrd.systemd.enable = true;
. This enables the new systemd-based initrd. It brings many of the benefits I described about doing it in stage 2 above into the initrd (though it’s still better to do it in stage 2 if you can). And it implements most of the same initrd
options like the boot.initrd.luks
options you’re using in terms of systemd stuff; LUKS devices are actually just translated into an /etc/crypttab
file for initrd to use. The only difference for your config is that with systemd-based initrd, your root fs is mounted at /sysroot
instead of /mnt-root
in initrd.
This feature is currently considered experimental. But several of us have been using it on our daily drivers for months now and this is exactly the kind of problem it was intended to fix.
5 Likes
Thank you very very very much. This helped me quite a lot.
For others encountering a similar issue when configurating multi-disk encryption with a single master boot key which is contained within your root hard disk, here is my configuration
# Setup keyfile
boot.initrd.secrets = {
"/crypto_keyfile.bin" = null;
};
environment.etc."crypttab".text = ''
ssd476g9crypt /dev/disk/by-uuid/8983aee6-0cec-46b7-b5c6-5ffefa5a0e41 /crypto_keyfile.bin
'';
fileSystems."/home" =
{ device = "/dev/disk/by-uuid/4e4adce6-cf79-4f2c-bf74-7099d808c1ea";
fsType = "btrfs";
options = [ "subvol=@home" ];
};
Important to note here is that this will NOT work unless environment.“etc”.text.cryptab comes after boot.initrd.secrets.
Thank you again. ![:slight_smile: :slight_smile:](https://discourse.nixos.org/images/emoji/twitter/slight_smile.png?v=12)
2 Likes
wut. Nix doesn’t care about the order of defitions. { a = 1; b = 2; }
is literally the exact same thing as { b = 2; a = 1; }
Can you please explain what this does? What happens if i don’t set any boot.initrd
setting? Is there no keyfile then and nothing at risk or is there an unencrypted keyfile?
I’m asking because i wasn’t able to define a /boot/efi
partition with the current/unstable calamares installer (it was complaining and didn’t boot when i created a 512MB FAT32 partition with the boot flag. Having it unmounted or mounting it as /boot/efi
or /efi
all didn’t work. The only thing that calamares accepted without complaints and that worked afterwards was an unencrypted /boot
partition. Using /boot/efi
in calamares was possible in 22.11).
This code says that the initrd should contain a file /crypto_keyfile.bin
which is copied from the root partition’s /crypto_keyfile.bin
file.
This is risky, and you shouldn’t do it unless you know what you’re doing or the calamares installer did it for you. And even then, the calamares installer did it wrong before 23.11.
This file will be stored in plaintext in the initrd. If you use an unencrypted /boot
partition, this means this key file is in plaintext on disk. The only way to encrypt /boot
is to use Grub, which the calamares installer will not do for UEFI systems. With systemd-boot, your initrd is going to be stored on an unencrypted partition, and you should not use boot.initrd.secrets
except for files that you don’t mind leaking. For disk decryption with systemd-boot, this means you should have initrd ask for the password, since the boot loader can’t.
In reality, the difference between the two methods is negligible from a security perspective; encrypting the initrd serves no security purpose when the boot loader still has to be unencrypted, and there’s no difference between typing your password into Grub vs typing it in while initrd boots (except that the initrd is way way faster and more flexible at it).
1 Like
Ah, glad that i asked. Thank you for your explaination!