From a75aee39236d5e343fcc8bfa3602a7e1b9ee30c9 Mon Sep 17 00:00:00 2001 From: Ben Wolsieffer Date: Tue, 27 Mar 2018 19:57:52 -0400 Subject: [PATCH] nixos/grub: support initrd secrets --- nixos/doc/manual/release-notes/rl-1809.xml | 9 ++++++ .../modules/system/boot/loader/grub/grub.nix | 20 ++++--------- .../system/boot/loader/grub/install-grub.pl | 30 +++++++++++-------- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-1809.xml b/nixos/doc/manual/release-notes/rl-1809.xml index 7136f4540502..8cce0db7a546 100644 --- a/nixos/doc/manual/release-notes/rl-1809.xml +++ b/nixos/doc/manual/release-notes/rl-1809.xml @@ -107,6 +107,15 @@ $ nix-instantiate -E '(import <nixpkgsunstable> {}).gitFull' a stable URL for Nixpkgs to use to package this proprietary software. + + + The GRUB specific option + has been replaced with the generic option + . This option creates a secondary + initrd from the specified files, rather than using a manually created + initrd file. + + diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index e2cff1c1bd94..9d9f5e41e54e 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -35,6 +35,7 @@ let let efiSysMountPoint = if args.efiSysMountPoint == null then args.path else args.efiSysMountPoint; efiSysMountPoint' = replaceChars [ "/" ] [ "-" ] efiSysMountPoint; + initrdSecrets = config.boot.initrd.secrets != {}; in pkgs.writeText "grub-config.xml" (builtins.toXML { splashImage = f cfg.splashImage; @@ -49,12 +50,12 @@ let storePath = config.boot.loader.grub.storePath; bootloaderId = if args.efiBootloaderId == null then "NixOS${efiSysMountPoint'}" else args.efiBootloaderId; timeout = if config.boot.loader.timeout == null then -1 else config.boot.loader.timeout; - inherit efiSysMountPoint; + inherit efiSysMountPoint initrdSecrets; inherit (args) devices; inherit (efi) canTouchEfiVariables; inherit (cfg) version extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber - extraEntriesBeforeNixOS extraPrepareConfig extraInitrd configurationLimit copyKernels + extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios; path = (makeBinPath ([ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfs-progs @@ -283,19 +284,6 @@ in ''; }; - extraInitrd = mkOption { - type = types.nullOr types.path; - default = null; - example = "/boot/extra_initramfs.gz"; - description = '' - The path to a second initramfs to be supplied to the kernel. - This ramfs will not be copied to the store, so that it can - contain secrets such as LUKS keyfiles or ssh keys. - This implies that rolling back to a previous configuration - won't rollback the state of this file. - ''; - }; - useOSProber = mkOption { default = false; type = types.bool; @@ -528,6 +516,8 @@ in { path = "/boot"; inherit (cfg) devices; inherit (efi) efiSysMountPoint; } ]; + boot.loader.supportsInitrdSecrets = true; + system.build.installBootLoader = let install-grub-pl = pkgs.substituteAll { diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 8bd203106f55..60d952889895 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -49,7 +49,7 @@ my $extraPrepareConfig = get("extraPrepareConfig"); my $extraPerEntryConfig = get("extraPerEntryConfig"); my $extraEntries = get("extraEntries"); my $extraEntriesBeforeNixOS = get("extraEntriesBeforeNixOS") eq "true"; -my $extraInitrd = get("extraInitrd"); +my $initrdSecrets = get("initrdSecrets"); my $splashImage = get("splashImage"); my $configurationLimit = int(get("configurationLimit")); my $copyKernels = get("copyKernels") eq "true"; @@ -228,13 +228,6 @@ my $grubStore; if ($copyKernels == 0) { $grubStore = GrubFs($storePath); } -my $extraInitrdPath; -if ($extraInitrd) { - if (! -f $extraInitrd) { - print STDERR "Warning: the specified extraInitrd " . $extraInitrd . " doesn't exist. Your system won't boot without it.\n"; - } - $extraInitrdPath = GrubFs($extraInitrd); -} # Generate the header. my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n"; @@ -348,9 +341,23 @@ sub addEntry { my $kernel = copyToKernelsDir(Cwd::abs_path("$path/kernel")); my $initrd = copyToKernelsDir(Cwd::abs_path("$path/initrd")); - if ($extraInitrd) { - $initrd .= " " .$extraInitrdPath->path; + + # Include second initrd with secrets + if ($initrdSecrets) { + # Get last element of path + $initrd =~ /\/([^\/]+)$/; + my $initrdSecretsPath = "$bootPath/kernels/$1-secrets"; + $initrd .= " $initrd-secrets"; + my $oldUmask = umask; + # Make sure initrd is not world readable (won't work if /boot is FAT) + umask 0137; + my $initrdSecretsPathTemp = File::Temp::mktemp("$initrdSecretsPath.XXXXXXXX"); + system("$path/append-initrd-secrets", $initrdSecretsPathTemp) == 0 or die "failed to create initrd secrets\n"; + rename $initrdSecretsPathTemp, $initrdSecretsPath or die "failed to move initrd secrets into place\n"; + umask $oldUmask; + $copied{$initrdSecretsPath} = 1; } + my $xen = -e "$path/xen.gz" ? copyToKernelsDir(Cwd::abs_path("$path/xen.gz")) : undef; # FIXME: $confName @@ -373,9 +380,6 @@ sub addEntry { if ($copyKernels == 0) { $conf .= $grubStore->search . "\n"; } - if ($extraInitrd) { - $conf .= $extraInitrdPath->search . "\n"; - } $conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig; $conf .= " multiboot $xen $xenParams\n" if $xen; $conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n";