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

grub: support initrd secrets

authored by Joachim F and committed by GitHub c06d7950 4c25fbe3

+31 -28
+9
nixos/doc/manual/release-notes/rl-1809.xml
··· 121 121 <literal>gnucash24</literal>. 122 122 </para> 123 123 </listitem> 124 + <listitem> 125 + <para> 126 + The GRUB specific option <option>boot.loader.grub.extraInitrd</option> 127 + has been replaced with the generic option 128 + <option>boot.initrd.secrets</option>. This option creates a secondary 129 + initrd from the specified files, rather than using a manually created 130 + initrd file. 131 + </para> 132 + </listitem> 124 133 </itemizedlist> 125 134 </section> 126 135
+5 -15
nixos/modules/system/boot/loader/grub/grub.nix
··· 35 35 let 36 36 efiSysMountPoint = if args.efiSysMountPoint == null then args.path else args.efiSysMountPoint; 37 37 efiSysMountPoint' = replaceChars [ "/" ] [ "-" ] efiSysMountPoint; 38 + initrdSecrets = config.boot.initrd.secrets != {}; 38 39 in 39 40 pkgs.writeText "grub-config.xml" (builtins.toXML 40 41 { splashImage = f cfg.splashImage; ··· 49 50 storePath = config.boot.loader.grub.storePath; 50 51 bootloaderId = if args.efiBootloaderId == null then "NixOS${efiSysMountPoint'}" else args.efiBootloaderId; 51 52 timeout = if config.boot.loader.timeout == null then -1 else config.boot.loader.timeout; 52 - inherit efiSysMountPoint; 53 + inherit efiSysMountPoint initrdSecrets; 53 54 inherit (args) devices; 54 55 inherit (efi) canTouchEfiVariables; 55 56 inherit (cfg) 56 57 version extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber 57 - extraEntriesBeforeNixOS extraPrepareConfig extraInitrd configurationLimit copyKernels 58 + extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels 58 59 default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios; 59 60 path = (makeBinPath ([ 60 61 pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfs-progs ··· 284 285 ''; 285 286 }; 286 287 287 - extraInitrd = mkOption { 288 - type = types.nullOr types.path; 289 - default = null; 290 - example = "/boot/extra_initramfs.gz"; 291 - description = '' 292 - The path to a second initramfs to be supplied to the kernel. 293 - This ramfs will not be copied to the store, so that it can 294 - contain secrets such as LUKS keyfiles or ssh keys. 295 - This implies that rolling back to a previous configuration 296 - won't rollback the state of this file. 297 - ''; 298 - }; 299 - 300 288 useOSProber = mkOption { 301 289 default = false; 302 290 type = types.bool; ··· 540 528 boot.loader.grub.mirroredBoots = optionals (cfg.devices != [ ]) [ 541 529 { path = "/boot"; inherit (cfg) devices; inherit (efi) efiSysMountPoint; } 542 530 ]; 531 + 532 + boot.loader.supportsInitrdSecrets = true; 543 533 544 534 system.build.installBootLoader = 545 535 let
+17 -13
nixos/modules/system/boot/loader/grub/install-grub.pl
··· 49 49 my $extraPerEntryConfig = get("extraPerEntryConfig"); 50 50 my $extraEntries = get("extraEntries"); 51 51 my $extraEntriesBeforeNixOS = get("extraEntriesBeforeNixOS") eq "true"; 52 - my $extraInitrd = get("extraInitrd"); 52 + my $initrdSecrets = get("initrdSecrets"); 53 53 my $splashImage = get("splashImage"); 54 54 my $configurationLimit = int(get("configurationLimit")); 55 55 my $copyKernels = get("copyKernels") eq "true"; ··· 228 228 if ($copyKernels == 0) { 229 229 $grubStore = GrubFs($storePath); 230 230 } 231 - my $extraInitrdPath; 232 - if ($extraInitrd) { 233 - if (! -f $extraInitrd) { 234 - print STDERR "Warning: the specified extraInitrd " . $extraInitrd . " doesn't exist. Your system won't boot without it.\n"; 235 - } 236 - $extraInitrdPath = GrubFs($extraInitrd); 237 - } 238 231 239 232 # Generate the header. 240 233 my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n"; ··· 354 347 355 348 my $kernel = copyToKernelsDir(Cwd::abs_path("$path/kernel")); 356 349 my $initrd = copyToKernelsDir(Cwd::abs_path("$path/initrd")); 357 - if ($extraInitrd) { 358 - $initrd .= " " .$extraInitrdPath->path; 350 + 351 + # Include second initrd with secrets 352 + if ($initrdSecrets) { 353 + # Get last element of path 354 + $initrd =~ /\/([^\/]+)$/; 355 + my $initrdSecretsPath = "$bootPath/kernels/$1-secrets"; 356 + $initrd .= " $initrd-secrets"; 357 + my $oldUmask = umask; 358 + # Make sure initrd is not world readable (won't work if /boot is FAT) 359 + umask 0137; 360 + my $initrdSecretsPathTemp = File::Temp::mktemp("$initrdSecretsPath.XXXXXXXX"); 361 + system("$path/append-initrd-secrets", $initrdSecretsPathTemp) == 0 or die "failed to create initrd secrets\n"; 362 + rename $initrdSecretsPathTemp, $initrdSecretsPath or die "failed to move initrd secrets into place\n"; 363 + umask $oldUmask; 364 + $copied{$initrdSecretsPath} = 1; 359 365 } 366 + 360 367 my $xen = -e "$path/xen.gz" ? copyToKernelsDir(Cwd::abs_path("$path/xen.gz")) : undef; 361 368 362 369 # FIXME: $confName ··· 378 385 $conf .= $grubBoot->search . "\n"; 379 386 if ($copyKernels == 0) { 380 387 $conf .= $grubStore->search . "\n"; 381 - } 382 - if ($extraInitrd) { 383 - $conf .= $extraInitrdPath->search . "\n"; 384 388 } 385 389 $conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig; 386 390 $conf .= " multiboot $xen $xenParams\n" if $xen;