mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-09 19:13:26 +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}
|
||||
|
||||
- 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. -->
|
||||
|
||||
- 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}
|
||||
|
||||
|
|
|
@ -249,6 +249,10 @@ def main():
|
|||
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):
|
||||
os.makedirs(limine_dir)
|
||||
else:
|
||||
|
@ -352,6 +356,28 @@ def main():
|
|||
print('error: failed to enroll limine config.', file=sys.stderr)
|
||||
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'):
|
||||
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;
|
||||
efiSupport = cfg.efiSupport;
|
||||
efiRemovable = cfg.efiInstallAsRemovable;
|
||||
secureBoot = cfg.secureBoot;
|
||||
biosSupport = cfg.biosSupport;
|
||||
biosDevice = cfg.biosDevice;
|
||||
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 = {
|
||||
wallpapers = lib.mkOption {
|
||||
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;
|
||||
secureBoot = runTest ./secure-boot.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