]> git.immae.eu Git - perso/Immae/Config/Nix.git/commitdiff
Refactor secrets handling
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Thu, 7 Oct 2021 13:17:30 +0000 (15:17 +0200)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Tue, 12 Oct 2021 22:00:55 +0000 (00:00 +0200)
23 files changed:
.envrc
.gitconfig
Makefile
flakes/backports/flake.lock
flakes/backports/flake.nix
modules/private/buildbot/default.nix
modules/private/databases/default.nix
modules/private/environment.nix
modules/private/system.nix
modules/private/system/backup-2.nix
modules/private/system/dilion.nix
modules/private/system/eldiron.nix
modules/private/system/monitoring-1.nix
modules/private/system/quatresaisons.nix
modules/secrets.nix
nixops/.sops.yaml [new file with mode: 0644]
nixops/Makefile
nixops/default.nix
nixops/public_keys/Immae.pub [new file with mode: 0644]
nixops/scripts/setup
nixops/scripts/with_env
nixops/secrets
shell.nix

diff --git a/.envrc b/.envrc
index b4859fdbf3bb129203bbec006bc039fe311b1346..438d807e29908d3c4855a7978433a504c952f38e 100644 (file)
--- a/.envrc
+++ b/.envrc
@@ -1,5 +1,4 @@
 # vim: filetype=bash
-export PASSWORD_STORE_DIR=$(expand_path nixops/secrets)
 export NIX_PATH=nixpkgs=$(cat $(expand_path nix/sources.json) | jq -r '."nixpkgs-nixops".url')
 NIX_PATH=$NIX_PATH:nixpkgs-nix=$(cat $(expand_path nix/sources.json) | jq -r '."nixpkgs-nix".url')
 
index e503780e26666adcef0e04f841438e5c2b5e8526..7aa88705c591bb396d20e6f20c7fa21da0038ca4 100644 (file)
@@ -1,3 +1,9 @@
 ; git config --local include.path '../.gitconfig'
 [push]
   recurseSubmodules = on-demand
+; Find a way to include this file automatically?
+; git -C nixops/secrets config --local diff.gpgdiffer.textconv "gpg --quiet -d"
+[diff "gpgdiffer"]
+       textconv = "gpg --quiet -d"
+[diff "sopsdiffer"]
+       textconv = "sops -d"
index e5b9284a5d987abc0ee3ace49b14b36b543a297a..50fa09f444082d2d542e8663dfbc68839d07be80 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-subrecipes = setup nix-info edit_env
+subrecipes = setup nix-info edit_env edit_vars
 subrecipes += ssh-eldiron ssh-backup-2 ssh-monitoring-1 ssh-4c
 subrecipes += debug build dry-run upload deploy next-boot deploy-reboot
 subrecipes += list-generations delete-generations cleanup
