Working on secrets
This commit is contained in:
+36
-37
@@ -2,12 +2,9 @@
|
||||
|
||||
with lib;
|
||||
let
|
||||
all-secrets = config.fudo.secrets;
|
||||
|
||||
encrypt-on-disk = name:
|
||||
{ target-host, source-file }:
|
||||
encrypt-on-disk = { secret-name, target-host, source-file }:
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "${name}-secret";
|
||||
name = "${target-host}-${secret-name}-secret";
|
||||
phases = "installPhase";
|
||||
buildInputs = [ pkgs.age ];
|
||||
installPhase = let key = config.fudo.hosts.${target-host}.ssh-pubkey;
|
||||
@@ -16,41 +13,42 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
decrypt-script = name:
|
||||
{ source-file, target-host, target-file, decrypt-key, user, group
|
||||
, permissions }:
|
||||
pkgs.writeShellScript "decrypt-fudo-secret-${name}.sh" ''
|
||||
decrypt-script = { secret-name, source-file, target-host, target-file
|
||||
, decrypt-key, user, group, permissions }:
|
||||
pkgs.writeShellScript
|
||||
"decrypt-fudo-secret-${target-host}-${secret-name}.sh" ''
|
||||
rm -rf ${target-file}
|
||||
age -d -i ${decrypt-key} -o ${target-file} ${
|
||||
encrypt-on-disk name { inherit source-file target-host; }
|
||||
encrypt-on-disk { inherit secret-name source-file target-host; }
|
||||
}
|
||||
chown ${user}:${group} ${target-file}
|
||||
chmod ${permissions} ${target-file}
|
||||
'';
|
||||
|
||||
secret-service = name:
|
||||
{ source-file, target-host, target-file, user, group, permissions
|
||||
, key-type ? "ed25519" }: {
|
||||
description = "decrypt secret ${name} for ${target-host}.";
|
||||
secret-service = target-host: secret-name:
|
||||
{ source-file, target-file, user, group, permissions, key-type ? "ed25519"
|
||||
}: {
|
||||
description = "decrypt secret ${secret-name} for ${target-host}.";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStartPre = pkgs.writeShellScript "prepare-${name}-secret-dir.sh" ''
|
||||
TARGET_DIR=$(dirname ${target-file})
|
||||
if [[ ! -d "$TARGET_DIR" ]]; then
|
||||
mkdir -p "$TARGET_DIR"
|
||||
fi
|
||||
'';
|
||||
ExecStop = pkgs.writeShellScript "clear-${name}-secret.sh" ''
|
||||
ExecStartPre = pkgs.writeShellScript
|
||||
"prepare-${target-host}-${secret-name}-secret-dir.sh" ''
|
||||
TARGET_DIR=$(dirname ${target-file})
|
||||
if [[ ! -d "$TARGET_DIR" ]]; then
|
||||
mkdir -p "$TARGET_DIR"
|
||||
fi
|
||||
'';
|
||||
ExecStop = pkgs.writeShellScript "clear-${secret-name}-secret.sh" ''
|
||||
rm -f ${target-file}
|
||||
'';
|
||||
ExecStart = let
|
||||
decrypt-keys =
|
||||
filter (key: key.type == key-type) config.services.openssh.hostKeys;
|
||||
decrypt-key = head (map (key: key.path) decrypt-keys);
|
||||
in decrypt-script name {
|
||||
inherit source-file target-host target-file decrypt-key user group
|
||||
permissions;
|
||||
in decrypt-script {
|
||||
inherit secret-name source-file target-host target-file decrypt-key
|
||||
user group permissions;
|
||||
};
|
||||
};
|
||||
path = [ pkgs.age ];
|
||||
@@ -63,12 +61,6 @@ let
|
||||
description = "File from which to load the secret.";
|
||||
};
|
||||
|
||||
target-host = mkOption {
|
||||
type = str;
|
||||
description =
|
||||
"Host to which the secret belongs (determins SSH key to encrypt).";
|
||||
};
|
||||
|
||||
target-file = mkOption {
|
||||
type = str;
|
||||
description =
|
||||
@@ -97,19 +89,26 @@ let
|
||||
in {
|
||||
options.fudo.secrets = with types;
|
||||
mkOption {
|
||||
type = attrsOf (submodule secretOpts);
|
||||
description = "Map of secrets to secret config.";
|
||||
type = attrsOf (attrsOf (submodule secretOpts));
|
||||
description = "Map of hosts, to secrets, to secret config.";
|
||||
default = { };
|
||||
example = {
|
||||
my-host = {
|
||||
my-host-secret = {
|
||||
source-file = /path/to/file/on/this/host;
|
||||
target-file = "/target/path/on/host";
|
||||
user = "some-user";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.services = let
|
||||
hostname = config.instance.hostname;
|
||||
host-secrets =
|
||||
filterAttrs (secret: secretOpts: secretOpts.target-host == hostname)
|
||||
all-secrets;
|
||||
host-secrets = config.fudo.secrets.${hostname};
|
||||
in mapAttrs' (secret: secretOpts:
|
||||
(nameValuePair "fudo-secret-${secret}"
|
||||
(secret-service secret secretOpts))) host-secrets;
|
||||
(nameValuePair "fudo-secret-${hostname}-${secret}"
|
||||
(secret-service hostname secret secretOpts))) host-secrets;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user