aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2021-10-07 15:17:30 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2021-10-13 00:00:55 +0200
commit282c67a117b7d349b30a96972b050d630f906dec (patch)
tree6686bdc126d5c0bd548cd6286a41be5c8cfdc01f /modules
parent97f5a24bc8839328571b23eb5f910de206ddbe1f (diff)
downloadNix-282c67a117b7d349b30a96972b050d630f906dec.tar.gz
Nix-282c67a117b7d349b30a96972b050d630f906dec.tar.zst
Nix-282c67a117b7d349b30a96972b050d630f906dec.zip
Refactor secrets handling
Diffstat (limited to 'modules')
-rw-r--r--modules/private/buildbot/default.nix2
-rw-r--r--modules/private/databases/default.nix2
-rw-r--r--modules/private/environment.nix25
-rw-r--r--modules/private/system.nix7
-rw-r--r--modules/private/system/backup-2.nix5
-rw-r--r--modules/private/system/dilion.nix11
-rw-r--r--modules/private/system/eldiron.nix5
-rw-r--r--modules/private/system/monitoring-1.nix5
-rw-r--r--modules/private/system/quatresaisons.nix5
-rw-r--r--modules/secrets.nix83
10 files changed, 98 insertions, 52 deletions
diff --git a/modules/private/buildbot/default.nix b/modules/private/buildbot/default.nix
index ac34845..ea0bef6 100644
--- a/modules/private/buildbot/default.nix
+++ b/modules/private/buildbot/default.nix
@@ -138,7 +138,7 @@ in
138 permissions = "0600"; 138 permissions = "0600";
139 user = "buildbot"; 139 user = "buildbot";
140 group = "buildbot"; 140 group = "buildbot";
141 text = builtins.readFile "${config.myEnv.privateFiles}/buildbot_ssh_key"; 141 text = config.myEnv.buildbot.ssh_key.private;
142 dest = "buildbot/ssh_key"; 142 dest = "buildbot/ssh_key";
143 } 143 }
144 ]; 144 ];
diff --git a/modules/private/databases/default.nix b/modules/private/databases/default.nix
index 6cd6feb..1241658 100644
--- a/modules/private/databases/default.nix
+++ b/modules/private/databases/default.nix
@@ -25,7 +25,7 @@ in
25 }; 25 };
26 26
27 openldap = { 27 openldap = {
28 accessFile = "${config.myEnv.privateFiles}/ldap.conf"; 28 accessFile = ../../../nixops/secrets/ldap.conf;
29 baseDn = config.myEnv.ldap.base; 29 baseDn = config.myEnv.ldap.base;
30 rootDn = config.myEnv.ldap.root_dn; 30 rootDn = config.myEnv.ldap.root_dn;
31 rootPw = config.myEnv.ldap.root_pw; 31 rootPw = config.myEnv.ldap.root_pw;
diff --git a/modules/private/environment.nix b/modules/private/environment.nix
index f0af572..65d9f0a 100644
--- a/modules/private/environment.nix
+++ b/modules/private/environment.nix
@@ -805,6 +805,15 @@ in
805 description = "Buildbot configuration"; 805 description = "Buildbot configuration";
806 type = submodule { 806 type = submodule {
807 options = { 807 options = {
808 ssh_key = mkOption {
809 description = "SSH key information";
810 type = submodule {
811 options = {
812 public = mkOption { type = str; description = "Public part of the key"; };
813 private = mkOption { type = lines; description = "Private part of the key"; };
814 };
815 };
816 };
808 workerPassword = mkOption { description = "Buildbot worker password"; type = str; }; 817 workerPassword = mkOption { description = "Buildbot worker password"; type = str; };
809 user = mkOption { 818 user = mkOption {
810 description = "Buildbot user"; 819 description = "Buildbot user";
@@ -961,6 +970,15 @@ in
961 type = submodule { 970 type = submodule {
962 options = { 971 options = {
963 ldap = mkLdapOptions "Gitolite" {}; 972 ldap = mkLdapOptions "Gitolite" {};
973 ssh_key = mkOption {
974 description = "SSH key information";
975 type = submodule {
976 options = {
977 public = mkOption { type = str; description = "Public part of the key"; };
978 private = mkOption { type = lines; description = "Private part of the key"; };
979 };
980 };
981 };
964 }; 982 };
965 }; 983 };
966 }; 984 };
@@ -1461,13 +1479,6 @@ in
1461 }; 1479 };
1462 }; 1480 };
1463 }; 1481 };
1464
1465 privateFiles = mkOption {
1466 type = path;
1467 description = ''
1468 Path to secret files to make available during build
1469 '';
1470 };
1471 }; 1482 };
1472 options.hostEnv = mkOption { 1483 options.hostEnv = mkOption {
1473 readOnly = true; 1484 readOnly = true;
diff --git a/modules/private/system.nix b/modules/private/system.nix
index 0e72d99..c7e277c 100644
--- a/modules/private/system.nix
+++ b/modules/private/system.nix
@@ -4,7 +4,12 @@
4 networking.extraHosts = builtins.concatStringsSep "\n" 4 networking.extraHosts = builtins.concatStringsSep "\n"
5 (lib.mapAttrsToList (n: v: "${v.config.hostEnv.ips.main.ip4} ${n}") nodes); 5 (lib.mapAttrsToList (n: v: "${v.config.hostEnv.ips.main.ip4} ${n}") nodes);
6 6
7 users.extraUsers.root.openssh.authorizedKeys.keyFiles = [ "${config.myEnv.privateFiles}/id_ed25519.pub" ]; 7 users.extraUsers.root.openssh.authorizedKeys.keys = [ config.myEnv.sshd.rootKeys.nix_repository ];
8 secrets.deleteSecretsVars = true;
9 secrets.gpgKeys = [
10 ../../nixops/public_keys/Immae.pub
11 ];
12
8 services.openssh.enable = true; 13 services.openssh.enable = true;
9 14
10 services.duplyBackup.profiles.system = { 15 services.duplyBackup.profiles.system = {
diff --git a/modules/private/system/backup-2.nix b/modules/private/system/backup-2.nix
index d1064c7..1f226c0 100644
--- a/modules/private/system/backup-2.nix
+++ b/modules/private/system/backup-2.nix
@@ -1,4 +1,3 @@
1{ privateFiles }:
2{ config, pkgs, resources, name, ... }: 1{ config, pkgs, resources, name, ... }:
3{ 2{
4 deployment = { 3 deployment = {
@@ -6,8 +5,10 @@
6 targetHost = config.hostEnv.ips.main.ip4; 5 targetHost = config.hostEnv.ips.main.ip4;
7 substituteOnDestination = true; 6 substituteOnDestination = true;
8 }; 7 };
8 # ssh-keyscan backup-2 | nix-shell -p ssh-to-age --run ssh-to-age
9 secrets.ageKeys = [ "age1kk3nr27qu42j28mcfdag5lhq0zu2pky7gfanvne8l4z2ctevjpgskmw0sr" ];
9 boot.kernelPackages = pkgs.linuxPackages_latest; 10 boot.kernelPackages = pkgs.linuxPackages_latest;
10 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 11 myEnv = import ../../../nixops/secrets/environment.nix;
11 12
12 imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ] ++ builtins.attrValues (import ../..); 13 imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ] ++ builtins.attrValues (import ../..);
13 14
diff --git a/modules/private/system/dilion.nix b/modules/private/system/dilion.nix
index a59d607..b9be8b0 100644
--- a/modules/private/system/dilion.nix
+++ b/modules/private/system/dilion.nix
@@ -1,4 +1,3 @@
1{ privateFiles }:
2{ config, pkgs, name, lib, ... }: 1{ config, pkgs, name, lib, ... }:
3{ 2{
4 deployment = { 3 deployment = {
@@ -6,6 +5,8 @@
6 targetHost = config.hostEnv.ips.main.ip4; 5 targetHost = config.hostEnv.ips.main.ip4;
7 substituteOnDestination = true; 6 substituteOnDestination = true;
8 }; 7 };
8 # ssh-keyscan dilion | nix-shell -p ssh-to-age --run ssh-to-age
9 secrets.ageKeys = [ "age1x49n6qa0arkdpq8530s7umgm0gqkq90exv4jep97q30rfnzknpaqate06a" ];
9 nixpkgs.system = lib.mkOverride 900 "x86_64-linux"; 10 nixpkgs.system = lib.mkOverride 900 "x86_64-linux";
10 boot = { 11 boot = {
11 loader = { 12 loader = {
@@ -31,7 +32,7 @@
31 powerManagement.cpuFreqGovernor = "powersave"; 32 powerManagement.cpuFreqGovernor = "powersave";
32 hardware.enableRedistributableFirmware = true; 33 hardware.enableRedistributableFirmware = true;
33 34
34 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 35 myEnv = import ../../../nixops/secrets/environment.nix;
35 36
36 swapDevices = [ { label = "swap"; } ]; 37 swapDevices = [ { label = "swap"; } ];
37 fileSystems = { 38 fileSystems = {
@@ -88,10 +89,10 @@
88 isSystemUser = true; 89 isSystemUser = true;
89 group = "libvirtd"; 90 group = "libvirtd";
90 packages = [ pkgs.netcat-openbsd ]; 91 packages = [ pkgs.netcat-openbsd ];
91 openssh.authorizedKeys.keyFiles = [ 92 openssh.authorizedKeys.keys = [
92 "${privateFiles}/buildbot_ssh_key.pub" 93 config.myEnv.buildbot.ssh_key.public
94 config.myEnv.sshd.rootKeys.ismael_flony
93 ]; 95 ];
94 openssh.authorizedKeys.keys = [ config.myEnv.sshd.rootKeys.ismael_flony ];
95 }; 96 };
96 97
97 users.users.backup = { 98 users.users.backup = {
diff --git a/modules/private/system/eldiron.nix b/modules/private/system/eldiron.nix
index 4fb18a0..6c570c8 100644
--- a/modules/private/system/eldiron.nix
+++ b/modules/private/system/eldiron.nix
@@ -1,4 +1,3 @@
1{ privateFiles }:
2{ config, pkgs, lib, ... }: 1{ config, pkgs, lib, ... }:
3{ 2{
4 deployment = { 3 deployment = {
@@ -6,6 +5,8 @@
6 targetHost = config.hostEnv.ips.main.ip4; 5 targetHost = config.hostEnv.ips.main.ip4;
7 substituteOnDestination = true; 6 substituteOnDestination = true;
8 }; 7 };
8 # ssh-keyscan eldiron | nix-shell -p ssh-to-age --run ssh-to-age
9 secrets.ageKeys = [ "age1dxr5lhvtnjssfaqpnf6qx80h8gfwkxg3tdf35m6n9wljmk7wadfs3kmahj" ];
9 boot = { 10 boot = {
10 kernelModules = [ "kvm-intel" ]; 11 kernelModules = [ "kvm-intel" ];
11 blacklistedKernelModules = [ "nvidiafb" ]; 12 blacklistedKernelModules = [ "nvidiafb" ];
@@ -28,7 +29,7 @@
28 ''; 29 '';
29 nix.maxJobs = 8; 30 nix.maxJobs = 8;
30 powerManagement.cpuFreqGovernor = "powersave"; 31 powerManagement.cpuFreqGovernor = "powersave";
31 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 32 myEnv = import ../../../nixops/secrets/environment.nix;
32 33
33 fileSystems = { 34 fileSystems = {
34 # pools: 35 # pools:
diff --git a/modules/private/system/monitoring-1.nix b/modules/private/system/monitoring-1.nix
index 2198d09..e335080 100644
--- a/modules/private/system/monitoring-1.nix
+++ b/modules/private/system/monitoring-1.nix
@@ -1,4 +1,3 @@
1{ privateFiles }:
2{ config, pkgs, resources, ... }: 1{ config, pkgs, resources, ... }:
3{ 2{
4 deployment = { 3 deployment = {
@@ -6,8 +5,10 @@
6 targetHost = config.hostEnv.ips.main.ip4; 5 targetHost = config.hostEnv.ips.main.ip4;
7 substituteOnDestination = true; 6 substituteOnDestination = true;
8 }; 7 };
8 # ssh-keyscan monitoring-1 | nix-shell -p ssh-to-age --run ssh-to-age
9 secrets.ageKeys = [ "age1dn4lzhgxusqrpjjnzm7w8ml39ptf326htuzmpqdqs2gg3wq7cqzqxuvx8k" ];
9 boot.kernelPackages = pkgs.linuxPackages_latest; 10 boot.kernelPackages = pkgs.linuxPackages_latest;
10 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 11 myEnv = import ../../../nixops/secrets/environment.nix;
11 12
12 imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ] ++ builtins.attrValues (import ../..); 13 imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ] ++ builtins.attrValues (import ../..);
13 14
diff --git a/modules/private/system/quatresaisons.nix b/modules/private/system/quatresaisons.nix
index 03446e7..0148650 100644
--- a/modules/private/system/quatresaisons.nix
+++ b/modules/private/system/quatresaisons.nix
@@ -1,4 +1,3 @@
1{ privateFiles }:
2{ config, pkgs, lib, ... }: 1{ config, pkgs, lib, ... }:
3let 2let
4 serverSpecificConfig = config.myEnv.serverSpecific.quatresaisons; 3 serverSpecificConfig = config.myEnv.serverSpecific.quatresaisons;
@@ -164,6 +163,8 @@ in
164 targetHost = config.hostEnv.ips.main.ip4; 163 targetHost = config.hostEnv.ips.main.ip4;
165 substituteOnDestination = true; 164 substituteOnDestination = true;
166 }; 165 };
166 # ssh-keyscan quatresaison | nix-shell -p ssh-to-age --run ssh-to-age
167 secrets.ageKeys = [ "age1yz8u6xvh2fltvyp96ep8crce3qx4tuceyhun6pwddfe0uvcrkarscxl7e7" ];
167 168
168 programs.ssh.package = pkgs.openssh.overrideAttrs(old: { 169 programs.ssh.package = pkgs.openssh.overrideAttrs(old: {
169 PATH_PASSWD_PROG = "/run/wrappers/bin/passwd"; 170 PATH_PASSWD_PROG = "/run/wrappers/bin/passwd";
@@ -173,7 +174,7 @@ in
173 imports = builtins.attrValues (import ../..) ++ 174 imports = builtins.attrValues (import ../..) ++
174 [ ./quatresaisons/nextcloud.nix ./quatresaisons/databases.nix ]; 175 [ ./quatresaisons/nextcloud.nix ./quatresaisons/databases.nix ];
175 176
176 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 177 myEnv = import ../../../nixops/secrets/environment.nix;
177 178
178 fileSystems = { 179 fileSystems = {
179 "/" = { device = "/dev/disk/by-uuid/865931b4-c5cc-439f-8e42-8072c7a30634"; fsType = "ext4"; }; 180 "/" = { device = "/dev/disk/by-uuid/865931b4-c5cc-439f-8e42-8072c7a30634"; fsType = "ext4"; };
diff --git a/modules/secrets.nix b/modules/secrets.nix
index ecc1ebc..86d276a 100644
--- a/modules/secrets.nix
+++ b/modules/secrets.nix
@@ -6,11 +6,36 @@
6 default = []; 6 default = [];
7 description = "Keys to upload to server"; 7 description = "Keys to upload to server";
8 }; 8 };
9 gpgKeys = lib.mkOption {
10 type = lib.types.listOf lib.types.path;
11 default = [];
12 description = "GPG public keys files to encrypt to";
13 };
14 ageKeys = lib.mkOption {
15 type = lib.types.listOf lib.types.str;
16 default = [];
17 description = "AGE keys to encrypt to";
18 };
19 decryptKey = lib.mkOption {
20 type = lib.types.str;
21 default = "/etc/ssh/ssh_host_ed25519_key";
22 description = "ed25519 key used to decrypt with AGE";
23 };
9 location = lib.mkOption { 24 location = lib.mkOption {
10 type = lib.types.path; 25 type = lib.types.path;
11 default = "/var/secrets"; 26 default = "/var/secrets";
12 description = "Location where to put the keys"; 27 description = "Location where to put the keys";
13 }; 28 };
29 secretsVars = lib.mkOption {
30 type = lib.types.path;
31 default = "/run/keys/vars.yml";
32 description = "Location where the secrets variables are defined, to be used to fill the templates in secrets";
33 };
34 deleteSecretsVars = lib.mkOption {
35 type = lib.types.bool;
36 default = false;
37 description = "Delete secrets file after deployment";
38 };
14 # Read-only variables 39 # Read-only variables
15 fullPaths = lib.mkOption { 40 fullPaths = lib.mkOption {
16 type = lib.types.attrsOf lib.types.path; 41 type = lib.types.attrsOf lib.types.path;
@@ -33,56 +58,56 @@
33 ${v.user or "root"} ${v.group or "root"} ${v.permissions or "0600"} ${fpath v} 58 ${v.user or "root"} ${v.group or "root"} ${v.permissions or "0600"} ${fpath v}
34 EOF 59 EOF
35 ''; 60 '';
36 secrets = pkgs.runCommand "secrets.tar" {} '' 61 secrets = pkgs.runCommand "secrets.tar.enc" {
62 buildInputs = [ pkgs.gnupg pkgs.sops ];
63 } ''
37 touch mods 64 touch mods
38 tar --format=ustar --mtime='1970-01-01' -P --transform="s@${empty}@secrets@" -cf $out ${empty}/done 65 tar --format=ustar --mtime='1970-01-01' -P --transform="s@${empty}@secrets@" -cf $out ${empty}/done
39 ${builtins.concatStringsSep "\n" (map dumpKey keys)} 66 ${builtins.concatStringsSep "\n" (map dumpKey keys)}
40 cat mods | while read u g p k; do 67 cat mods | while read u g p k; do
41 tar --format=ustar --mtime='1970-01-01' --owner="$u" --group="$g" --mode="$p" --append -f $out "$k" 68 tar --format=ustar --mtime='1970-01-01' --owner="$u" --group="$g" --mode="$p" --append -f $out "$k"
42 done 69 done
70 export HOME=$(pwd)
71 fingerprints=
72 for key in ${builtins.concatStringsSep " " config.secrets.gpgKeys}; do
73 gpg --import $key 2>/dev/null
74 fingerprints=$fingerprints,$(cat $key | gpg --with-colons --import-options show-only --import 2>/dev/null | grep ^fpr | cut -d: -f10 | head -n1)
75 done
76
77 sops --age ${builtins.concatStringsSep "," config.secrets.ageKeys} --pgp ''${fingerprints#,} --input-type binary -i -e $out 2>/dev/null
43 ''; 78 '';
44 in lib.mkIf (builtins.length keys > 0) { 79 in lib.mkIf (builtins.length keys > 0) {
45 system.activationScripts.secrets = { 80 system.activationScripts.secrets = {
46 deps = [ "users" "wrappers" ]; 81 deps = [ "users" "wrappers" ];
47 text = '' 82 text = ''
48 install -m0750 -o root -g keys -d ${location} 83 install -m0750 -o root -g keys -d ${location}
49 if [ -f /run/keys/secrets.tar ]; then 84 TMP=$(${pkgs.coreutils}/bin/mktemp -d)
50 if [ ! -f ${location}/currentSecrets ] || ! sha512sum -c --status "${location}/currentSecrets"; then 85 TMPWORK=$(${pkgs.coreutils}/bin/mktemp -d)
51 echo "rebuilding secrets" 86 chmod go-rwx $TMPWORK
52 TMP=$(${pkgs.coreutils}/bin/mktemp -d) 87 if [ -n "$TMP" -a -n "$TMPWORK" ]; then
53 if [ -n "$TMP" ]; then 88 install -m0750 -o root -g keys -d $TMP
54 install -m0750 -o root -g keys -d $TMP 89 ${pkgs.ssh-to-age}/bin/ssh-to-age -private-key -i ${config.secrets.decryptKey} -o $TMPWORK/keys.txt
55 ${pkgs.gnutar}/bin/tar --strip-components 1 -C $TMP -xf /run/keys/secrets.tar 90 SOPS_AGE_KEY_FILE=$TMPWORK/keys.txt ${pkgs.sops}/bin/sops -d ${secrets} | ${pkgs.gnutar}/bin/tar --strip-components 1 -C $TMP -x
56 if [ -f /run/keys/vars.yml ]; then 91 if [ -f ${config.secrets.secretsVars} ]; then
57 find $TMP -name "*.gucci.tpl" -exec \ 92 SOPS_AGE_KEY_FILE=$TMPWORK/keys.txt ${pkgs.sops}/bin/sops -d ${config.secrets.secretsVars} > $TMPWORK/vars.yml
58 /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}' \;
59 sha512sum /run/keys/secrets.tar /run/keys/vars.yml > $TMP/currentSecrets
60 else
61 sha512sum /run/keys/secrets.tar > $TMP/currentSecrets
62 fi
63 find $TMP -type d -exec chown root:keys {} \; -exec chmod o-rx {} \;
64 ${pkgs.rsync}/bin/rsync --exclude="*.gucci.tpl" -O -c -av --delete $TMP/ ${location}
65 rm -rf $TMP
66 fi
67 fi 93 fi
94 if [ -f $TMPWORK/vars.yml ]; then
95 find $TMP -name "*.gucci.tpl" -exec \
96 /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}' \;
97 fi
98 find $TMP -type d -exec chown root:keys {} \; -exec chmod o-rx {} \;
99 ${pkgs.rsync}/bin/rsync --exclude="*.gucci.tpl" -O -c -av --delete $TMP/ ${location}
100 rm -rf $TMP $TMPWORK ${lib.optionalString config.secrets.deleteSecretsVars config.secrets.secretsVars}
68 fi 101 fi
69 ''; 102 '';
70 }; 103 };
71 104
72 system.extraDependencies = [ secrets ];
73 deployment.secrets."secret_vars.yml" = { 105 deployment.secrets."secret_vars.yml" = {
74 source = builtins.toString <privateFiles/vars.yml>; 106 source = builtins.toString ../nixops/secrets/vars.yml;
75 destination = "/run/keys/vars.yml"; 107 destination = config.secrets.secretsVars;
76 owner.user = "root"; 108 owner.user = "root";
77 owner.group = "root"; 109 owner.group = "root";
78 permissions = "0400"; 110 permissions = "0400";
79 }; 111 };
80 deployment.secrets."secrets.tar" = {
81 source = "${secrets}";
82 destination = "/run/keys/secrets.tar";
83 owner.user = "root";
84 owner.group = "root";
85 permissions = "0400";
86 };
87 }; 112 };
88} 113}