nixos/grub: support initrd secrets
This commit is contained in:
		
							parent
							
								
									50a5e5597a
								
							
						
					
					
						commit
						14eceb5991
					
				@ -441,6 +441,20 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
 | 
			
		||||
       recommended to only use lower-case characters.
 | 
			
		||||
     </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.
 | 
			
		||||
 | 
			
		||||
     Due to an existing bug with <option>boot.loader.grub.extraInitrd</option>,
 | 
			
		||||
     it is not possible to directly boot an older generation that used that
 | 
			
		||||
     option. It is still possible to rollback to that generation if the required
 | 
			
		||||
     initrd file has not been deleted.
 | 
			
		||||
    </para>
 | 
			
		||||
   </listitem>
 | 
			
		||||
  </itemizedlist>
 | 
			
		||||
 </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ let
 | 
			
		||||
      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 gfxpayloadEfi gfxpayloadBios;
 | 
			
		||||
      path = with pkgs; makeBinPath (
 | 
			
		||||
        [ coreutils gnused gnugrep findutils diffutils btrfs-progs utillinux mdadm ]
 | 
			
		||||
@ -292,19 +292,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;
 | 
			
		||||
@ -608,6 +595,8 @@ in
 | 
			
		||||
        { path = "/boot"; inherit (cfg) devices; inherit (efi) efiSysMountPoint; }
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      boot.loader.supportsInitrdSecrets = true;
 | 
			
		||||
 | 
			
		||||
      system.build.installBootLoader =
 | 
			
		||||
        let
 | 
			
		||||
          install-grub-pl = pkgs.substituteAll {
 | 
			
		||||
@ -705,6 +694,24 @@ in
 | 
			
		||||
      (mkRenamedOptionModule [ "boot" "grubDevice" ] [ "boot" "loader" "grub" "device" ])
 | 
			
		||||
      (mkRenamedOptionModule [ "boot" "bootMount" ] [ "boot" "loader" "grub" "bootDevice" ])
 | 
			
		||||
      (mkRenamedOptionModule [ "boot" "grubSplashImage" ] [ "boot" "loader" "grub" "splashImage" ])
 | 
			
		||||
      (mkRemovedOptionModule [ "boot" "loader" "grub" "extraInitrd" ] ''
 | 
			
		||||
        This option has been replaced with the bootloader agnostic
 | 
			
		||||
        boot.initrd.secrets option. To migrate to the initrd secrets system,
 | 
			
		||||
        extract the extraInitrd archive into your main filesystem:
 | 
			
		||||
 | 
			
		||||
          # zcat /boot/extra_initramfs.gz | cpio -idvmD /etc/secrets/initrd
 | 
			
		||||
          /path/to/secret1
 | 
			
		||||
          /path/to/secret2
 | 
			
		||||
 | 
			
		||||
        then replace boot.loader.grub.extraInitrd with boot.initrd.secrets:
 | 
			
		||||
 | 
			
		||||
          boot.initrd.secrets = {
 | 
			
		||||
            "/path/to/secret1" = "/etc/secrets/initrd/path/to/secret1";
 | 
			
		||||
            "/path/to/secret2" = "/etc/secrets/initrd/path/to/secret2";
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
        See the boot.initrd.secrets option documentation for more information.
 | 
			
		||||
      '')
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,6 @@ my $extraPrepareConfig = get("extraPrepareConfig");
 | 
			
		||||
my $extraPerEntryConfig = get("extraPerEntryConfig");
 | 
			
		||||
my $extraEntries = get("extraEntries");
 | 
			
		||||
my $extraEntriesBeforeNixOS = get("extraEntriesBeforeNixOS") eq "true";
 | 
			
		||||
my $extraInitrd = get("extraInitrd");
 | 
			
		||||
my $splashImage = get("splashImage");
 | 
			
		||||
my $splashMode = get("splashMode");
 | 
			
		||||
my $backgroundColor = get("backgroundColor");
 | 
			
		||||
@ -232,13 +231,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";
 | 
			
		||||
@ -363,9 +355,30 @@ 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 (-e -x "$path/append-initrd-secrets") {
 | 
			
		||||
      my $initrdName = basename($initrd);
 | 
			
		||||
      my $initrdSecretsPath = "$bootPath/kernels/$initrdName-secrets";
 | 
			
		||||
 | 
			
		||||
      mkpath(dirname($initrdSecretsPath), 0, 0755);
 | 
			
		||||
      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";
 | 
			
		||||
      # Check whether any secrets were actually added
 | 
			
		||||
      if (-e $initrdSecretsPathTemp && ! -z _) {
 | 
			
		||||
        rename $initrdSecretsPathTemp, $initrdSecretsPath or die "failed to move initrd secrets into place\n";
 | 
			
		||||
        $copied{$initrdSecretsPath} = 1;
 | 
			
		||||
        $initrd .= " " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/kernels/$initrdName-secrets";
 | 
			
		||||
      } else {
 | 
			
		||||
        unlink $initrdSecretsPathTemp;
 | 
			
		||||
        rmdir dirname($initrdSecretsPathTemp);
 | 
			
		||||
      }
 | 
			
		||||
      umask $oldUmask;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    my $xen = -e "$path/xen.gz" ? copyToKernelsDir(Cwd::abs_path("$path/xen.gz")) : undef;
 | 
			
		||||
 | 
			
		||||
    # FIXME: $confName
 | 
			
		||||
@ -388,9 +401,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";
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user