index 0a2de64f805f34fdc7b81ceb3cad0ce6e8fefe70..5f9289efd7cd57444f52d27ee30445d2d6922503 100644 (file)
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1629925853,
-        "narHash": "sha256-gK2Q0o3Ov5/xT7XhCPbtfoFQ0Ty1Mu2aeWcNX6+XzjQ=",
+        "lastModified": 1634032472,
+        "narHash": "sha256-IoSg358w6nPpTYLWhvN3UgnU6r322dDPOLFXHyqyIkM=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "9e98c9db932a19bbd8fd4d3f879cd94f66270a43",
+        "rev": "3abf4b55b7c991909fde3115827d398dd7c5a299",
         "type": "github"
       },
       "original": {
index 89a9f400a450eec4bd7df3bb981add52ee6e799f..fe65d2ab0a03ad6f5cca6717730239c69a0e4e45 100644 (file)
@@ -21,7 +21,9 @@
         mpd-small = pkgs.mpd-small;
         pg_activity = pkgs.pg_activity;
         signald = pkgs.signald;
+        ssh-to-age = pkgs.ssh-to-age;
         stgit = pkgs.stgit;
+        sops = pkgs.sops;
         telegram-cli = pkgs.telegram-cli;
         woob = pkgs.python3Packages.woob;
         zrepl = pkgs.zrepl;
@@ -39,7 +41,9 @@
         mpd-small = flake-utils.lib.mkApp { drv = packages.mpd-small; name = "mpd"; };
         pg_activity = flake-utils.lib.mkApp { drv = packages.pg_activity; name = "pg_activity"; };
         signald = flake-utils.lib.mkApp { drv = packages.signald; name = "signald"; };
+        ssh-to-age = flake-utils.lib.mkApp { drv = packages.ssh-to-age; name = "ssh-to-age"; };
         stgit = flake-utils.lib.mkApp { drv = packages.stgit; name = "stgit"; };
+        sops = flake-utils.lib.mkApp { drv = packages.sops; name = "sops"; };
         telegram-cli = flake-utils.lib.mkApp { drv = packages.telegram-cli; name = "telegram-cli"; };
         woob = flake-utils.lib.mkApp { drv = packages.woob; name = "woob"; };
         zrepl = flake-utils.lib.mkApp { drv = packages.zrepl; name = "zrepl"; };
@@ -67,7 +71,9 @@
       mpd = final: prev: { mpd = self.packages."${final.system}".mpd; };
       pg_activity = final: prev: { pg_activity = self.packages."${final.system}".pg_activity; };
       signald = final: prev: { signald = self.packages."${final.system}".signald; };
+      ssh-to-age = final: prev: { ssh-to-age = self.packages."${final.system}".ssh-to-age; };
       stgit = final: prev: { stgit = self.packages."${final.system}".stgit; };
+      sops = final: prev: { sops = self.packages."${final.system}".sops; };
       telegram-cli = final: prev: { telegram-cli = self.packages."${final.system}".telegram-cli; };
       woob = final: prev: { woob = self.packages."${final.system}".woob; };
       zrepl = final: prev: { zrepl = self.packages."${final.system}".zrepl; };
@@ -84,7 +90,9 @@
       // overlays.mpd final prev
       // overlays.pg_activity final prev
       // overlays.signald final prev
+      // overlays.ssh-to-age final prev
       // overlays.stgit final prev
+      // overlays.sops final prev
       // overlays.telegram-cli final prev
       // overlays.woob final prev
       // overlays.zrepl final prev
index ac34845bcbda084dc53ba6927dad8a010f7800b6..ea0bef682c5a65ac50fbf9053a04115fd744c8ee 100644 (file)
@@ -138,7 +138,7 @@ in
         permissions = "0600";
         user = "buildbot";
         group = "buildbot";
-        text = builtins.readFile "${config.myEnv.privateFiles}/buildbot_ssh_key";
+        text = config.myEnv.buildbot.ssh_key.private;
         dest = "buildbot/ssh_key";
       }
     ];
index 6cd6feb5b25dae3dfb6107e2b1df277422d21097..1241658a18574846a057ca06b68d444a42db25f3 100644 (file)
@@ -25,7 +25,7 @@ in
     };
 
     openldap = {
-      accessFile = "${config.myEnv.privateFiles}/ldap.conf";
+      accessFile = ../../../nixops/secrets/ldap.conf;
       baseDn = config.myEnv.ldap.base;
       rootDn = config.myEnv.ldap.root_dn;
       rootPw = config.myEnv.ldap.root_pw;
index f0af57203145b472cf0929cace8205740045e842..65d9f0a5ab0975737185da7ba96470a9d7080582 100644 (file)
@@ -805,6 +805,15 @@ in
       description = "Buildbot configuration";
       type = submodule {
         options = {
+          ssh_key = mkOption {
+            description = "SSH key information";
+            type = submodule {
+              options = {
+                public = mkOption { type = str; description = "Public part of the key"; };
+                private = mkOption { type = lines; description = "Private part of the key"; };
+              };
+            };
+          };
           workerPassword = mkOption { description = "Buildbot worker password"; type = str; };
           user = mkOption {
             description = "Buildbot user";
@@ -961,6 +970,15 @@ in
             type = submodule {
               options = {
                 ldap = mkLdapOptions "Gitolite" {};
+                ssh_key = mkOption {
+                  description = "SSH key information";
+                  type = submodule {
+                    options = {
+                      public = mkOption { type = str; description = "Public part of the key"; };
+                      private = mkOption { type = lines; description = "Private part of the key"; };
+                    };
+                  };
+                };
               };
             };
           };
@@ -1461,13 +1479,6 @@ in
         };
       };
     };
