From b6c85d89dd1e02a91324288d9d57253f2ccf3ccb Mon Sep 17 00:00:00 2001 From: Dennis Wuitz Date: Tue, 26 Dec 2023 19:06:02 +0100 Subject: [PATCH] configure programs for photon --- .envrc | 1 + .gitignore | 3 + .sops.yaml | 33 +++++++++-- flake.lock | 18 +++--- flake.nix | 17 ++++++ modules/backup.nix | 122 +++++++++++++++++++++++++++++++++++++++ systems/programs.nix | 1 + users/alice/secrets.yaml | 51 ++++++++++++++++ users/default.nix | 1 + 9 files changed, 234 insertions(+), 13 deletions(-) create mode 100644 .envrc create mode 100644 modules/backup.nix create mode 100644 users/alice/secrets.yaml diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 5857177..caf0618 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ +.direnv +.envrc + result result-man \ No newline at end of file diff --git a/.sops.yaml b/.sops.yaml index 78c7757..9fdee2c 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,8 +1,7 @@ keys: # The PGP keys in keys/ - - &admins - - F63832C3080D6E1AC77EECF80B4245FFE305BC82 # alice - - 8F79E6CD6434700615867480D11A514F5095BFA8 # dennis + - &admin_alice F63832C3080D6E1AC77EECF80B4245FFE305BC82 + - &admin_dennis 8F79E6CD6434700615867480D11A514F5095BFA8 # Generate AGE keys from SSH keys with: # nix-shell -p ssh-to-age --run 'ssh some.ssh.wavelens.io cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age' @@ -11,8 +10,34 @@ keys: # update keys by executing: sops updatekeys secrets.yaml creation_rules: + - path_regex: systems/palatine-hill/secrets\.yaml$ + key_groups: + - pgp: + - *admin_alice + - *admin_dennis + age: + - *palatine-hill + - path_regex: systems/photon/secrets\.yaml$ key_groups: - - pgp: *admins + - pgp: + - *admin_alice + - *admin_dennis age: + - *photon + + - path_regex: users/alice/secrets\.yaml$ + key_groups: + - pgp: + - *admin_alice + age: + - *palatine-hill + - *photon + + - path_regex: users/dennis/secrets\.yaml$ + key_groups: + - pgp: + - *admin_dennis + age: + - *palatine-hill - *photon \ No newline at end of file diff --git a/flake.lock b/flake.lock index 62f675e..88fe7a5 100644 --- a/flake.lock +++ b/flake.lock @@ -7,11 +7,11 @@ ] }, "locked": { - "lastModified": 1703527373, - "narHash": "sha256-AjypRssRtS6F3xkf7rE3/bXkIF2WJOZLbTIspjcE1zM=", + "lastModified": 1703657526, + "narHash": "sha256-C3fQG/tasnhtfJb0cvXthMDUJ/OLgCKNLqfMuR/M+0k=", "owner": "nix-community", "repo": "home-manager", - "rev": "80679ea5074ab7190c4cce478c600057cfb5edae", + "rev": "d1d950841d230490f308f5fcf8c0d4f2bd3f24a7", "type": "github" }, "original": { @@ -43,11 +43,11 @@ ] }, "locked": { - "lastModified": 1703545968, - "narHash": "sha256-u5yE7Bw2mw/yu+Ljk51YOoy0rz3suGdiOS6dSu8Zgm0=", + "lastModified": 1703639290, + "narHash": "sha256-Bflli82UQGjhlg4Gh7FVaYG/CmLa4D9irv2qx2PxpFQ=", "owner": "SuperSandro2000", "repo": "nixos-modules", - "rev": "c5ae5e9b02fddb35ae37479c77238fc3dd9a1589", + "rev": "4251f23f93ef6d38fc16884758f01862301b9590", "type": "github" }, "original": { @@ -58,11 +58,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1703255338, - "narHash": "sha256-Z6wfYJQKmDN9xciTwU3cOiOk+NElxdZwy/FiHctCzjU=", + "lastModified": 1703438236, + "narHash": "sha256-aqVBq1u09yFhL7bj1/xyUeJjzr92fXVvQSSEx6AdB1M=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6df37dc6a77654682fe9f071c62b4242b5342e04", + "rev": "5f64a12a728902226210bf01d25ec6cbb9d9265b", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 0739b01..1d24cf1 100644 --- a/flake.nix +++ b/flake.nix @@ -53,6 +53,12 @@ ++ map(user: { config, lib, pkgs, ... }@args: { users.users.${user} = import ./users/${user} (args // { name = "${user}"; }); boot.initrd.network.ssh.authorizedKeys = config.users.users.${user}.openssh.authorizedKeys.keys; + sops = { + secrets."${user}/user-password" = { + sopsFile = ./users/${user}/secrets.yaml; + neededForUsers = true; + }; + }; }) users ++ map(user: { home-manager.users.${user} = import ./users/${user}/home.nix; }) users; }; @@ -73,5 +79,16 @@ ]; }; }; + + devShell = lib.mapAttrs (system: sopsPkgs: + with nixpkgs.legacyPackages.${system}; + mkShell { + sopsPGPKeyDirs = [ "./keys" ]; + nativeBuildInputs = [ + apacheHttpd + sopsPkgs.sops-import-keys-hook + ]; + } + ) sops-nix.packages; }; } diff --git a/modules/backup.nix b/modules/backup.nix new file mode 100644 index 0000000..0f07a60 --- /dev/null +++ b/modules/backup.nix @@ -0,0 +1,122 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.backup; +in +{ + options.services.backup = { + enable = lib.mkEnableOption "backup"; + + paths = lib.mkOption { + type = with lib.types; listOf str; + default = []; + description = "Extra paths to include in backup."; + }; + + exclude = lib.mkOption { + type = with lib.types; listOf str; + default = []; + description = "Extra paths to exclude in backup."; + }; + }; + + config = { + assertions = [ { + assertion = cfg.paths != [ ] -> cfg.enable; + message = "Configuring backup services.backup.paths without enabling services.backup.enable is useless!"; + } ]; + + services = { + postgresqlBackup = { + inherit (config.services.postgresql) enable; + backupAll = true; + startAt = "*-*-* 04:00:00"; + }; + + restic.backups = + let + commonOpts = { + extraBackupArgs = [ + "--exclude-file=${pkgs.writeText "restic-exclude-file" (lib.concatMapStrings (x: x + "\n") cfg.exclude)}" + ]; + initialize = true; + passwordFile = config.sops.secrets."restic/password".path; + paths = [ + "/etc/group" + "/etc/machine-id" + "/etc/passwd" + "/etc/shadow" + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + "/etc/subgid" + "/etc/subuid" + "/var/lib/nixos/" + ] ++ cfg.paths + ++ lib.optional config.services.postgresql.enable "/var/backup/postgresql/" + ++ lib.optional (config.security.acme.certs != {}) "/var/lib/acme/" + ++ lib.optional config.security.dhparams.enable "/var/lib/dhparams/"; + pruneOpts = [ + "--group-by host" + "--keep-daily 7" + "--keep-weekly 4" + "--keep-monthly 12" + ]; + timerConfig = { + OnCalendar = "*-*-* 04:30:00"; + RandomizedDelaySec = "5m"; + }; + }; + in + lib.mkIf cfg.enable { + server9 = commonOpts // { + repositoryFile = config.sops.secrets."restic/repositories/server9".path; + }; + offsite = commonOpts // { + repository = "sftp://offsite/${config.networking.hostName}"; + }; + }; + }; + + sops.secrets = lib.mkIf cfg.enable { + "restic/offsite/private" = { + owner = "root"; + path = "/root/.ssh/id_offsite-backup"; + sopsFile = ./backup.yaml; + }; + "restic/offsite/public" = { + owner = "root"; + path = "/root/.ssh/id_offsite-backup.pub"; + sopsFile = ./backup.yaml; + }; + "restic/offsite/ssh-config" = { + owner = "root"; + path = "/root/.ssh/config"; + sopsFile = ./backup.yaml; + }; + + # relies on defaultSopsFile + "restic/password".owner = "root"; + "restic/repositories/server9".owner = "root"; + }; + + system.activationScripts.linkResticSSHConfigIntoVirtioFS = lib.mkIf cfg.enable '' + echo "Linking restic ssh config..." + mkdir -m700 -p /home/root/.ssh/ + ln -fs {,/home}/root/.ssh/id_offsite-backup + ln -fs {,/home}/root/.ssh/id_offsite-backup.pub + ln -fs {,/home}/root/.ssh/config + ''; + + systemd = lib.mkIf cfg.enable { + services = { + restic-backups-server9.serviceConfig.Environment = "RESTIC_PROGRESS_FPS=0.016666"; + restic-backups-offsite.serviceConfig.Environment = "RESTIC_PROGRESS_FPS=0.016666"; + }; + timers = lib.mkIf config.services.postgresqlBackup.enable { + postgresqlBackup.timerConfig.RandomizedDelaySec = "5m"; + }; + }; + }; +} \ No newline at end of file diff --git a/systems/programs.nix b/systems/programs.nix index 476fee9..65b97ff 100644 --- a/systems/programs.nix +++ b/systems/programs.nix @@ -3,6 +3,7 @@ environment.systemPackages = with pkgs; [ bat btop + croc deadnix direnv fd diff --git a/users/alice/secrets.yaml b/users/alice/secrets.yaml new file mode 100644 index 0000000..0720f95 --- /dev/null +++ b/users/alice/secrets.yaml @@ -0,0 +1,51 @@ +alice: + user-password: ENC[AES256_GCM,data:vrvMbDzLD9I=,iv:j5zA6qihQA97+eM6kn97EL4OdeEv+m0XC46qxq7qeec=,tag:r/rgcWs0Ieqx3xG8o496Dg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1z8q02wdp0a2ep5uuffgfeqlfam4ztl95frhw5qhnn6knn0rrmcnqk5evej + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBubjhKaWVMdTRVaFM0OXBR + NGdSQTYxRG5rYk11SHRsR01IbnUwb1gvc1FZCmtXVGxTYVozOXFmalE1MXdETmJ3 + Z3Y1Q0pqd0xYSHdGWExqdkh2YjhscUkKLS0tIE9Ub1Mybk90bXVDcnFBTUpFeXpK + aUQvdCtHVi9DYzk2dk5rM1g4M2FOSGsKxtWFgL9S6cdQ91pJurSD/i/3f2tWsjIT + Tqw9JoTErhO8aY12LgX6iXHpCQnHvsknN4XL1DZllBNzKJ5XLrJBHA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1rjlc6vwnz2lcrpshtd9rldlxels6l2utwmnmf3prus8drfefeywq5ljrdg + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6bEVmeVdXcUZEc3VjZzJU + Z2JsTHM0dzRleXJwRWxNei9aUC9oQWh0T1ZvCkdyWENHa1NXZHJNS25DZ1JWMFkv + cWhrQVUxYUpYVmhYeEV0NzBrY2ZuVVkKLS0tIFU0R2JlNkhtN2dmcmZxUExXRitW + SXV2OEI1QlIxVjRUVGJQZ3doSUllRk0KAd5xczxDAGqYf+e91UbtOc4A0dlf7Fir + hYEfG1Bcn7Sb5lab6DoNrj+KMh2ZnB/Kl6uVAtZ6Rscfs6N6s9KFhQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-12-27T08:22:15Z" + mac: ENC[AES256_GCM,data:kYrqx4qv7C8seyenaIDBPLaYog/LNTVd8qfFqUW2vsP7P6v8GMyQSCzi8UN22WXBnlZq0K5Fria4ZknIYB3ImqKuvdFfP40E6wK4IRAJhlLwukDAdNdMxS39ZcYiMud3mjPWyDKkoxx3ldBzdQSelAPVpQourWsiauVkM9clKNw=,iv:hoDUPBsDEjflZn+TK47u5jXWktFl5zj8CtBBC2PUFrs=,tag:JyLcTHZXyIzc6gwKzwtAzQ==,type:str] + pgp: + - created_at: "2023-12-27T07:38:50Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQIMA84hNUGIgI/nAQ//TBHE0gHfS4c7EbDRCQbPEL0XwZje06yW+ZNMHUWJWAwX + knxFPGXnlVyUF30ghkd1rCaQXrdtawg1Gml+Wpc9mG+IK7VTPM/O3Mb9QsWlvNiA + K8esjZMQ0Aq53Mb16OQolk3WuZ1toogkirzex+KMhpFvXDcEfOmV+MI1HosBv7Y1 + UJP+9vcAimuMAgG2nLF8NLGKeWARfL8sRE9Lz6RrYrljAzPH4KdVRhN8ye11ZYul + odNKRi0/gjdC2+zUfhJnDN4h+mxxybKfTFSaXIQgN5oVlR1wpxpsSAf8lNyEztIo + fB9M8K0g18h9Q1r0SASaxt3QA7CkXyu/oclvu2Qoa3P4z0GCQKur+6ednV28pzYG + tlMjuKl3InrTvtowc8ehYWNsmIkiLFQc9j0/ZEGTnmtMU/EDgQqA++oKK8iI0Gbl + FY1058k5VfI95b2dOenJ1FOAzX4krlJFveZr0Bo7RIWJA1L5zSohu5wpVJj3vmVu + ss2t3qOLSog3YcAEP5bibejPxojb/DAmhoZTK6RumRA9r2ZVu4ZnqDsIPS7SzxS6 + y9Bm8SDHrzEzQlRWQKYYI5jieEXfUAKOJwV2xOZOlgZ1tVJZEzHH+FW0ro1zaLJt + zk5BoqpHgTQLQYcSLyODvrFR/8Menx85PHty5fChbipekWx08IbSHwqhbxd8phzS + XgECotBGOy1Da7RtHHuZsJ+PBnk9oY/dZJz7Rn3UMLEgNd2DF1X0fD/PUvzZiGtL + U0CANiRypGLxDEVXcguMDDz//2UltjiuKZ6AXJ8Hij7GshBp0Wjpmc9W+MzvCqM= + =jZCc + -----END PGP MESSAGE----- + fp: F63832C3080D6E1AC77EECF80B4245FFE305BC82 + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/users/default.nix b/users/default.nix index 7a54a5f..4370194 100644 --- a/users/default.nix +++ b/users/default.nix @@ -23,5 +23,6 @@ "uaccess" ]; shell = pkgs.${defaultShell}; + hashedPasswordFile = config.sops.secrets."${name}/user-password".path; openssh.authorizedKeys.keys = publicKeys; } \ No newline at end of file