Unclear how to use disko with LUKS + keyfile on usb stick configuration
Hi,
i have the following configuration:
# disko config
{ lib, ... }:
{
disko.devices.disk = (lib.genAttrs [ "/dev/sda" ] (disk: {
type = "disk";
device = disk;
content = {
type = "table";
format = "gpt";
partitions = [
{
name = "boot";
start = "0";
end = "1M";
part-type = "primary";
flags = [ "bios_grub" ];
}
{
name = "ESP";
start = "1M";
end = "1047MB";
fs-type = "fat32";
bootable = true;
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
}
{
name = "root";
start = "1074MB";
end = "100%";
part-type = "primary";
bootable = true;
content = {
type = "luks";
name = "cryptedroot";
extraOpenArgs = [ "--allow-discards" ];
keyFile = "/key/hdd.key";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
}
];
};
}));
}
the /key folder is mounted from a usb stick. in order to have that available at boot, i use:
{ config, lib, ... }:
# this snippet is motivated from https://nixos.wiki/wiki/Full_Disk_Encryption
{
boot.initrd.kernelModules = ["uas" "usbcore" "usb_storage" "vfat" "nls_cp437" "nls_iso8859_1"];
boot.initrd.postDeviceCommands = lib.mkBefore ''
mkdir -m 0755 -p /key
sleep 2 # To make sure the usb key has been loaded
mount -n -t vfat -o ro /dev/sdc1 /key
'';
}
After installation (using nixos-anywhere) and first boot, i immediately get to a password prompt for the disk, although there is no password. it seems like the snippet is setup for execution too late.
Even if i put an exit 1 into this script, i still arrive at the blocking password prompt.
How do i use this correctly with disko?
Also, it seems like the prompt is this one from the luks nixos module and when i just enter something, i see that cryptsetup luksOpen /dev/sda3 cryptedroot --key-file=-, which really seems wrong.
Ok, i got it working by adding these additional lines to my nixos config:
boot.initrd.luks.devices.cryptedroot.keyFile = "/key/hdd.key";
boot.initrd.luks.devices.cryptedroot.preLVM = false;
Thanks @Lassulus for pointing the preLVM stuff out!
It feels like disko should handle this alone, but that does now at least fix my problem.
the
/keyfolder is mounted from a usb stick. in order to have that available at boot, i use:{ config, lib, ... }: # this snippet is motivated from https://nixos.wiki/wiki/Full_Disk_Encryption { boot.initrd.kernelModules = ["uas" "usbcore" "usb_storage" "vfat" "nls_cp437" "nls_iso8859_1"]; boot.initrd.postDeviceCommands = lib.mkBefore '' mkdir -m 0755 -p /key sleep 2 # To make sure the usb key has been loaded mount -n -t vfat -o ro /dev/sdc1 /key ''; }
Did you try to use boot.initrd.luks.devices.<name>.preOpenCommands which seems to be designed for what you want to do?
According to man configuration.nix:
boot.initrd.luks.devices.<name>.preOpenCommands Commands that should be run right before we try to mount our LUKS device. This can be useful, if the keys needed to open the drive is on another partition. Type: strings concatenated with “\n” Default: "" Example: '' mkdir -p /tmp/persistent mount -t zfs rpool/safe/persistent /tmp/persistent ''
Since #291, you should be able to declare it directly in your disko configuration through the settings submodule, i.e.:
# disko config
{ lib, ... }:
{
disko.devices.disk = (lib.genAttrs [ "/dev/sda" ] (disk: {
# [...]
content = {
# [...]
{
# [...]
content = {
type = "luks";
# [...]
settings = {
keyFile = "/key/hdd.key";
preOpenCommands = ''
mkdir -m 0755 -p /key
sleep 2 # To make sure the usb key has been loaded
mount -n -t vfat -o ro /dev/sdc1 /key
'';
};
# [...]
};
}
];
};
}));
}