2023-03-22 15:17:23 +01:00
|
|
|
{ system ? builtins.currentSystem
|
|
|
|
, config ? {}
|
|
|
|
, pkgs ? import ../.. {inherit system config; }
|
|
|
|
, systemdStage1 ? false }:
|
|
|
|
import ./make-test-python.nix ({ lib, pkgs, ... }: let
|
|
|
|
|
|
|
|
keyfile = pkgs.writeText "luks-keyfile" ''
|
|
|
|
MIGHAoGBAJ4rGTSo/ldyjQypd0kuS7k2OSsmQYzMH6TNj3nQ/vIUjDn7fqa3slt2
|
|
|
|
gV6EK3TmTbGc4tzC1v4SWx2m+2Bjdtn4Fs4wiBwn1lbRdC6i5ZYCqasTWIntWn+6
|
|
|
|
FllUkMD5oqjOR/YcboxG8Z3B5sJuvTP9llsF+gnuveWih9dpbBr7AgEC
|
|
|
|
'';
|
|
|
|
|
|
|
|
in {
|
|
|
|
name = "initrd-luks-empty-passphrase";
|
|
|
|
|
|
|
|
nodes.machine = { pkgs, ... }: {
|
nixos/qemu-vm: use persistent block device names
This change removes the bespoke logic around identifying block devices.
Instead of trying to find the right device by iterating over
`qemu.drives` and guessing the right partition number (e.g.
/dev/vda{1,2}), devices are now identified by persistent names provided
by udev in /dev/disk/by-*.
Before this change, the root device was formatted on demand in the
initrd. However, this makes it impossible to use filesystem identifiers
to identify devices. Now, the formatting step is performed before the VM
is started. Because some tests, however, rely on this behaviour, a
utility function to replace this behaviour in added in
/nixos/tests/common/auto-format-root-device.nix.
Devices that contain neither a partition table nor a filesystem are
identified by their hardware serial number which is injecetd via QEMU
(and is thus persistent and predictable). PCI paths are not a reliably
way to identify devices because their availability and numbering depends
on the QEMU machine type.
This change makes the module more robust against changes in QEMU and the
kernel (non-persistent device naming) and by decoupling abstractions
(i.e. rootDevice, bootPartition, and bootLoaderDevice) enables further
improvement down the line.
2023-06-08 02:34:10 +02:00
|
|
|
imports = lib.optionals (!systemdStage1) [ ./common/auto-format-root-device.nix ];
|
|
|
|
|
2023-03-22 15:17:23 +01:00
|
|
|
virtualisation = {
|
|
|
|
emptyDiskImages = [ 512 ];
|
|
|
|
useBootLoader = true;
|
|
|
|
useEFIBoot = true;
|
2023-05-25 19:02:28 +02:00
|
|
|
# This requires to have access
|
|
|
|
# to a host Nix store as
|
|
|
|
# the new root device is /dev/vdb
|
|
|
|
# an empty 512MiB drive, containing no Nix store.
|
|
|
|
mountHostNixStore = true;
|
nixos/qemu-vm: use persistent block device names
This change removes the bespoke logic around identifying block devices.
Instead of trying to find the right device by iterating over
`qemu.drives` and guessing the right partition number (e.g.
/dev/vda{1,2}), devices are now identified by persistent names provided
by udev in /dev/disk/by-*.
Before this change, the root device was formatted on demand in the
initrd. However, this makes it impossible to use filesystem identifiers
to identify devices. Now, the formatting step is performed before the VM
is started. Because some tests, however, rely on this behaviour, a
utility function to replace this behaviour in added in
/nixos/tests/common/auto-format-root-device.nix.
Devices that contain neither a partition table nor a filesystem are
identified by their hardware serial number which is injecetd via QEMU
(and is thus persistent and predictable). PCI paths are not a reliably
way to identify devices because their availability and numbering depends
on the QEMU machine type.
This change makes the module more robust against changes in QEMU and the
kernel (non-persistent device naming) and by decoupling abstractions
(i.e. rootDevice, bootPartition, and bootLoaderDevice) enables further
improvement down the line.
2023-06-08 02:34:10 +02:00
|
|
|
fileSystems."/".autoFormat = lib.mkIf systemdStage1 true;
|
2023-03-22 15:17:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
boot.loader.systemd-boot.enable = true;
|
|
|
|
boot.initrd.systemd = lib.mkIf systemdStage1 {
|
|
|
|
enable = true;
|
|
|
|
emergencyAccess = true;
|
|
|
|
};
|
|
|
|
environment.systemPackages = with pkgs; [ cryptsetup ];
|
|
|
|
|
|
|
|
specialisation.boot-luks-wrong-keyfile.configuration = {
|
|
|
|
boot.initrd.luks.devices = lib.mkVMOverride {
|
|
|
|
cryptroot = {
|
2022-10-16 00:18:03 +02:00
|
|
|
device = "/dev/vdb";
|
2023-03-22 15:17:23 +01:00
|
|
|
keyFile = "/etc/cryptroot.key";
|
|
|
|
tryEmptyPassphrase = true;
|
|
|
|
fallbackToPassword = !systemdStage1;
|
|
|
|
};
|
|
|
|
};
|
2022-10-16 00:18:03 +02:00
|
|
|
virtualisation.rootDevice = "/dev/mapper/cryptroot";
|
2023-03-22 15:17:23 +01:00
|
|
|
boot.initrd.secrets."/etc/cryptroot.key" = keyfile;
|
|
|
|
};
|
|
|
|
|
|
|
|
specialisation.boot-luks-missing-keyfile.configuration = {
|
|
|
|
boot.initrd.luks.devices = lib.mkVMOverride {
|
|
|
|
cryptroot = {
|
2022-10-16 00:18:03 +02:00
|
|
|
device = "/dev/vdb";
|
2023-03-22 15:17:23 +01:00
|
|
|
keyFile = "/etc/cryptroot.key";
|
|
|
|
tryEmptyPassphrase = true;
|
|
|
|
fallbackToPassword = !systemdStage1;
|
|
|
|
};
|
|
|
|
};
|
2022-10-16 00:18:03 +02:00
|
|
|
virtualisation.rootDevice = "/dev/mapper/cryptroot";
|
2023-03-22 15:17:23 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
testScript = ''
|
|
|
|
# Encrypt key with empty key so boot should try keyfile and then fallback to empty passphrase
|
|
|
|
|
|
|
|
|
|
|
|
def grub_select_boot_luks_wrong_key_file():
|
|
|
|
"""
|
|
|
|
Selects "boot-luks" from the GRUB menu
|
|
|
|
to trigger a login request.
|
|
|
|
"""
|
|
|
|
machine.send_monitor_command("sendkey down")
|
|
|
|
machine.send_monitor_command("sendkey down")
|
|
|
|
machine.send_monitor_command("sendkey ret")
|
|
|
|
|
|
|
|
def grub_select_boot_luks_missing_key_file():
|
|
|
|
"""
|
|
|
|
Selects "boot-luks" from the GRUB menu
|
|
|
|
to trigger a login request.
|
|
|
|
"""
|
|
|
|
machine.send_monitor_command("sendkey down")
|
|
|
|
machine.send_monitor_command("sendkey ret")
|
|
|
|
|
|
|
|
# Create encrypted volume
|
|
|
|
machine.wait_for_unit("multi-user.target")
|
2022-10-16 00:18:03 +02:00
|
|
|
machine.succeed("echo "" | cryptsetup luksFormat /dev/vdb --batch-mode")
|
2023-03-22 15:17:23 +01:00
|
|
|
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks-wrong-keyfile.conf")
|
|
|
|
machine.succeed("sync")
|
|
|
|
machine.crash()
|
|
|
|
|
|
|
|
# Check if rootfs is on /dev/mapper/cryptroot
|
|
|
|
machine.wait_for_unit("multi-user.target")
|
|
|
|
assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount")
|
|
|
|
|
|
|
|
# Choose boot-luks-missing-keyfile specialisation
|
|
|
|
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks-missing-keyfile.conf")
|
|
|
|
machine.succeed("sync")
|
|
|
|
machine.crash()
|
|
|
|
|
|
|
|
# Check if rootfs is on /dev/mapper/cryptroot
|
|
|
|
machine.wait_for_unit("multi-user.target")
|
|
|
|
assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount")
|
|
|
|
'';
|
|
|
|
})
|