disko icon indicating copy to clipboard operation
disko copied to clipboard

Unclear how to use disko with LUKS + keyfile on usb stick configuration

Open tfc opened this issue 2 years ago • 3 comments

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?

tfc avatar Jul 10 '23 15:07 tfc

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.

tfc avatar Jul 10 '23 15:07 tfc

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.

tfc avatar Jul 10 '23 17:07 tfc

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
  '';
}

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
              '';
            };
            # [...]
          };
        }
      ];
    };
  }));
}

rogarb avatar Jul 23 '23 20:07 rogarb