diff --git a/flake.lock b/flake.lock index ab28d6c..ac3e4da 100644 --- a/flake.lock +++ b/flake.lock @@ -121,6 +121,27 @@ "url": "https://git.clerie.de/clerie/fieldpoc.git" } }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "ssh-to-age", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709336216, + "narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -228,6 +249,22 @@ "type": "github" } }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1713434076, + "narHash": "sha256-+/p5edwlkqKZc6GDAQl+92Hoe1f3NNbUF9uj+X9H3pU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "8494ae076b7878d61a7d2d25e89a847fe8f8364c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs_2": { "locked": { "lastModified": 1665732960, @@ -271,7 +308,9 @@ "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs_3", "nixpkgs-krypton": "nixpkgs-krypton", - "solid-xmpp-alarm": "solid-xmpp-alarm" + "solid-xmpp-alarm": "solid-xmpp-alarm", + "sops-nix": "sops-nix", + "ssh-to-age": "ssh-to-age" } }, "solid-xmpp-alarm": { @@ -294,6 +333,48 @@ "url": "https://git.clerie.de/clerie/solid-xmpp-alarm.git" } }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1713532771, + "narHash": "sha256-vfKxhYVMzG2tg48/1rewBoSLCrKIjQsG1j7Nm/Y2gf4=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "a929a011a09db735abc45a8a45d1ff7fdee62755", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "ssh-to-age": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712553767, + "narHash": "sha256-hg6lBgxmTJ2hc1EFUoiA6BLA2QZGIfoBIxub9FK3x6M=", + "owner": "Mic92", + "repo": "ssh-to-age", + "rev": "5842a0023432eca39537060f38cbff7c9c2123c7", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "ssh-to-age", + "type": "github" + } + }, "systems": { "locked": { "lastModified": 1681028828, diff --git a/flake.nix b/flake.nix index 810a4ab..1dd9579 100644 --- a/flake.nix +++ b/flake.nix @@ -28,8 +28,16 @@ url = "git+https://git.clerie.de/clerie/solid-xmpp-alarm.git"; inputs.nixpkgs.follows = "nixpkgs"; }; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + ssh-to-age = { + url = "github:Mic92/ssh-to-age"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; - outputs = { self, agenix, nixpkgs, nixos-hardware, chaosevents, fernglas, nixos-exporter, solid-xmpp-alarm, ... }@inputs: let + outputs = { self, agenix, nixpkgs, nixos-hardware, chaosevents, fernglas, nixos-exporter, solid-xmpp-alarm, ssh-to-age, ... }@inputs: let lib = import ./lib inputs; helper = lib.flake-helper; in { @@ -111,6 +119,8 @@ agenix; inherit (chaosevents.packages.${system}) chaosevents; + inherit (ssh-to-age.packages.${system}) + ssh-to-age; }) ]; }; @@ -120,6 +130,8 @@ clerie-system-upgrade clerie-merge-nixfiles-update clerie-update-nixfiles + clerie-sops + clerie-sops-config chromium-incognito iot-data nix-remove-result-links diff --git a/hosts/dn42-ildix-service/configuration.nix b/hosts/dn42-ildix-service/configuration.nix index 629204a..895bc5a 100644 --- a/hosts/dn42-ildix-service/configuration.nix +++ b/hosts/dn42-ildix-service/configuration.nix @@ -45,13 +45,14 @@ autoUpgrade = true; }; + sops.secrets.wg-monitoring = {}; + clerie.monitoring = { enable = true; id = "391"; pubkey = "Rfu2JLxAk0seAZgt43sOEAF69Z9uQaOjeNgM4jJF0h4="; }; - system.stateVersion = "23.05"; } diff --git a/hosts/dn42-ildix-service/secrets.json b/hosts/dn42-ildix-service/secrets.json new file mode 100644 index 0000000..3d92076 --- /dev/null +++ b/hosts/dn42-ildix-service/secrets.json @@ -0,0 +1,26 @@ +{ + "wg-monitoring": "ENC[AES256_GCM,data:kG/PCFQv4pRaup3sKOZNkwoJQ5Fdo/k5UUTh8/fedq87gA8yF7esZySUYc4=,iv:JYlaGotwiIiXVnfz98pjL1j2YwNtgoTmmk//9bABqz4=,tag:v7Csuvn1EjOxWnD2YHQ7kA==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1d3scmrwmhl5wzfq632sjg679kae3vsn8q5lmx05xrltnh5jt0yls6xnm00", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvM1hpMUJ4d2xvUWgxcFRs\nTGwyYW5vQWdwL1JObm1BR3J4OFB2Z09HQkIwCnh1TVlvUFNmOXVvdFZLL1AwNC9p\nNUxMV3ZsMW53RElXcU0veGQ2NCtyQmsKLS0tIG01Q3lIbDR0ZEQ2dDlONlhlSGho\nbU1LdzZlOGtmVmJKQjNiTE5RWVlyakkK2dm5BQ2P1cZVpFKLtARm1E9aoGM9j351\nbYmmdtTnXrgVM0rZuexiM+G+3MjZEFvGI+RkrFcGcY3WSKy0OQSlfg==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2024-04-20T21:14:46Z", + "mac": "ENC[AES256_GCM,data:WdiOdmBc6EabnWM5Wkxj3W7a+qDJr4wQQEMR39bZabTMuW+8Y/p/eX5YxUL7U6XisI5c6JPIGcGYU7gaLWSvQ9uh6eFn/NZm+3WmyVXzAUjYDC2I8pm9DKAbPUU95zMmgSQDGJYr8ZFzfTDFepCn1poaxJ7TDpfD7tUfaDwDq34=,iv:vm6BHsXkb9pjKDeI/oXU7lYg4uHuFhE9g5s/JXDu5/o=,tag:hGGz8JKjBZ84Nx/3xT+p4Q==,type:str]", + "pgp": [ + { + "created_at": "2024-04-20T21:14:21Z", + "enc": "-----BEGIN PGP MESSAGE-----\n\n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\nRZi1vIZRrA==\n=EbyO\n-----END PGP MESSAGE-----", + "fp": "0C982F87B7AFBA0F504F90A2629E741947C87928" + } + ], + "unencrypted_suffix": "_unencrypted", + "version": "3.8.1" + } +} \ No newline at end of file diff --git a/lib/flake-helper.nix b/lib/flake-helper.nix index 1f28cdb..ed8e299 100644 --- a/lib/flake-helper.nix +++ b/lib/flake-helper.nix @@ -1,4 +1,4 @@ -{ self, nixpkgs, agenix, bij, chaosevents, fernglas, fieldpoc, nixos-exporter, solid-xmpp-alarm, ... }@inputs: +{ self, nixpkgs, agenix, bij, chaosevents, fernglas, fieldpoc, nixos-exporter, solid-xmpp-alarm, sops-nix, ... }@inputs: rec { generateNixosSystem = { @@ -43,6 +43,7 @@ rec { fieldpoc.nixosModules.default nixos-exporter.nixosModules.default solid-xmpp-alarm.nixosModules.solid-xmpp-alarm + sops-nix.nixosModules.sops (../hosts + "/${name}/configuration.nix") # Automatically load secrets from the hosts secrets directory ({ lib, ... }: let @@ -52,6 +53,10 @@ rec { file = secretsPath + "/${filename}"; }) (lib.filterAttrs (name: type: (type == "regular") && (lib.hasSuffix ".age" name) ) (if builtins.pathExists secretsPath then builtins.readDir secretsPath else {})); }) + # Automatically load secrets from sops file for host + ({ ... }: { + sops.defaultSopsFile = ../hosts + "/${name}/secrets.json"; + }) ]; }; diff --git a/modules/monitoring/default.nix b/modules/monitoring/default.nix index 1e99857..831560f 100644 --- a/modules/monitoring/default.nix +++ b/modules/monitoring/default.nix @@ -54,7 +54,9 @@ in publicKey = "eyhJKV41E1F0gZHBNqyzUnj72xg5f3bdDduVtpPN4AY="; } ]; - privateKeyFile = if cfg.privateKeyFile == null then config.age.secrets.wg-monitoring.path else cfg.privateKeyFile; + privateKeyFile = if cfg.privateKeyFile != null then cfg.privateKeyFile else + if builtins.elem "wg-monitoring" (attrNames config.sops.secrets) then config.sops.secrets.wg-monitoring.path else + config.age.secrets.wg-monitoring.path; }; }; diff --git a/pkgs/clerie-sops/clerie-sops-config.nix b/pkgs/clerie-sops/clerie-sops-config.nix new file mode 100644 index 0000000..f7e13f7 --- /dev/null +++ b/pkgs/clerie-sops/clerie-sops-config.nix @@ -0,0 +1,37 @@ +{ pkgs, lib, ... }: + +with lib; + +let + hosts = builtins.attrNames (builtins.readDir ../../hosts); + + mkAgeKey = hostname: ssh_pub_file: + pkgs.runCommand "${hostname}.age" { + buildInputs = [ pkgs.ssh-to-age ]; + } '' + ssh-to-age -i ${ssh_pub_file} -o $out + ''; + + ageKeysForHost = hostname: let + ssh_pub_file = ../../hosts + "/${hostname}/ssh.pub"; + in + if builtins.pathExists ssh_pub_file then [ + (fileContents (mkAgeKey hostname ssh_pub_file)) + ] else []; + + mkCreationRules = hosts: + map (hostname: { + path_regex = escapeRegex "hosts/${hostname}/secrets.json"; + key_groups = [{ + pgp = [ + (fileContents (pkgs.clerie-keys + "/gpg/clerie@clerie.de.fingerprint.txt")) + ]; + age = ageKeysForHost hostname; + }]; + }) hosts; + + sops_config = { + creation_rules = mkCreationRules hosts; + }; +in + pkgs.writeText "sops.json" (builtins.toJSON sops_config) diff --git a/pkgs/clerie-sops/clerie-sops.nix b/pkgs/clerie-sops/clerie-sops.nix new file mode 100644 index 0000000..1730e6b --- /dev/null +++ b/pkgs/clerie-sops/clerie-sops.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: + +pkgs.writeShellApplication { + name = "clerie-sops"; + runtimeInputs = with pkgs; [ + sops + ]; + text = '' + exec sops --config ${pkgs.clerie-sops-config} "$@" + ''; +} diff --git a/pkgs/overlay.nix b/pkgs/overlay.nix index aed5107..2b6ae5a 100644 --- a/pkgs/overlay.nix +++ b/pkgs/overlay.nix @@ -2,6 +2,8 @@ final: prev: { clerie-keys = final.callPackage ./clerie-keys {}; clerie-system-upgrade = final.callPackage ./clerie-system-upgrade/clerie-system-upgrade.nix {}; clerie-merge-nixfiles-update = final.callPackage ./clerie-update-nixfiles/clerie-merge-nixfiles-update.nix {}; + clerie-sops = final.callPackage ./clerie-sops/clerie-sops.nix {}; + clerie-sops-config = final.callPackage ./clerie-sops/clerie-sops-config.nix {}; clerie-update-nixfiles = final.callPackage ./clerie-update-nixfiles/clerie-update-nixfiles.nix {}; chromium-incognito = final.callPackage ./chromium-incognito {}; iot-data = final.python3.pkgs.callPackage ./iot-data {};