From a7f233e00ed5d5313091a361271b8301d08cb7ea Mon Sep 17 00:00:00 2001 From: madmin Date: Sun, 1 Sep 2024 15:18:55 +0200 Subject: [PATCH] feat(home/optional, sys/core): add sops, fix optinal/dev --- home/laozi/common/optional/dev/default.nix | 1 + home/laozi/common/optional/utilities/sops.nix | 40 +++++++++++ home/laozi/jeroboam.nix | 2 +- systems/common/core/sops.nix | 69 +++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 home/laozi/common/optional/utilities/sops.nix create mode 100644 systems/common/core/sops.nix diff --git a/home/laozi/common/optional/dev/default.nix b/home/laozi/common/optional/dev/default.nix index fe71d0c..12abf53 100644 --- a/home/laozi/common/optional/dev/default.nix +++ b/home/laozi/common/optional/dev/default.nix @@ -6,5 +6,6 @@ inherit (pkgs) # Here go packages without my configs #!Remember to comment without space after package + ; }; } diff --git a/home/laozi/common/optional/utilities/sops.nix b/home/laozi/common/optional/utilities/sops.nix new file mode 100644 index 0000000..b0b9247 --- /dev/null +++ b/home/laozi/common/optional/utilities/sops.nix @@ -0,0 +1,40 @@ +# home level sops. see hosts/common/optional/sops.nix for hosts level +# TODO should I split secrets.yaml into a home level and a hosts level or move to a single sops.nix entirely? + +{ inputs, config, ... }: +let + secretsDirectory = builtins.toString inputs.nix-secrets; + secretsFile = "${secretsDirectory}/secrets.yaml"; + homeDirectory = config.home.homeDirectory; +in +{ + imports = [ + inputs.sops-nix.homeManagerModules.sops + ]; + + sops = { + # This is the location of the host specific age-key for ta and will to have been extracted to this location via hosts/common/core/sops.nix on the host + age.keyFile = "${homeDirectory}/.config/sops/age/keys.txt"; + + defaultSopsFile = "${secretsFile}"; + validateSopsFiles = false; + + secrets = { + "ssh_keys/stanislav" = { + path = "${homeDirectory}/.ssh/id_stanislav"; + }; + "ssh_keys/vladislav" = { + path = "${homeDirectory}/.ssh/id_vladislav"; + }; + "ssh_keys/rostislav" = { + path = "${homeDirectory}/.ssh/id_rostislav"; + }; + "ssh_keys/borislav" = { + path = "${homeDirectory}/.ssh/id_borislav"; + }; + "ssh_keys/radoslav" = { + path = "${homeDirectory}/.ssh/id_radoslav"; + }; + }; + }; +} diff --git a/home/laozi/jeroboam.nix b/home/laozi/jeroboam.nix index e12fef0..4b74c66 100644 --- a/home/laozi/jeroboam.nix +++ b/home/laozi/jeroboam.nix @@ -1,7 +1,7 @@ { inputs, configVars, configLib, ... }: #map with prefix to refactor let - optionals = (configLib.mapPathsToPrefix { prefix = common/optional; list = [ /system /internet /comms /utilities /dev/foot.nix /office ];}); + optionals = (configLib.mapPathsToPrefix { prefix = common/optional; list = [ /system /internet /comms /utilities /dev /office ];}); in { imports = [ diff --git a/systems/common/core/sops.nix b/systems/common/core/sops.nix new file mode 100644 index 0000000..80ae4e1 --- /dev/null +++ b/systems/common/core/sops.nix @@ -0,0 +1,69 @@ +# hosts level sops. see home/[user]/common/optional/sops.nix for home/user level + +{ pkgs, inputs, config, configVars, ... }: +let + secretsDirectory = builtins.toString inputs.nix-secrets; + secretsFile = "${secretsDirectory}/secrets.yaml"; + + homeDirectory = "/home/${configVars.username}"; +in +{ + imports = [ + inputs.sops-nix.nixosModules.sops + ]; + + sops = { + defaultSopsFile = "${secretsFile}"; + validateSopsFiles = false; + + age = { + # automatically import host SSH keys as age keys + sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + }; + + # secrets will be output to /run/secrets + # e.g. /run/secrets/msmtp-password + # secrets required for user creation are handled in respective ./users/.nix files + # because they will be output to /run/secrets-for-users and only when the user is assigned to a host. + secrets = { + # For home-manager a separate age key is used to decrypt secrets and must be placed onto the host. This is because + # the user doesn't have read permission for the ssh service private key. However, we can bootstrap the age key from + # the secrets decrypted by the host key, which allows home-manager secrets to work without manually copying over + # the age key. + # These age keys are are unique for the user on each host and are generated on their own (i.e. they are not derived + # from an ssh key). + "user_age_keys/${configVars.username}_${config.networking.hostName}" = { + owner = config.users.users.${configVars.username}.name; + inherit (config.users.users.${configVars.username}) group; + # We need to ensure the entire directory structure is that of the user... + path = "${homeDirectory}/.config/sops/age/keys.txt"; + }; + + # extract username/password to /run/secrets-for-users/ so it can be used to create the user + "${configVars.username}/password".neededForUsers = true; + + #FIXME move to mstmp.nix and also have host and address being assigned to configVars as per fidgetingbits + msmtp-host = { }; + msmtp-address = { }; + msmtp-password = { }; + + # extract to default pam-u2f authfile location for passwordless sudo. see ../optional/yubikey + "yubico/u2f_keys" = { + path = "/home/${configVars.username}/.config/Yubico/u2f_keys"; + }; + }; + }; + # The containing folders are created as root and if this is the first ~/.config/ entry, + # the ownership is busted and home-manager can't target because it can't write into .config... + # FIXME: We might not need this depending on how https://github.com/Mic92/sops-nix/issues/381 is fixed + system.activationScripts.sopsSetAgeKeyOwnwership = + let + ageFolder = "${homeDirectory}/.config/sops/age"; + user = config.users.users.${configVars.username}.name; + group = config.users.users.${configVars.username}.group; + in + '' + mkdir -p ${ageFolder} || true + chown -R ${user}:${group} ${homeDirectory}/.config + ''; +}