# 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?
2 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.
3 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. 
1 Like
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; }