simplify secrets file format
Each secret file to be deployed is now backed by one local file. This simplifies 'setup-secrets' and the secret definitions. Also, with the old format it was not possible to add new secrets to secrets.nix in a simple way. Old secrets are automatically converted to the new format when running nix-shell. Using the new option 'nix-bitcoin.secrets', secrets are now directly defined by the services that use them.
This commit is contained in:
parent
314272a228
commit
b1e13e9415
15 changed files with 151 additions and 152 deletions
|
|
@ -1,68 +0,0 @@
|
|||
{ secretsFile ? null, config ? null }:
|
||||
let
|
||||
secrets = import secretsFile;
|
||||
secretsDir = "/secrets/";
|
||||
secret = { text ? null, keyFile ? null, user, group ? user }: {
|
||||
inherit text keyFile user group;
|
||||
destDir = secretsDir;
|
||||
permissions = "0440";
|
||||
};
|
||||
in rec {
|
||||
allSecrets = {
|
||||
bitcoin-rpcpassword = secret {
|
||||
text = secrets.bitcoinrpcpassword;
|
||||
user = "bitcoin";
|
||||
group = "bitcoinrpc";
|
||||
};
|
||||
lnd-wallet-password = secret {
|
||||
text = secrets.lnd-wallet-password;
|
||||
user = "lnd";
|
||||
};
|
||||
lightning-charge-api-token = secret {
|
||||
text = "API_TOKEN=" + secrets.lightning-charge-api-token;
|
||||
user = "clightning";
|
||||
};
|
||||
# variable is called CHARGE_TOKEN instead of API_TOKEN
|
||||
lightning-charge-api-token-for-nanopos = secret {
|
||||
text = "CHARGE_TOKEN=" + secrets.lightning-charge-api-token;
|
||||
user = "nanopos";
|
||||
};
|
||||
liquid-rpcpassword = secret {
|
||||
text = secrets.liquidrpcpassword;
|
||||
user = "liquid";
|
||||
};
|
||||
spark-wallet-login = secret {
|
||||
text = "login=" + "spark-wallet:" + secrets.spark-wallet-password;
|
||||
user = "clightning";
|
||||
};
|
||||
nginx_key = secret {
|
||||
keyFile = toString ../../secrets/nginx.key;
|
||||
user = "nginx";
|
||||
group = "root";
|
||||
};
|
||||
nginx_cert = secret {
|
||||
keyFile = toString ../../secrets/nginx.cert;
|
||||
user = "nginx";
|
||||
group = "root";
|
||||
};
|
||||
lnd_key = secret {
|
||||
keyFile = toString ../../secrets/lnd.key;
|
||||
user = "lnd";
|
||||
};
|
||||
lnd_cert = secret {
|
||||
keyFile = toString ../../secrets/lnd.cert;
|
||||
user = "lnd";
|
||||
};
|
||||
};
|
||||
|
||||
activeSecrets = let
|
||||
secretsFor = service: attrs: if service.enable then attrs else {};
|
||||
in with allSecrets;
|
||||
(secretsFor config.services.bitcoind { inherit bitcoin-rpcpassword; })
|
||||
// (secretsFor config.services.lnd { inherit lnd-wallet-password lnd_key lnd_cert; })
|
||||
// (secretsFor config.services.lightning-charge { inherit lightning-charge-api-token; })
|
||||
// (secretsFor config.services.nanopos { inherit lightning-charge-api-token-for-nanopos; })
|
||||
// (secretsFor config.services.liquidd { inherit liquid-rpcpassword; })
|
||||
// (secretsFor config.services.spark-wallet { inherit spark-wallet-login; })
|
||||
// (secretsFor config.services.electrs { inherit nginx_key nginx_cert; });
|
||||
}
|
||||
|
|
@ -2,18 +2,41 @@
|
|||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.nix-bitcoin;
|
||||
secretsDir = "/secrets/"; # TODO: make this an option
|
||||
|
||||
secrets = (import ./make-secrets.nix { inherit config; }).activeSecrets;
|
||||
|
||||
setupSecrets = concatStrings (mapAttrsToList (n: v: ''
|
||||
setupSecret ${n} ${v.user} ${v.group} ${v.permissions} ${optionalString (v.keyFile != null) (baseNameOf v.keyFile)}
|
||||
'') secrets);
|
||||
setupSecret ${n} ${v.user} ${v.group} ${v.permissions} }
|
||||
'') cfg.secrets);
|
||||
in
|
||||
{
|
||||
options.nix-bitcoin.setup-secrets = mkEnableOption "Set permissions for secrets generated by 'generate-secrets.sh'";
|
||||
options.nix-bitcoin = {
|
||||
secrets = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule (
|
||||
{ config, ... }: {
|
||||
options = {
|
||||
user = mkOption {
|
||||
type = str;
|
||||
default = "root";
|
||||
};
|
||||
group = mkOption {
|
||||
type = str;
|
||||
default = config.user;
|
||||
};
|
||||
permissions = mkOption {
|
||||
type = str;
|
||||
default = "0440";
|
||||
};
|
||||
};
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
config = mkIf config.nix-bitcoin.setup-secrets {
|
||||
setup-secrets = mkEnableOption "Set permissions for secrets generated by 'generate-secrets.sh'";
|
||||
};
|
||||
|
||||
config = mkIf cfg.setup-secrets {
|
||||
systemd.targets.nix-bitcoin-secrets = {
|
||||
requires = [ "setup-secrets.service" ];
|
||||
after = [ "setup-secrets.service" ];
|
||||
|
|
@ -23,7 +46,7 @@ in
|
|||
# - Create missing secrets that are composed of attrs from secrets.nix
|
||||
# - Set owner and permissions for all used secrets
|
||||
# - Make all other secrets accessible to root only
|
||||
# For all steps make sure that no secrets are copied to the nix-store.
|
||||
# For all steps make sure that no secrets are copied to the nix store.
|
||||
#
|
||||
systemd.services.setup-secrets = {
|
||||
serviceConfig = {
|
||||
|
|
@ -36,39 +59,15 @@ in
|
|||
user="$2"
|
||||
group="$3"
|
||||
permissions="$4"
|
||||
srcFile="$5"
|
||||
if [[ ! -e $file ]]; then
|
||||
if [[ $srcFile ]]; then
|
||||
if [[ ! -e $srcFile ]]; then
|
||||
echo "Error: Secret source file '$srcFile' is missing"
|
||||
exit 1
|
||||
fi
|
||||
mv "$srcFile" "$file"
|
||||
else
|
||||
createFile "$file"
|
||||
fi
|
||||
echo "Error: Secret file '$file' is missing"
|
||||
exit 1
|
||||
fi
|
||||
chown "$user:$group" "$file"
|
||||
chmod "$permissions" "$file"
|
||||
processedFiles+=("$file")
|
||||
}
|
||||
|
||||
createFile() {
|
||||
file="$1"
|
||||
# 'nix eval' requires filesystem or daemon access to a store even if nothing is built.
|
||||
# Use a private store so that 'nix eval' always succeeds regardless of the
|
||||
# execution environment, like a container.
|
||||
|
||||
# This tmp dir is automatically removed by systemd via PrivateTmp
|
||||
[[ $store ]] || store="$(mktemp -d)"
|
||||
secretsFile="$(realpath secrets.nix)" \
|
||||
${pkgs.nix}/bin/nix eval --raw --store "$store" "(
|
||||
(import ${./make-secrets.nix} {
|
||||
secretsFile = builtins.getEnv \"secretsFile\";
|
||||
}).allSecrets.$file.text
|
||||
)" > "$file"
|
||||
}
|
||||
|
||||
dir="${secretsDir}"
|
||||
if [[ ! -e $dir ]]; then
|
||||
echo "Error: Secrets dir '$dir' is missing"
|
||||
Loading…
Add table
Add a link
Reference in a new issue