mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-11 12:15:34 +03:00
nixos/limine: add support for secure boot
Signed-off-by: John Titor <50095635+JohnRTitor@users.noreply.github.com>
This commit is contained in:
parent
b97b6308bd
commit
36ecfe6216
6 changed files with 150 additions and 2 deletions
|
@ -34,4 +34,3 @@
|
||||||
### Additions and Improvements {#sec-nixpkgs-release-25.11-lib-additions-improvements}
|
### Additions and Improvements {#sec-nixpkgs-release-25.11-lib-additions-improvements}
|
||||||
|
|
||||||
- Create the first release note entry in this section!
|
- Create the first release note entry in this section!
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
|
|
||||||
- Create the first release note entry in this section!
|
- Secure boot support can now be enabled for the Limine bootloader through {option}`boot.loader.limine.secureBoot.enable`. Bootloader install script signs the bootloader, then kernels are hashed during system rebuild and written to a config. This allows Limine to boot only the kernels installed through NixOS system.
|
||||||
|
|
||||||
## New Modules {#sec-release-25.11-new-modules}
|
## New Modules {#sec-release-25.11-new-modules}
|
||||||
|
|
||||||
|
|
|
@ -249,6 +249,10 @@ def main():
|
||||||
partition formatted as FAT.
|
partition formatted as FAT.
|
||||||
'''))
|
'''))
|
||||||
|
|
||||||
|
if config('secureBoot')['enable'] and not config('secureBoot')['createAndEnrollKeys'] and not os.path.exists("/var/lib/sbctl"):
|
||||||
|
print("There are no sbctl secure boot keys present. Please generate some.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if not os.path.exists(limine_dir):
|
if not os.path.exists(limine_dir):
|
||||||
os.makedirs(limine_dir)
|
os.makedirs(limine_dir)
|
||||||
else:
|
else:
|
||||||
|
@ -352,6 +356,28 @@ def main():
|
||||||
print('error: failed to enroll limine config.', file=sys.stderr)
|
print('error: failed to enroll limine config.', file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
if config('secureBoot')['enable']:
|
||||||
|
sbctl = os.path.join(config('secureBoot')['sbctl'], 'bin', 'sbctl')
|
||||||
|
if config('secureBoot')['createAndEnrollKeys']:
|
||||||
|
print("TEST MODE: creating and enrolling keys")
|
||||||
|
try:
|
||||||
|
subprocess.run([sbctl, 'create-keys'])
|
||||||
|
except:
|
||||||
|
print('error: failed to create keys', file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
try:
|
||||||
|
subprocess.run([sbctl, 'enroll-keys', '--yes-this-might-brick-my-machine'])
|
||||||
|
except:
|
||||||
|
print('error: failed to enroll keys', file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print('signing limine...')
|
||||||
|
try:
|
||||||
|
subprocess.run([sbctl, 'sign', dest_path])
|
||||||
|
except:
|
||||||
|
print('error: failed to sign limine', file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if not config('efiRemovable') and not config('canTouchEfiVariables'):
|
if not config('efiRemovable') and not config('canTouchEfiVariables'):
|
||||||
print('warning: boot.loader.efi.canTouchEfiVariables is set to false while boot.loader.limine.efiInstallAsRemovable.\n This may render the system unbootable.')
|
print('warning: boot.loader.efi.canTouchEfiVariables is set to false while boot.loader.limine.efiInstallAsRemovable.\n This may render the system unbootable.')
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ let
|
||||||
canTouchEfiVariables = efi.canTouchEfiVariables;
|
canTouchEfiVariables = efi.canTouchEfiVariables;
|
||||||
efiSupport = cfg.efiSupport;
|
efiSupport = cfg.efiSupport;
|
||||||
efiRemovable = cfg.efiInstallAsRemovable;
|
efiRemovable = cfg.efiInstallAsRemovable;
|
||||||
|
secureBoot = cfg.secureBoot;
|
||||||
biosSupport = cfg.biosSupport;
|
biosSupport = cfg.biosSupport;
|
||||||
biosDevice = cfg.biosDevice;
|
biosDevice = cfg.biosDevice;
|
||||||
partitionIndex = cfg.partitionIndex;
|
partitionIndex = cfg.partitionIndex;
|
||||||
|
@ -177,6 +178,41 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
secureBoot = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
description = ''
|
||||||
|
Whether to use sign the limine binary with sbctl.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
This requires you to already have generated the keys and enrolled them with {command}`sbctl`.
|
||||||
|
|
||||||
|
To create keys use {command}`sbctl create-keys`.
|
||||||
|
|
||||||
|
To enroll them first reset secure boot to "Setup Mode". This is device specific.
|
||||||
|
Then enroll them using {command}`sbctl enroll-keys -m -f`.
|
||||||
|
|
||||||
|
You can now rebuild your system with this option enabled.
|
||||||
|
|
||||||
|
Afterwards turn setup mode off and enable secure boot.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
createAndEnrollKeys = lib.mkEnableOption null // {
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Creates secure boot signing keys and enrolls them during bootloader installation.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
This is used for automated nixos tests.
|
||||||
|
NOT INTENDED to be used on a real system.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sbctl = lib.mkPackageOption pkgs "sbctl" { };
|
||||||
|
};
|
||||||
|
|
||||||
style = {
|
style = {
|
||||||
wallpapers = lib.mkOption {
|
wallpapers = lib.mkOption {
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
@ -368,5 +404,57 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
(lib.mkIf (cfg.enable && cfg.secureBoot.enable) {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.enrollConfig;
|
||||||
|
message = "Disabling enrollConfig allows bypassing secure boot.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.validateChecksums;
|
||||||
|
message = "Disabling validateChecksums allows bypassing secure boot.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.panicOnChecksumMismatch;
|
||||||
|
message = "Disabling panicOnChecksumMismatch allows bypassing secure boot.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.efiSupport;
|
||||||
|
message = "Secure boot is only supported on EFI systems.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.loader.limine.enrollConfig = true;
|
||||||
|
boot.loader.limine.validateChecksums = true;
|
||||||
|
boot.loader.limine.panicOnChecksumMismatch = true;
|
||||||
|
})
|
||||||
|
|
||||||
|
# Fwupd binary needs to be signed in secure boot mode
|
||||||
|
(lib.mkIf (cfg.enable && cfg.secureBoot.enable && config.services.fwupd.enable) {
|
||||||
|
systemd.services.fwupd = {
|
||||||
|
environment.FWUPD_EFIAPPDIR = "/run/fwupd-efi";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.fwupd-efi = {
|
||||||
|
description = "Sign fwupd EFI app for secure boot";
|
||||||
|
wantedBy = [ "fwupd.service" ];
|
||||||
|
partOf = [ "fwupd.service" ];
|
||||||
|
before = [ "fwupd.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
RuntimeDirectory = "fwupd-efi";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
cp ${config.services.fwupd.package.fwupd-efi}/libexec/fwupd/efi/fwupd*.efi /run/fwupd-efi/
|
||||||
|
chmod +w /run/fwupd-efi/fwupd*.efi
|
||||||
|
${lib.getExe pkgs.sbctl} sign /run/fwupd-efi/fwupd*.efi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.fwupd.uefiCapsuleSettings = {
|
||||||
|
DisableShimForSecureBoot = true;
|
||||||
|
};
|
||||||
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
checksum = runTest ./checksum.nix;
|
checksum = runTest ./checksum.nix;
|
||||||
|
secureBoot = runTest ./secure-boot.nix;
|
||||||
uefi = runTest ./uefi.nix;
|
uefi = runTest ./uefi.nix;
|
||||||
}
|
}
|
||||||
|
|
34
nixos/tests/limine/secure-boot.nix
Normal file
34
nixos/tests/limine/secure-boot.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
name = "secureBoot";
|
||||||
|
meta.maintainers = with lib.maintainers; [
|
||||||
|
programmerlexi
|
||||||
|
];
|
||||||
|
meta.platforms = [
|
||||||
|
"aarch64-linux"
|
||||||
|
"i686-linux"
|
||||||
|
"x86_64-linux"
|
||||||
|
];
|
||||||
|
nodes.machine =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
virtualisation.useBootLoader = true;
|
||||||
|
virtualisation.useEFIBoot = true;
|
||||||
|
virtualisation.useSecureBoot = true;
|
||||||
|
virtualisation.efi.OVMF = pkgs.OVMFFull.fd;
|
||||||
|
virtualisation.efi.keepVariables = true;
|
||||||
|
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
boot.loader.limine.enable = true;
|
||||||
|
boot.loader.limine.efiSupport = true;
|
||||||
|
boot.loader.limine.secureBoot.enable = true;
|
||||||
|
boot.loader.limine.secureBoot.createAndEnrollKeys = true;
|
||||||
|
boot.loader.timeout = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
machine.start()
|
||||||
|
assert "Secure Boot: enabled (user)" in machine.succeed("bootctl status")
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue