From b930d66869ac2a137e09f321350a86f1190b880d Mon Sep 17 00:00:00 2001 From: Alexander Bantyev Date: Mon, 11 Jan 2021 20:51:09 +0300 Subject: [PATCH] MOAR SECRETS STUFF --- flake.lock | 16 ----- flake.nix | 2 - modules/applications/weechat.nix | 2 +- modules/applications/yt-utilities.nix | 2 +- modules/matrix-synapse.nix | 6 +- modules/secrets-envsubst.nix | 29 ++++---- modules/secrets.nix | 99 ++++++++++----------------- modules/workspace/gnome3.nix | 94 +++++++++++++++++++++++++ 8 files changed, 151 insertions(+), 99 deletions(-) diff --git a/flake.lock b/flake.lock index f178a7e..21792d9 100644 --- a/flake.lock +++ b/flake.lock @@ -302,7 +302,6 @@ "nixpkgs": "nixpkgs_4", "nixpkgs-old": "nixpkgs-old", "nixpkgs-wayland": "nixpkgs-wayland", - "secrets": "secrets", "simple-nixos-mailserver": "simple-nixos-mailserver", "simple-osd-daemons": "simple-osd-daemons", "weechat-notify-send": "weechat-notify-send", @@ -310,21 +309,6 @@ "yt-utilities": "yt-utilities" } }, - "secrets": { - "locked": { - "lastModified": 1610367002, - "narHash": "sha256-u2bwZhhTvXl9XK6EMVRyBiEjs7DDTCx1Nog1mQkB0yQ=", - "ref": "master", - "rev": "77a6f919690c8a0dd383fccdd61f2c7c99fc24cb", - "revCount": 1, - "type": "git", - "url": "ssh://git@github.com/balsoft/pass" - }, - "original": { - "type": "git", - "url": "ssh://git@github.com/balsoft/pass" - } - }, "simple-nixos-mailserver": { "flake": false, "locked": { diff --git a/flake.nix b/flake.nix index 26ea724..597a586 100644 --- a/flake.nix +++ b/flake.nix @@ -46,8 +46,6 @@ }; nixos-fhs-compat.url = github:balsoft/nixos-fhs-compat; simple-osd-daemons.url = github:balsoft/simple-osd-daemons; - - secrets.url = git+ssh://git@github.com/balsoft/pass; }; outputs = { nixpkgs, nix, self, ... }@inputs: { diff --git a/modules/applications/weechat.nix b/modules/applications/weechat.nix index 214c259..c07eab6 100644 --- a/modules/applications/weechat.nix +++ b/modules/applications/weechat.nix @@ -8,7 +8,7 @@ let in { secrets-envsubst.weechat = { owner = "balsoft:users"; - directory = "weechat"; + secrets = [ "slack_api_token" ]; template = '' [var] python.slack.auto_open_threads = "true" diff --git a/modules/applications/yt-utilities.nix b/modules/applications/yt-utilities.nix index 8179865..7379740 100644 --- a/modules/applications/yt-utilities.nix +++ b/modules/applications/yt-utilities.nix @@ -3,7 +3,7 @@ home.activation.yt-config = "$DRY_RUN_CMD ln -sf $VERBOSE_ARG ${config.secrets-envsubst.yt} $HOME/.yt.yaml"; }; secrets-envsubst.yt = { - directory = "yt"; + secrets = [ "user" "template" ]; owner = "balsoft:users"; template = builtins.toJSON { yt-token = "$user"; diff --git a/modules/matrix-synapse.nix b/modules/matrix-synapse.nix index 5dde951..c8fa98d 100644 --- a/modules/matrix-synapse.nix +++ b/modules/matrix-synapse.nix @@ -85,7 +85,7 @@ }; secrets-envsubst.mautrix-telegram = { - directory = "mautrix-telegram"; + secrets = [ "as_token" "hs_token" "api_id" "api_hash" ]; template = '' MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=$as_token MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=$hs_token @@ -96,6 +96,7 @@ secrets-envsubst.mautrix-telegram-registration = { directory = "mautrix-telegram"; + secrets = [ "as_token" "hs_token" ]; owner = "matrix-synapse"; template = builtins.toJSON { as_token = "$as_token"; @@ -118,7 +119,7 @@ }; secrets-envsubst.mautrix-whatsapp = { - directory = "mautrix-whatsapp"; + secrets = [ "as_token" "hs_token" ]; owner = "mautrix-whatsapp"; template = builtins.toJSON { appservice = { @@ -181,6 +182,7 @@ secrets-envsubst.mautrix-whatsapp-registration = { directory = "mautrix-whatsapp"; + secrets = [ "as_token" "hs_token" ]; owner = "matrix-synapse"; template = builtins.toJSON { as_token = "$as_token"; diff --git a/modules/secrets-envsubst.nix b/modules/secrets-envsubst.nix index de7f10d..a890cf6 100644 --- a/modules/secrets-envsubst.nix +++ b/modules/secrets-envsubst.nix @@ -4,7 +4,11 @@ with types; let envsubstSecrets = { name, ... }: { options = { - directory = mkOption { type = str; }; + directory = mkOption { + type = nullOr str; + default = name; + }; + secrets = mkOption { type = listOf str; }; template = mkOption { type = str; }; prefix = mkOption { type = nullOr str; @@ -38,34 +42,32 @@ let }; }; - individualSecrets = name: cfg: - map (x: builtins.elemAt (builtins.match "(.*).gpg" x) 0) (builtins.attrNames (lib.filterAttrs (n: v: v == "regular" || v == "symlink") - (builtins.readDir (inputs.secrets + "/${cfg.directory}")))); - exportSecrets = name: cfg: let prefix = lib.optionalString (!isNull cfg.prefix) "${cfg.prefix}_"; in map (secret: '' export ${prefix}${secret}="$(cat ${ config.secrets."${name}-envsubst-${secret}".decrypted - })"'') (individualSecrets name cfg); + })"'') cfg.secrets; envsubst = name: cfg: with cfg; { "${name}-envsubst" = rec { - wantedBy = [ "multi-user.target" ]; - - requires = [ "user@1000.service" "gpg-setup.service" ] - ++ map (secret: "${name}-envsubst-${secret}-secrets.service") (individualSecrets name cfg); + requires = [ "user@1000.service" ] + ++ map (secret: "${name}-envsubst-${secret}-secrets.service") + cfg.secrets; after = requires; + bindsTo = requires; preStart = "mkdir -p '${builtins.dirOf substituted}'"; script = '' ${builtins.concatStringsSep "\n" (exportSecrets name cfg)} - if cat '${builtins.toFile "template" template}' | ${cfg.envsubst} > '${substituted}.tmp'; then + if cat '${ + builtins.toFile "template" template + }' | ${cfg.envsubst} > '${substituted}.tmp'; then mv -f '${substituted}.tmp' '${substituted}' chown '${owner}' '${substituted}' chmod '${permissions}' '${substituted}' @@ -87,16 +89,17 @@ let genAttrs services (service: rec { requires = [ "${name}-envsubst" ]; after = requires; + bindsTo = requires; }); mkServices = name: cfg: [ (envsubst name cfg) (addDependencies name cfg) ]; mkIndividualSecrets = name: cfg: map (x: { "${name}-envsubst-${x}" = { - encrypted = inputs.secrets + "/${cfg.directory}/${x}.gpg"; + encrypted = "/home/balsoft/.password-store/${lib.optionalString (! isNull cfg.directory) "${cfg.directory}/"}${x}.gpg"; services = [ ]; }; - }) (individualSecrets name cfg); + }) cfg.secrets; in { options.secrets-envsubst = lib.mkOption { type = attrsOf (submodule envsubstSecrets); }; diff --git a/modules/secrets.nix b/modules/secrets.nix index ff23d5d..62a867c 100755 --- a/modules/secrets.nix +++ b/modules/secrets.nix @@ -6,7 +6,7 @@ let options = { encrypted = mkOption { type = path; - default = inputs.secrets + "/${name}.gpg"; + default = "/home/balsoft/.password-store/${name}.gpg"; }; decrypted = mkOption { type = path; @@ -48,22 +48,15 @@ let with cfg; { "${name}-secrets" = rec { - wantedBy = [ "multi-user.target" ]; - - requires = [ "user@1000.service" "gpg-setup.service" ]; + requires = [ "user@1000.service" ]; after = requires; preStart = '' - [[ -r '${encrypted}' ]] + stat '${encrypted}' mkdir -p '${builtins.dirOf decrypted}' ''; script = '' - ${optionalString (pkgs.gnupg.version == "2.2.24") - "/run/wrappers/bin/sudo -u ${user} ${pkgs.gnupg}/bin/gpg --card-status" - # 2.2.24 is broken and needs this hack for yubi to work - } - if cat '${encrypted}' | /run/wrappers/bin/sudo -u ${user} ${cfg.decrypt} > '${decrypted}.tmp'; then mv -f '${decrypted}.tmp' '${decrypted}' chown '${owner}' '${decrypted}' @@ -95,68 +88,46 @@ let genAttrs services (service: rec { requires = [ "${name}-secrets" ]; after = requires; + bindsTo = requires; }); - gpg-setup = rec { - - wantedBy = [ "multi-user.target" ]; - - requires = [ "user@1000.service" ]; - after = requires; - - path = [ pkgs.gnupg ]; - - script = "echo fetch | gpg --card-edit --no-tty --command-fd=0"; - - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = "yes"; - User = "balsoft"; - }; - }; - mkServices = name: cfg: [ (decrypt name cfg) (addDependencies name cfg) ]; in { options.secrets = lib.mkOption { type = attrsOf (submodule secret); }; - config.systemd.services = mkMerge ([{ inherit gpg-setup; }] - ++ concatLists (mapAttrsToList mkServices config.secrets)); + config.systemd.services = + mkMerge (concatLists (mapAttrsToList mkServices config.secrets)); + + config.environment.systemPackages = [ + (pkgs.writeShellScriptBin "activate-secrets" '' + set -euo pipefail + # Make sure card is available and unlocked + echo fetch | gpg --card-edit --no-tty --command-fd=0 + ${pkgs.gnupg}/bin/gpg --card-status + if [ -d "$HOME/.password-store" ]; then + cd "$HOME/.password-store"; ${pkgs.git}/bin/git pull + else + ${pkgs.git}/bin/git clone ssh://git@github.com/balsoft/pass "$HOME/.password-store" + fi + ln -sf ${ + pkgs.writeShellScript "push" "${pkgs.git}/bin/git push origin master" + } "$HOME/.password-store/.git/hooks/post-commit" + cat $HOME/.password-store/email/balsoft@balsoft.ru.gpg | ${pkgs.gnupg}/bin/gpg --decrypt > /dev/null + sudo systemctl restart '*-secrets.service' '*-envsubst.service' + '') + ]; + + config.security.sudo.extraRules = [{ + users = [ "balsoft" ]; + commands = [{ + command = + "/run/current-system/sw/bin/systemctl restart '*-secrets.service' '*-envsubst.service'"; + options = [ "NOPASSWD" ]; + }]; + }]; config.home-manager.users.balsoft = { - systemd.user.services.pass-sync = { - Install.WantedBy = - [ "sway-session.target" ]; # Start when the gpg agent is ready - - Service = { - ExecStartPre = toString (pkgs.writeShellScript "clone-pass-repo" '' - set -euo pipefail - - ''); - ExecStart = toString (pkgs.writeShellScript "pass-sync" '' - set -euo pipefail - cd $HOME/.password-store - while ${pkgs.inotifyTools}/bin/inotifywait "$HOME/.password-store/.git" -r -e modify -e close_write -e move -e create -e delete; do - sleep 0.5 - ${pkgs.git}/bin/git push - done - ''); - }; - }; wayland.windowManager.sway = { - config.startup = [{ - command = toString (pkgs.writeShellScript "activate-secrets" '' - set -euo pipefail - # Make sure card is available and unlocked - ${pkgs.gnupg}/bin/gpg --card-status - cat ${inputs.secrets}/email/balsoft@balsoft.ru.gpg | ${pkgs.gnupg}/bin/gpg --decrypt - systemctl restart '*-secrets.service' '*-envsubst.service' - if [ -d "$HOME/.password-store" ]; then - cd "$HOME/.password-store"; ${pkgs.git}/bin/git pull - else - ${pkgs.git}/bin/git clone ssh://git@github.com/balsoft/pass "$HOME/.password-store" - fi - ln -sf ${pkgs.writeShellScript "push" "${pkgs.git}/bin/git push origin master"} "$HOME/.password-store/.git/hooks/post-commit" - ''); - }]; + config.startup = [{ command = "activate-secrets"; }]; }; }; } diff --git a/modules/workspace/gnome3.nix b/modules/workspace/gnome3.nix index 9b8138d..052d929 100644 --- a/modules/workspace/gnome3.nix +++ b/modules/workspace/gnome3.nix @@ -12,6 +12,10 @@ services.geoclue2.enable = true; home-manager.users.balsoft = { xdg.userDirs.enable = true; + home.activation.gnome-keyring = '' + ln -sf ${config.secrets-envsubst.gnome-keyring} "$XDG_DATA_HOME/keyrings/Default_keyring.keyring" + echo "Default_keyring" > "$XDG_DATA_HOME/keyrings/default" + ''; dconf.settings = { "org/gnome/nautilus/icon-view" = { captions = [ "size" "date_modified" "none" ]; @@ -53,4 +57,94 @@ }; }; }; + secrets-envsubst.gnome-keyring = { + owner = "balsoft:users"; + secrets = [ "matrix_token" "matrix_password" "email" "nextcloud" ]; + template = '' + [keyring] + display-name=Default keyring + ctime=1609508068 + mtime=0 + lock-on-idle=false + lock-after=false + + [5] + item-type=0 + display-name=fractal-token + secret=$matrix_token + mtime=1610374847 + ctime=1610374847 + + [5:attribute0] + name=uid + type=string + value=@balsoft:balsoft.ru + + [3] + item-type=0 + display-name=Geary IMAP password + secret=$email + mtime=1610307006 + ctime=1609572471 + + [3:attribute0] + name=host + type=string + value=balsoft.ru + + [3:attribute1] + name=login + type=string + value=balsoft@balsoft.ru + + [3:attribute2] + name=proto + type=string + value=IMAP + + [3:attribute3] + name=xdg:schema + type=string + value=org.gnome.Geary + + [1] + item-type=0 + display-name=GOA owncloud credentials for identity account_1609508064_4 + secret={'password': <'$nextcloud'>} + mtime=1609508086 + ctime=1609508086 + + [1:attribute0] + name=goa-identity + type=string + value=owncloud:gen0:account_1609508064_4 + + [1:attribute1] + name=xdg:schema + type=string + value=org.gnome.OnlineAccounts + + [4] + item-type=0 + display-name=fractal + secret=$matrix_password + mtime=1610374846 + ctime=1610374846 + + [4:attribute0] + name=identity + type=string + value=https://vector.im/ + + [4:attribute1] + name=server + type=string + value=https://balsoft.ru/ + + [4:attribute2] + name=username + type=string + value=balsoft + ''; + }; }