Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/unl0kr: fix tests, change default package to buffybox (bumps unl0kr to 3.2.0-unstable-2024-11-10) #362825

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 47 additions & 46 deletions nixos/modules/system/boot/unl0kr.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ in
description = ''Whether to enable the unl0kr on-screen keyboard in initrd to unlock LUKS.'';
};

package = lib.mkPackageOption pkgs "unl0kr" { };
package = lib.mkPackageOption pkgs "buffybox" { };

allowVendorDrivers = lib.mkEnableOption "load optional drivers" // {
description = ''Whether to load additional drivers for certain vendors (I.E: Wacom, Intel, etc.)'';
Expand All @@ -27,7 +27,7 @@ in

See `unl0kr.conf(5)` for supported values.

Alternatively, visit `https://gitlab.com/postmarketOS/buffybox/-/blob/unl0kr-2.0.0/unl0kr.conf`
Alternatively, visit `https://gitlab.postmarketos.org/postmarketOS/buffybox/-/blob/3.2.0/unl0kr/unl0kr.conf`
'';

example = lib.literalExpression ''
Expand All @@ -51,16 +51,16 @@ in
assertion = cfg.enable -> config.boot.initrd.systemd.enable;
message = "boot.initrd.unl0kr is only supported with boot.initrd.systemd.";
}
{
assertion = !config.boot.plymouth.enable;
message = "unl0kr will not work if plymouth is enabled.";
}
{
assertion = !config.hardware.amdgpu.initrd.enable;
message = "unl0kr has issues with video drivers that are loaded on stage 1.";
}
];

