mirror of
https://github.com/nmasur/dotfiles
synced 2025-07-05 15:00:14 +00:00
new secrets management system
This commit is contained in:
97
modules/services/secrets.nix
Normal file
97
modules/services/secrets.nix
Normal file
@ -0,0 +1,97 @@
|
||||
# Secrets management method taken from here:
|
||||
# https://xeiaso.net/blog/nixos-encrypted-secrets-2021-01-20
|
||||
|
||||
# In my case, I pre-encrypt my secrets and commit them to git.
|
||||
|
||||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
options = {
|
||||
|
||||
identityFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Path to existing identity file.";
|
||||
default = "/etc/ssh/ssh_host_ed25519_key";
|
||||
};
|
||||
|
||||
# secretsDirectory = lib.mkOption {
|
||||
# type = lib.types.str;
|
||||
# description = "Default path to place secrets.";
|
||||
# default = "/var/lib/private";
|
||||
# };
|
||||
|
||||
secrets = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule {
|
||||
options = {
|
||||
source = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = "Path to encrypted secret.";
|
||||
};
|
||||
dest = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Resulting path for decrypted secret.";
|
||||
};
|
||||
owner = lib.mkOption {
|
||||
default = "root";
|
||||
type = lib.types.str;
|
||||
description = "User to own the secret.";
|
||||
};
|
||||
group = lib.mkOption {
|
||||
default = "root";
|
||||
type = lib.types.str;
|
||||
description = "Group to own the secret.";
|
||||
};
|
||||
permissions = lib.mkOption {
|
||||
default = "0400";
|
||||
type = lib.types.str;
|
||||
description = "Permissions expressed as octal.";
|
||||
};
|
||||
};
|
||||
});
|
||||
description = "Set of secrets to decrypt to disk.";
|
||||
default = { };
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
# Create a default directory to place secrets
|
||||
|
||||
# systemd.tmpfiles.rules = [ "d ${config.secretsDirectory} 0750 root wheel" ];
|
||||
|
||||
# Declare oneshot service to decrypt secret using SSH host key
|
||||
# - Requires that the secret is already encrypted for the host
|
||||
# - Encrypt secrets: nix run github:nmasur/dotfiles#encrypt-secret
|
||||
|
||||
systemd.services = lib.mapAttrs' (name: attrs: {
|
||||
name = "${name}-secret";
|
||||
value = {
|
||||
|
||||
description = "Decrypt secret for ${name}";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
${pkgs.age}/bin/age --decrypt \
|
||||
--identity ${config.identityFile} \
|
||||
--output ${attrs.dest} \
|
||||
${attrs.source}
|
||||
|
||||
chown '${attrs.owner}':'${attrs.group}' '${attrs.dest}'
|
||||
chmod '${attrs.permissions}' '${attrs.dest}'
|
||||
'';
|
||||
|
||||
};
|
||||
}) config.secrets;
|
||||
|
||||
# Example declaration
|
||||
# config.secrets.my-secret = {
|
||||
# source = ../../private/my-secret.age;
|
||||
# dest = "/var/lib/private/my-secret";
|
||||
# owner = "my-app";
|
||||
# group = "my-app";
|
||||
# permissions = "0440";
|
||||
# };
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -1,10 +1,6 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
let credentialsFile = "/var/lib/private/transmission.json";
|
||||
|
||||
in {
|
||||
|
||||
imports = [ ./wireguard.nix ];
|
||||
imports = [ ./wireguard.nix ./secrets.nix ];
|
||||
|
||||
options = {
|
||||
transmissionServer = lib.mkOption {
|
||||
@ -33,14 +29,14 @@ in {
|
||||
rpc-whitelist = "127.0.0.1,${vpnIp}";
|
||||
rpc-whitelist-enabled = true;
|
||||
};
|
||||
credentialsFile = credentialsFile;
|
||||
credentialsFile = config.secrets.transmission.dest;
|
||||
};
|
||||
|
||||
# Bind transmission to wireguard namespace
|
||||
systemd.services.transmission = {
|
||||
bindsTo = [ "netns@${namespace}.service" ];
|
||||
requires = [ "network-online.target" ];
|
||||
after = [ "wireguard-wg0.service" ];
|
||||
requires = [ "network-online.target" "transmission-secret.service" ];
|
||||
after = [ "wireguard-wg0.service" "transmission-secret.service" ];
|
||||
unitConfig.JoinsNamespaceOf = "netns@${namespace}.service";
|
||||
serviceConfig.NetworkNamespacePath = "/var/run/netns/${namespace}";
|
||||
};
|
||||
@ -71,21 +67,11 @@ in {
|
||||
};
|
||||
|
||||
# Create credentials file for transmission
|
||||
systemd.services.transmission-creds = {
|
||||
requiredBy = [ "transmission.service" ];
|
||||
before = [ "transmission.service" ];
|
||||
serviceConfig = { Type = "oneshot"; };
|
||||
script = ''
|
||||
if [ ! -f "${credentialsFile}" ]; then
|
||||
mkdir --parents ${builtins.dirOf credentialsFile}
|
||||
${pkgs.age}/bin/age --decrypt \
|
||||
--identity ${config.identityFile} \
|
||||
--output ${credentialsFile} \
|
||||
${builtins.toString ../../private/transmission.json.age}
|
||||
chown transmission:transmission ${credentialsFile}
|
||||
chmod 0700 ${credentialsFile}
|
||||
fi
|
||||
'';
|
||||
secrets.transmission = {
|
||||
source = ../../private/transmission.json.age;
|
||||
dest = "/var/lib/private/transmission.json";
|
||||
owner = "transmission";
|
||||
group = "transmission";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -1,25 +1,25 @@
|
||||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
options = {
|
||||
identityFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Path to SSH key for age";
|
||||
default = "${config.homePath}/.ssh/id_ed25519";
|
||||
};
|
||||
# identityFile = lib.mkOption {
|
||||
# type = lib.types.str;
|
||||
# description = "Path to SSH key for age";
|
||||
# default = "${config.homePath}/.ssh/id_ed25519";
|
||||
# };
|
||||
};
|
||||
|
||||
config = {
|
||||
home-manager.users.${config.user}.home.packages = with pkgs; [ age ];
|
||||
|
||||
system.activationScripts.age.text = ''
|
||||
if [ ! -f "${config.identityFile}" ]; then
|
||||
$DRY_RUN_CMD echo -e \nEnter the seed phrase for your SSH key...\n
|
||||
$DRY_RUN_CMD echo -e \nThen press ^D when complete.\n\n
|
||||
$DRY_RUN_CMD ${pkgs.melt}/bin/melt restore ${config.identityFile}
|
||||
$DRY_RUN_CMD chown ${config.user}:wheel ${config.identityFile}*
|
||||
$DRY_RUN_CMD echo -e \n\nContinuing activation.\n\n
|
||||
fi
|
||||
'';
|
||||
# system.activationScripts.age.text = ''
|
||||
# if [ ! -f "${config.identityFile}" ]; then
|
||||
# $DRY_RUN_CMD echo -e \nEnter the seed phrase for your SSH key...\n
|
||||
# $DRY_RUN_CMD echo -e \nThen press ^D when complete.\n\n
|
||||
# $DRY_RUN_CMD ${pkgs.melt}/bin/melt restore ${config.identityFile}
|
||||
# $DRY_RUN_CMD chown ${config.user}:wheel ${config.identityFile}*
|
||||
# $DRY_RUN_CMD echo -e \n\nContinuing activation.\n\n
|
||||
# fi
|
||||
# '';
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user