-
-    privateFiles = mkOption {
-      type = path;
-      description = ''
-        Path to secret files to make available during build
-        '';
-    };
   };
   options.hostEnv = mkOption {
     readOnly = true;
index 0e72d9962fec977563a3607002aa44910cc42f89..c7e277c4bb7313efdd72e57bc2b57a2c234ed8b2 100644 (file)
@@ -4,7 +4,12 @@
     networking.extraHosts = builtins.concatStringsSep "\n"
       (lib.mapAttrsToList (n: v: "${v.config.hostEnv.ips.main.ip4} ${n}") nodes);
 
-    users.extraUsers.root.openssh.authorizedKeys.keyFiles = [ "${config.myEnv.privateFiles}/id_ed25519.pub" ];
+    users.extraUsers.root.openssh.authorizedKeys.keys = [ config.myEnv.sshd.rootKeys.nix_repository ];
+    secrets.deleteSecretsVars = true;
+    secrets.gpgKeys = [
+      ../../nixops/public_keys/Immae.pub
+    ];
+
     services.openssh.enable = true;
 
     services.duplyBackup.profiles.system = {
index d1064c7a5dec513f51f10535ea693307327e530b..1f226c0bdff723c766a5bc1d732c1c12ded00ee7 100644 (file)
@@ -1,4 +1,3 @@
-{ privateFiles }:
 { config, pkgs, resources, name, ... }:
 {
   deployment = {
@@ -6,8 +5,10 @@
     targetHost = config.hostEnv.ips.main.ip4;
     substituteOnDestination = true;
   };
+  # ssh-keyscan backup-2 | nix-shell -p ssh-to-age --run ssh-to-age
+  secrets.ageKeys = [ "age1kk3nr27qu42j28mcfdag5lhq0zu2pky7gfanvne8l4z2ctevjpgskmw0sr" ];
   boot.kernelPackages = pkgs.linuxPackages_latest;
-  myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
+  myEnv = import ../../../nixops/secrets/environment.nix;
 
   imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ] ++ builtins.attrValues (import ../..);
 
index a59d60797dc79b7f173e1a7a6573105a021f34cc..b9be8b073430b7e7019526b099d5bb3fcf5684f9 100644 (file)
@@ -1,4 +1,3 @@
-{ privateFiles }:
 { config, pkgs, name, lib, ... }:
 {
   deployment = {
@@ -6,6 +5,8 @@
     targetHost = config.hostEnv.ips.main.ip4;
     substituteOnDestination = true;
   };
+  # ssh-keyscan dilion | nix-shell -p ssh-to-age --run ssh-to-age
+  secrets.ageKeys = [ "age1x49n6qa0arkdpq8530s7umgm0gqkq90exv4jep97q30rfnzknpaqate06a" ];
   nixpkgs.system = lib.mkOverride 900 "x86_64-linux";
   boot = {
     loader = {
@@ -31,7 +32,7 @@
   powerManagement.cpuFreqGovernor = "powersave";
   hardware.enableRedistributableFirmware = true;
 
-  myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
+  myEnv = import ../../../nixops/secrets/environment.nix;
 
   swapDevices = [ { label = "swap"; } ];
   fileSystems = {
     isSystemUser = true;
     group = "libvirtd";
     packages = [ pkgs.netcat-openbsd ];
-    openssh.authorizedKeys.keyFiles = [
-      "${privateFiles}/buildbot_ssh_key.pub"
+    openssh.authorizedKeys.keys = [
+      config.myEnv.buildbot.ssh_key.public
+      config.myEnv.sshd.rootKeys.ismael_flony
     ];
-    openssh.authorizedKeys.keys = [ config.myEnv.sshd.rootKeys.ismael_flony ];
   };
 
   users.users.backup = {
index 4fb18a0f1e0334b9818e47243534e24b92437261..6c570c8b2dcda93a797f14909d73c00d3b25215c 100644 (file)
@@ -1,4 +1,3 @@
-{ privateFiles }:
 { config, pkgs, lib, ... }:
 {
   deployment = {
@@ -6,6 +5,8 @@
     targetHost = config.hostEnv.ips.main.ip4;
     substituteOnDestination = true;
   };
+  # ssh-keyscan eldiron | nix-shell -p ssh-to-age --run ssh-to-age
+  secrets.ageKeys = [ "age1dxr5lhvtnjssfaqpnf6qx80h8gfwkxg3tdf35m6n9wljmk7wadfs3kmahj" ];
   boot = {
     kernelModules = [ "kvm-intel" ];
     blacklistedKernelModules = [ "nvidiafb" ];
@@ -28,7 +29,7 @@
   '';
   nix.maxJobs = 8;
   powerManagement.cpuFreqGovernor = "powersave";
-  myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
+  myEnv = import ../../../nixops/secrets/environment.nix;
 
   fileSystems = {
     # pools:
index 2198d09fc3f480b7045284d3f2019ff1c3ff4a91..e335080b88d66fda0163e86583215114b5f3aa5c 100644 (file)
@@ -1,4 +1,3 @@
-{ privateFiles }:
 { config, pkgs, resources, ... }:
 {
   deployment = {
@@ -6,8 +5,10 @@
     targetHost = config.hostEnv.ips.main.ip4;
     substituteOnDestination = true;
   };
+  # ssh-keyscan monitoring-1 | nix-shell -p ssh-to-age --run ssh-to-age
+  secrets.ageKeys = [ "age1dn4lzhgxusqrpjjnzm7w8ml39ptf326htuzmpqdqs2gg3wq7cqzqxuvx8k" ];
   boot.kernelPackages = pkgs.linuxPackages_latest;
-  myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
+  myEnv = import ../../../nixops/secrets/environment.nix;
 
   imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ] ++ builtins.attrValues (import ../..);
 
index 03446e70c02b295d6b767ea762ed42a56915607f..01486501760704c6a6ef073a44969bbf228b4f86 100644 (file)
@@ -1,4 +1,3 @@
-{ privateFiles }:
 { config, pkgs, lib, ... }:
 let
   serverSpecificConfig = config.myEnv.serverSpecific.quatresaisons;
@@ -164,6 +163,8 @@ in
     targetHost = config.hostEnv.ips.main.ip4;
     substituteOnDestination = true;
   };
+  # ssh-keyscan quatresaison | nix-shell -p ssh-to-age --run ssh-to-age
+  secrets.ageKeys = [ "age1yz8u6xvh2fltvyp96ep8crce3qx4tuceyhun6pwddfe0uvcrkarscxl7e7" ];
 
   programs.ssh.package = pkgs.openssh.overrideAttrs(old: {
     PATH_PASSWD_PROG = "/run/wrappers/bin/passwd";
@@ -173,7 +174,7 @@ in
   imports = builtins.attrValues (import ../..) ++
     [ ./quatresaisons/nextcloud.nix ./quatresaisons/databases.nix ];
 
-  myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
+  myEnv = import ../../../nixops/secrets/environment.nix;
 
   fileSystems = {
     "/"     = { device = "/dev/disk/by-uuid/865931b4-c5cc-439f-8e42-8072c7a30634"; fsType = "ext4"; };
index ecc1ebc56a976023911fb1ac8b88968b6e9e85df..86d276a27e1ebb6947963da3b95343b63a4b4c59 100644 (file)
@@ -6,11 +6,36 @@
       default = [];
       description = "Keys to upload to server";
     };
+    gpgKeys = lib.mkOption {
+      type = lib.types.listOf lib.types.path;
+      default = [];
+      description = "GPG public keys files to encrypt to";
+    };
+    ageKeys = lib.mkOption {
+      type = lib.types.listOf lib.types.str;
+      default = [];
+      description = "AGE keys to encrypt to";
+    };
+    decryptKey = lib.mkOption {
+      type = lib.types.str;
+      default = "/etc/ssh/ssh_host_ed25519_key";
+      description = "ed25519 key used to decrypt with AGE";
+    };
     location = lib.mkOption {
       type = lib.types.path;
       default = "/var/secrets";
       description = "Location where to put the keys";
     };
+    secretsVars = lib.mkOption {
+      type = lib.types.path;
+      default = "/run/keys/vars.yml";
+      description = "Location where the secrets variables are defined, to be used to fill the templates in secrets";
+    };
+    deleteSecretsVars = lib.mkOption {
+      type = lib.types.bool;
+      default = false;
+      description = "Delete secrets file after deployment";
+    };
     # Read-only variables
     fullPaths = lib.mkOption {
       type = lib.types.attrsOf lib.types.path;
         ${v.user or "root"} ${v.group or "root"} ${v.permissions or "0600"} ${fpath v}
         EOF
         '';
-    secrets = pkgs.runCommand "secrets.tar" {} ''
+    secrets = pkgs.runCommand "secrets.tar.enc" {
+      buildInputs = [ pkgs.gnupg pkgs.sops ];
+      } ''
       touch mods
       tar --format=ustar --mtime='1970-01-01' -P --transform="s@${empty}@secrets@" -cf $out ${empty}/done
       ${builtins.concatStringsSep "\n" (map dumpKey keys)}
       cat mods | while read u g p k; do
       tar --format=ustar --mtime='1970-01-01' --owner="$u" --group="$g" --mode="$p" --append -f $out "$k"
       done
+      export HOME=$(pwd)
+      fingerprints=
+      for key in ${builtins.concatStringsSep " " config.secrets.gpgKeys}; do
+        gpg --import $key 2>/dev/null
+        fingerprints=$fingerprints,$(cat $key | gpg --with-colons --import-options show-only --import 2>/dev/null | grep ^fpr | cut -d: -f10 | head -n1)
+      done
+
+      sops --age ${builtins.concatStringsSep "," config.secrets.ageKeys} --pgp ''${fingerprints#,} --input-type binary -i -e $out 2>/dev/null
       '';
   in lib.mkIf (builtins.length keys > 0) {
     system.activationScripts.secrets = {
       deps = [ "users" "wrappers" ];
       text = ''
         install -m0750 -o root -g keys -d ${location}
-        if [ -f /run/keys/secrets.tar ]; then
-          if [ ! -f ${location}/currentSecrets ] || ! sha512sum -c --status "${location}/currentSecrets"; then
-            echo "rebuilding secrets"
-            TMP=$(${pkgs.coreutils}/bin/mktemp -d)
-            if [ -n "$TMP" ]; then
-              install -m0750 -o root -g keys -d $TMP
-              ${pkgs.gnutar}/bin/tar --strip-components 1 -C $TMP -xf /run/keys/secrets.tar
-              if [ -f /run/keys/vars.yml ]; then
-                find $TMP -name "*.gucci.tpl" -exec \
-                  /bin/sh -c 'f="{}"; ${pkgs.gucci}/bin/gucci -f /run/keys/vars.yml "$f" > "''${f%.gucci.tpl}"; touch --reference "$f" ''${f%.gucci.tpl} ; chmod --reference="$f" ''${f%.gucci.tpl} ; chown --reference="$f" ''${f%.gucci.tpl}' \;
-                sha512sum /run/keys/secrets.tar /run/keys/vars.yml > $TMP/currentSecrets
-              else
-                sha512sum /run/keys/secrets.tar > $TMP/currentSecrets
-              fi
-              find $TMP -type d -exec chown root:keys {} \; -exec chmod o-rx {} \;
-              ${pkgs.rsync}/bin/rsync --exclude="*.gucci.tpl" -O -c -av --delete $TMP/ ${location}
-              rm -rf $TMP
-            fi
+        TMP=$(${pkgs.coreutils}/bin/mktemp -d)
+        TMPWORK=$(${pkgs.coreutils}/bin/mktemp -d)
+        chmod go-rwx $TMPWORK
+        if [ -n "$TMP" -a -n "$TMPWORK" ]; then
+          install -m0750 -o root -g keys -d $TMP
+          ${pkgs.ssh-to-age}/bin/ssh-to-age -private-key -i ${config.secrets.decryptKey} -o $TMPWORK/keys.txt
+          SOPS_AGE_KEY_FILE=$TMPWORK/keys.txt ${pkgs.sops}/bin/sops -d ${secrets} | ${pkgs.gnutar}/bin/tar --strip-components 1 -C $TMP -x
+          if [ -f ${config.secrets.secretsVars} ]; then
+            SOPS_AGE_KEY_FILE=$TMPWORK/keys.txt ${pkgs.sops}/bin/sops -d ${config.secrets.secretsVars} > $TMPWORK/vars.yml
           fi
+          if [ -f $TMPWORK/vars.yml ]; then
+            find $TMP -name "*.gucci.tpl" -exec \
+              /bin/sh -c 'f="{}"; ${pkgs.gucci}/bin/gucci -f '$TMPWORK'/vars.yml "$f" > "''${f%.gucci.tpl}"; touch --reference "$f" ''${f%.gucci.tpl} ; chmod --reference="$f" ''${f%.gucci.tpl} ; chown --reference="$f" ''${f%.gucci.tpl}' \;
+          fi
+          find $TMP -type d -exec chown root:keys {} \; -exec chmod o-rx {} \;
+          ${pkgs.rsync}/bin/rsync --exclude="*.gucci.tpl" -O -c -av --delete $TMP/ ${location}
+          rm -rf $TMP $TMPWORK ${lib.optionalString config.secrets.deleteSecretsVars config.secrets.secretsVars}
         fi
         '';
     };
 
-    system.extraDependencies = [ secrets ];
     deployment.secrets."secret_vars.yml" = {
-      source = builtins.toString <privateFiles/vars.yml>;
-      destination = "/run/keys/vars.yml";
+      source = builtins.toString ../nixops/secrets/vars.yml;
+      destination = config.secrets.secretsVars;
       owner.user = "root";
       owner.group = "root";
       permissions = "0400";
      };
-    deployment.secrets."secrets.tar" = {
-      source = "${secrets}";
-      destination = "/run/keys/secrets.tar";
-      owner.user = "root";
-      owner.group = "root";
-      permissions = "0400";
-    };
   };
 }
diff --git a/nixops/.sops.yaml b/nixops/.sops.yaml
new file mode 100644 (file)
index 0000000..04826a2
--- /dev/null
@@ -0,0 +1,19 @@
+keys:
+  - &Immae F82806FDA1BF5B9A1B3014E7C9FCED6CA6B79454
+  # obtained with: ssh-keyscan eldiron | nix-shell -p ssh-to-age --run ssh-to-age
+  - &eldiron age1dxr5lhvtnjssfaqpnf6qx80h8gfwkxg3tdf35m6n9wljmk7wadfs3kmahj
+  - &monitoring-1 age1dn4lzhgxusqrpjjnzm7w8ml39ptf326htuzmpqdqs2gg3wq7cqzqxuvx8k
+  - &backup-2 age1kk3nr27qu42j28mcfdag5lhq0zu2pky7gfanvne8l4z2ctevjpgskmw0sr
+  - &dilion age1x49n6qa0arkdpq8530s7umgm0gqkq90exv4jep97q30rfnzknpaqate06a
+  - &quatresaisons age1yz8u6xvh2fltvyp96ep8crce3qx4tuceyhun6pwddfe0uvcrkarscxl7e7
+creation_rules:
+  - path_regex: vars.yml
+    key_groups:
+      - pgp:
+        - *Immae
+        age:
+        - *eldiron
+        - *monitoring-1
+        - *backup-2
+        - *dilion
+        - *quatresaisons
index f3d06efdbb0d33036e41975eb4707bc13d4a586c..fb9da4cb2f6fa30cf4d99e45ad20fab8415438fa 100644 (file)
@@ -26,7 +26,14 @@ endif
 SSH_ARGS ?=
 
 edit_env:
-       pass edit Nixops/files/environment.nix || true
+       $(EDITOR) secrets/environment.nix || true
+       git -C secrets add environment.nix || true
+       git -C secrets commit -m "Edit environment.nix" environment.nix || true
+
+edit_vars:
+       sops secrets/vars.yml || true
+       git -C secrets add vars.yml || true
+       git -C secrets commit -m "Edit password for vars.yml using sops." vars.yml || true
 
 ssh-eldiron:
        ./scripts/with_env bash -c 'ssh -i $$SSH_IDENTITY_FILE root@eldiron $(SSH_ARGS)'
@@ -77,8 +84,8 @@ list-generations:
 .PHONY: list-generations
 
 delete-generations:
-       echo "make sure you ran a complete build before cleaning up!"
-       false
+       @echo "making sure that a complete build is done before cleaning up"
+       $(MAKE) build MORPH_ARGS=--keep-result
        nix-env -p $(PROFILE) --delete-generations $(GEN)
        $(MAKE) ssh-eldiron SSH_ARGS="nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN)"
        $(MAKE) ssh-dilion SSH_ARGS="nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN)"
index f048c80c7c445952e39177c72f85b46c2ba42d1e..1241443af63f31c137b8cb993d801afb3bebf18f 100644 (file)
@@ -1,11 +1,8 @@
-let
-  privateFiles = <privateFiles>;
-in
 {
-  dilion = import ../modules/private/system/dilion.nix { inherit privateFiles; };
-  eldiron = import ../modules/private/system/eldiron.nix { inherit privateFiles; };
-  backup-2 = import ../modules/private/system/backup-2.nix { inherit privateFiles; };
-  monitoring-1 = import ../modules/private/system/monitoring-1.nix { inherit privateFiles; };
+  dilion = import ../modules/private/system/dilion.nix;
+  eldiron = import ../modules/private/system/eldiron.nix;
+  backup-2 = import ../modules/private/system/backup-2.nix;
+  monitoring-1 = import ../modules/private/system/monitoring-1.nix;
 
-  quatresaisons = import ../modules/private/system/quatresaisons.nix { inherit privateFiles; };
+  quatresaisons = import ../modules/private/system/quatresaisons.nix;
 }
diff --git a/nixops/public_keys/Immae.pub b/nixops/public_keys/Immae.pub
new file mode 100644 (file)
index 0000000..dd42b04
--- /dev/null
@@ -0,0 +1,322 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+DRuKdymWEii1jA9KlmheLTFr
+=r9L+
+-----END PGP PUBLIC KEY BLOCK-----
index 9bdb8df2c684339f8240698f3af36c4500b79caf..db0f353b679429f10ccf14b60c4420489b662588 100755 (executable)
@@ -44,23 +44,21 @@ if [ "$(git config --get include.path)" != "../.gitconfig" ]; then
   fi
 fi
 
-gpg_keys=$(pass ls Nixops/GPGKeys | sed -e "1d" | cut -d" " -f2)
-for key in $gpg_keys; do
-  content=$(pass show Nixops/GPGKeys/$key)
-  fpr=$(echo "$content" | gpg --import-options show-only --import --with-colons | grep -e "^pub" | cut -d':' -f5)
+for key in public_keys/*; do
+  fpr=$(cat "$key" | gpg --import-options show-only --import --with-colons | grep -e "^pub" | cut -d':' -f5)
   gpg --list-key "$fpr" >/dev/null 2>/dev/null && imported=yes || imported=no
   # /usr/share/doc/gnupg/DETAILS field 2
-  (echo "$content" | gpg --import-options show-only --import --with-colons |
+  (cat "$key" | gpg --import-options show-only --import --with-colons |
       grep -E '^pub:' |
       cut -d':' -f2 |
       grep -q '[fu]') && signed=yes || signed=no
   if [ "$signed" = no -o "$imported" = no ] ; then
     echo "The key for $key needs to be imported and signed (a local signature is enough)"
-    echo "$content" | gpg --import-options show-only --import
+    cat "$key" | gpg --import-options show-only --import
     echo "Continue? [y/N]"
     read y
     if [ "$y" = "y" -o "$y" = "Y" ]; then
-      echo "$content" | gpg --import
+      cat "$key" | gpg --import
       gpg --expert --edit-key "$fpr" lsign quit
     else
       echo "Aborting"
index f8e5537b43423b3ac0362d79bb8b9226f502d3ac..c570ccf2afcd95cde5495679f18fce4f40911f1f 100755 (executable)
@@ -15,14 +15,8 @@ finish() {
 
 trap finish EXIT
 
-# pass cannot "just" list files in a directory without showing a tree :(
-files=$(pass ls Nixops/files | sed -e '1d' -e 's/^.* //')
+sops -d secrets/vars.yml | yq -r .ssl_keys.nix_repository > $TEMP/id_ed25519
 
-for file in $files; do
-  pass show "Nixops/files/$file" > $TEMP/$file
-done
-
-export NIX_PATH="privateFiles=$TEMP:$NIX_PATH"
 export SSH_IDENTITY_FILE="$TEMP/id_ed25519"
 
 "$@"
index 3b4bfa3cddc7f0621d1bec042a388c32e38245f4..a1e6498139cc51a3d68e5655480542e6ccd3a45f 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 3b4bfa3cddc7f0621d1bec042a388c32e38245f4
+Subproject commit a1e6498139cc51a3d68e5655480542e6ccd3a45f
index 3aa03a770a9eaf9d522975db9b76df0c62dabfca..2295f8cc10b8eca9bf4798562080a2256963c1e5 100644 (file)
--- a/shell.nix
+++ b/shell.nix
@@ -14,5 +14,5 @@ let
   });
 in
 pkgs.mkShell {
-  buildInputs = [ patchedNix pkgs.morph pkgs.niv pkgs.pass pkgs.curl pkgs.shellcheck pkgs.jq pkgs.gnumake ];
+  buildInputs = [ patchedNix pkgs.sops pkgs.morph pkgs.niv pkgs.curl pkgs.shellcheck pkgs.jq pkgs.gnumake pkgs.yq ];
 }