warnings =
if config.hardware.amdgpu.initrd.enable then
[ ''Use early video loading at your risk. It's not guaranteed to work with unl0kr.'' ]
else if config.boot.plymouth.enable then
[ ''Plymouth **might** cause issues'' ]
else
[ ];

boot.initrd.availableKernelModules =
lib.optionals cfg.enable [
"hid-multitouch"
Expand All @@ -82,60 +82,61 @@ in

boot.initrd.systemd = {
contents."/etc/unl0kr.conf".source = settingsFormat.generate "unl0kr.conf" cfg.settings;
storePaths = with pkgs; [
"${pkgs.gnugrep}/bin/grep"
libinput
xkeyboard_config
"${config.boot.initrd.systemd.package}/lib/systemd/systemd-reply-password"
(lib.getExe' cfg.package "unl0kr")
];
storePaths = (
with pkgs;
[
libinput
libwacom
xkeyboard_config
cfg.package
]
);
services = {
unl0kr-ask-password = {
description = "Forward Password Requests to unl0kr";
unl0kr-agent = {
description = "Dispatch Password Requests to unl0kr";
Copy link
Contributor

@ElvishJerricco ElvishJerricco Dec 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try just adding buffybox to boot.initrd.systemd.packages rather than duplicating the upstream systemd units? Would be a lot cleaner. Should just need to manually add the necessary wantedBy to the path unit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm attempting to use the password agent from upstream, rewritten in C.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I currently don't know how to debug the systemd service, is there a manual entry for debugging stage 1 services?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a way to get a shell in stage 1, then you can manually run commands to check whatever you want to do. Would that be helpful?

Copy link
Contributor

@ElvishJerricco ElvishJerricco Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm attempting to use the password agent from upstream, rewritten in C.

Yes. The buffybox package has upstream unit files that can be included in initrd automatically by setting boot.initrd.systemd.packages = [ buffybox ]; so you don't have to reimplement the units yourself here.

I currently don't know how to debug the systemd service, is there a manual entry for debugging stage 1 services?

You can get a debug shell in systemd initrd by adding the rd.systemd.debug_shell kernel param and switching to VT9


unitConfig.DefaultDependencies = false;
unitConfig.ConditionPathExists = "!/run/plymouth/pid";

after = [
"plymouth-start.service"
];
conflicts = [
"emergency.service"
"initrd-switch-root.target"
"shutdown.target"
"initrd-switch-root.target"
];
unitConfig.DefaultDependencies = false;
after = [
"systemd-vconsole-setup.service"
"udev.service"
before = [
"emergency.service"
"shutdown.target"
"initrd-switch-root.target"
];
before = [ "shutdown.target" ];
script = ''
# This script acts as a Password Agent: https://systemd.io/PASSWORD_AGENTS/

DIR=/run/systemd/ask-password/
# If a user has multiple encrypted disks, the requests might come in different times,
# so make sure to answer as many requests as we can. Once boot succeeds, other
# password agents will be responsible for watching for requests.
while [ -d $DIR ] && [ "$(ls -A $DIR/ask.*)" ];
do
for file in `ls $DIR/ask.*`; do
socket="$(cat "$file" | ${pkgs.gnugrep}/bin/grep "Socket=" | cut -d= -f2)"
${lib.getExe' cfg.package "unl0kr"} -v -C "/etc/unl0kr.conf" | ${config.boot.initrd.systemd.package}/lib/systemd/systemd-reply-password 1 "$socket"
done
done
'';

serviceConfig.ExecStart = "${cfg.package}/libexec/unl0kr-agent";
};
};

paths = {
unl0kr-ask-password = {
description = "Forward Password Requests to unl0kr";
unl0kr-agent = {
description = "Dispatch Password Requests to unl0kr Directory Watch";

unitConfig.DefaultDependencies = false;
unitConfig.ConditionPathExists = "!/run/plymouth/pid";

after = [
"plymouth-start.service"
];
conflicts = [
"emergency.service"
"initrd-switch-root.target"
"shutdown.target"
];
unitConfig.DefaultDependencies = false;
before = [
"shutdown.target"
"paths.target"
"cryptsetup.target"
"emergency.service"
"shutdown.target"
];
wantedBy = [ "sysinit.target" ];

pathConfig = {
DirectoryNotEmpty = "/run/systemd/ask-password";
MakeDirectory = true;
Expand Down
141 changes: 76 additions & 65 deletions nixos/tests/systemd-initrd-luks-unl0kr.nix
Original file line number Diff line number Diff line change
@@ -1,75 +1,86 @@
import ./make-test-python.nix ({ lib, pkgs, ... }: let
passphrase = "secret";
in {
name = "systemd-initrd-luks-unl0kr";
meta = {
maintainers = [];
};
import ./make-test-python.nix (
{ lib, pkgs, ... }:
let
passphrase = "secret";
in
{
name = "systemd-initrd-luks-unl0kr"; # How to run an interactive test: `nix run .#nixosTests.systemd-initrd-luks-unl0kr.driverInteractive'
meta = {
maintainers = [ ];
};

enableOCR = true;
enableOCR = true;

nodes.machine = { pkgs, ... }: {
virtualisation = {
emptyDiskImages = [ 512 512 ];
useBootLoader = true;
mountHostNixStore = true;
useEFIBoot = true;
qemu.options = [
"-vga virtio"
];
};
boot.loader.systemd-boot.enable = true;
nodes.machine =
{ pkgs, ... }:
{
virtualisation = {
emptyDiskImages = [
512
512
];
useBootLoader = true;
mountHostNixStore = true;
useEFIBoot = true;
qemu.options = [
"-vga virtio"
];
};
boot.loader.systemd-boot.enable = true;

boot.initrd.availableKernelModules = [
"evdev" # for entering pw
"bochs"
];
boot.initrd.availableKernelModules = [
"bochs" # for debugging
];

environment.systemPackages = with pkgs; [ cryptsetup ];
boot.initrd = {
systemd = {
enable = true;
emergencyAccess = true;
};
unl0kr.enable = true;
};
environment.systemPackages = with pkgs; [
cryptsetup
bintools
]; # I need strings to debug buffybox
boot.initrd = {
systemd = {
enable = true;
emergencyAccess = true;
};
unl0kr.enable = true;
};

specialisation.boot-luks.configuration = {
boot.initrd.luks.devices = lib.mkVMOverride {
# We have two disks and only type one password - key reuse is in place
cryptroot.device = "/dev/vdb";
cryptroot2.device = "/dev/vdc";
specialisation.boot-luks.configuration = {
boot.initrd.luks.devices = lib.mkVMOverride {
# We have two disks and only type one password - key reuse is in place
cryptroot.device = "/dev/vdb";
cryptroot2.device = "/dev/vdc";
};
virtualisation.rootDevice = "/dev/mapper/cryptroot";
virtualisation.fileSystems."/".autoFormat = true;
# test mounting device unlocked in initrd after switching root
virtualisation.fileSystems."/cryptroot2".device = "/dev/mapper/cryptroot2";
};
};
virtualisation.rootDevice = "/dev/mapper/cryptroot";
virtualisation.fileSystems."/".autoFormat = true;
# test mounting device unlocked in initrd after switching root
virtualisation.fileSystems."/cryptroot2".device = "/dev/mapper/cryptroot2";
};
};

testScript = ''
# Create encrypted volume
machine.wait_for_unit("multi-user.target")
machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -")
machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -")
machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen -q /dev/vdc cryptroot2")
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2")
testScript = ''
# Create encrypted volume
machine.wait_for_unit("multi-user.target")
machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -")
machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -")
machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen -q /dev/vdc cryptroot2")
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2")

# Boot from the encrypted disk
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf")
machine.succeed("sync")
machine.crash()
# Boot from the encrypted disk
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf")
machine.succeed("sync")
machine.crash()

# Boot and decrypt the disk
machine.start()
machine.wait_for_text("Password required for booting")
machine.screenshot("prompt")
machine.send_chars("${passphrase}")
machine.screenshot("pw")
machine.send_chars("\n")
machine.wait_for_unit("multi-user.target")
# Boot and decrypt the disk. This part of the test is SLOW.
machine.start()
machine.wait_for_text("password") # This is the best keyword for such prompts.
machine.screenshot("prompt")
machine.send_chars("${passphrase}")
machine.screenshot("pw")
machine.send_chars("\n")
machine.wait_for_unit("multi-user.target")

assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount"), "/dev/mapper/cryptroot do not appear in mountpoints list"
assert "/dev/mapper/cryptroot2 on /cryptroot2 type ext4" in machine.succeed("mount")
'';
})
assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount"), "/dev/mapper/cryptroot do not appear in mountpoints list"
assert "/dev/mapper/cryptroot2 on /cryptroot2 type ext4" in machine.succeed("mount")
'';
}
)
58 changes: 0 additions & 58 deletions pkgs/by-name/un/unl0kr/package.nix

This file was deleted.

1 change: 1 addition & 0 deletions pkgs/top-level/aliases.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,7 @@ mapAliases {
unifi8 = unifi; # Added 2024-11-15
unifiLTS = throw "'unifiLTS' has been removed since UniFi no longer has LTS and stable releases. Use `pkgs.unifi` instead."; # Added 2024-04-11
unifiStable = throw "'unifiStable' has been removed since UniFi no longer has LTS and stable releases. Use `pkgs.unifi` instead."; # Converted to throw 2024-04-11
unl0kr = throw "'unl0kr' is now included with buffybox. Use `pkgs.buffybox` instead.";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a comment with the date at the end?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgout about it

untrunc = throw "'untrunc' has been renamed to/replaced by 'untrunc-anthwlock'"; # Converted to throw 2024-10-17
urxvt_autocomplete_all_the_things = throw "'urxvt_autocomplete_all_the_things' has been renamed to/replaced by 'rxvt-unicode-plugins.autocomplete-all-the-things'"; # Converted to throw 2024-10-17
urxvt_bidi = throw "'urxvt_bidi' has been renamed to/replaced by 'rxvt-unicode-plugins.bidi'"; # Converted to throw 2024-10-17
Expand Down
Loading