Add facility to append secrets to the initrd

This commit is contained in:
Shea Levy 2017-04-02 14:45:44 -04:00
parent ff4fa6387e
commit 59c0977300
3 changed files with 100 additions and 3 deletions

View file

@ -53,6 +53,8 @@ let
ln -s ${config.system.build.initialRamdisk}/initrd $out/initrd
ln -s ${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets $out
ln -s ${config.hardware.firmware}/lib/firmware $out/firmware
''}

View file

@ -8,6 +8,14 @@ export LD_LIBRARY_PATH=@extraUtils@/lib
export PATH=@extraUtils@/bin
ln -s @extraUtils@/bin /bin
# Copy the secrets to their needed location
if [ -d "@extraUtils@/secrets" ]; then
for secret in $(cd "@extraUtils@/secrets"; find . -type f); do
mkdir -p $(dirname "/$secret")
ln -s "@extraUtils@/secrets/$secret" "$secret"
done
fi
# Stop LVM complaining about fd3
export LVM_SUPPRESS_FD_WARNINGS=true

View file

@ -82,6 +82,17 @@ let
copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/resize2fs
''}
# Copy secrets if needed.
${optionalString (!config.boot.loader.supportsInitrdSecrets)
(concatStringsSep "\n" (mapAttrsToList (dest: source:
let source' = if source == null then dest else source; in
''
mkdir -p $(dirname "$out/secrets/${dest}")
cp -a ${source'} "$out/secrets/${dest}"
''
) config.boot.initrd.secrets))
}
${config.boot.initrd.extraUtilsCommands}
# Copy ld manually since it isn't detected correctly
@ -242,6 +253,52 @@ let
];
};
# Script to add secret files to the initrd at bootloader update time
initialRamdiskSecretAppender =
pkgs.writeScriptBin "append-initrd-secrets"
''
#!${pkgs.bash}/bin/bash -e
function usage {
echo "USAGE: $0 INITRD_FILE" >&2
echo "Appends this configuration's secrets to INITRD_FILE" >&2
}
if [ $# -ne 1 ]; then
usage
exit 1
fi
if [ "$1"x = "--helpx" ]; then
usage
exit 0
fi
${lib.optionalString (config.boot.initrd.secrets == {})
"exit 0"}
export PATH=${pkgs.coreutils}/bin:${pkgs.cpio}/bin:${pkgs.gzip}/bin:${pkgs.findutils}/bin
function cleanup {
if [ -n "$tmp" -a -d "$tmp" ]; then
rm -fR "$tmp"
fi
}
trap cleanup EXIT
tmp=$(mktemp -d initrd-secrets.XXXXXXXXXX)
${lib.concatStringsSep "\n" (mapAttrsToList (dest: source:
let source' = if source == null then dest else toString source; in
''
mkdir -p $(dirname "$tmp/${dest}")
cp -a ${source'} "$tmp/${dest}"
''
) config.boot.initrd.secrets)
}
(cd "$tmp" && find . | cpio -H newc -o) | gzip >>"$1"
'';
in
{
@ -370,6 +427,25 @@ in
example = "xz";
};
boot.initrd.secrets = mkOption
{ internal = true;
default = {};
type = types.attrsOf (types.nullOr types.path);
description =
''
Secrets to append to the initrd. The attribute name is the
path the secret should have inside the initrd, the value
is the path it should be copied from (or null for the same
path inside and out).
'';
example = literalExample
''
{ "/etc/dropbear/dropbear_rsa_host_key" =
./secret-dropbear-key;
}
'';
};
boot.initrd.supportedFilesystems = mkOption {
default = [ ];
example = [ "btrfs" ];
@ -377,6 +453,18 @@ in
description = "Names of supported filesystem types in the initial ramdisk.";
};
boot.loader.supportsInitrdSecrets = mkOption
{ internal = true;
default = false;
type = types.bool;
description =
''
Whether the bootloader setup runs append-initrd-secrets.
If not, any needed secrets must be copied into the initrd
and thus added to the store.
'';
};
fileSystems = mkOption {
options.neededForBoot = mkOption {
default = false;
@ -404,9 +492,8 @@ in
}
];
system.build.bootStage1 = bootStage1;
system.build.initialRamdisk = initialRamdisk;
system.build.extraUtils = extraUtils;
system.build =
{ inherit bootStage1 initialRamdisk initialRamdiskSecretAppender extraUtils; };
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "TMPFS")