Merge pull request #38263 from lopsided98/grub-initrd-secrets

grub: support initrd secrets

Changed files
+31 -28
nixos
doc
manual
release-notes
modules
system
boot
+9
nixos/doc/manual/release-notes/rl-1809.xml
···
<literal>gnucash24</literal>.
</para>
</listitem>
+
<listitem>
+
<para>
+
The GRUB specific option <option>boot.loader.grub.extraInitrd</option>
+
has been replaced with the generic option
+
<option>boot.initrd.secrets</option>. This option creates a secondary
+
initrd from the specified files, rather than using a manually created
+
initrd file.
+
</para>
+
</listitem>
</itemizedlist>
</section>
+5 -15
nixos/modules/system/boot/loader/grub/grub.nix
···
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;
···
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
···
'';
};
-
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;
···
boot.loader.grub.mirroredBoots = optionals (cfg.devices != [ ]) [
{ path = "/boot"; inherit (cfg) devices; inherit (efi) efiSysMountPoint; }
];
+
+
boot.loader.supportsInitrdSecrets = true;
system.build.installBootLoader =
let
+17 -13
nixos/modules/system/boot/loader/grub/install-grub.pl
···
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";
···
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";
···
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
···
$conf .= $grubBoot->search . "\n";
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;