diff --git a/README.md b/README.md index 0f1ab51..ad72270 100644 --- a/README.md +++ b/README.md @@ -73,9 +73,13 @@ even if we had a scheme to securely transfer them to each system. [Agenix](https solves this issue by encrypting the secrets using [age](https://github.com/FiloSottile/age), and then decrypting and symlinking them using the system's SSH host key during system activation. -To bootstrap a new system, we must first generate a host key manually using `ssh-keygen -A -f /mnt/nix/persist` -during installation. Then, on an existing system, add the new host's public key to `secrets.nix` and rekey all -secrets using `agenix --rekey`. Commit and push the changes and proceed below. +All secrets, and other private configuration such as DNS zonefiles, are stored +in a separate, private [repo](https://git.caspervk.net/caspervk/nixos-secrets). +To bootstrap a new system, we must first generate a host key manually using +`ssh-keygen -A -f /mnt/nix/persist` during installation. Then, on an existing +system, add the new host's public key to `secrets.nix` in the `nixos-secrets` +repo and rekey all secrets using `agenix --rekey`. Commit and transfer the +repository to the new system. When managing secrets, the Keepass recovery key is used like so: ```fish @@ -93,7 +97,7 @@ cd tmp/ nixos-generate-config --root /mnt --show-hardware-config vim hosts/omega/hardware.nix git add . # nix sometimes ignores files outside version control -nixos-install --no-root-passwd --flake .#omega +nixos-install --no-root-passwd --flake .#omega --override-input secrets ./../nixos-secrets/ ``` ### Hardware Configuration @@ -107,8 +111,8 @@ enough](https://sourcegraph.com/search?q=context%3Aglobal+repo%3A%5Egithub%5C.co ## Useful Commands ```fish -# upgrade system -sudo nixos-rebuild switch --flake . +# development +sudo nixos-rebuild switch --flake . --override-input secrets ./../nixos-secrets/ # start build environment with user's default shell instead of bash nix develop --command $SHELL @@ -122,8 +126,7 @@ nix shell --impure --expr 'with builtins.getFlake "nixpkgs"; with legacyPackages ### Debugging ```nix # load flake into repl -nix repl -:lf . +nix repl . --override-input secrets ./../nixos-secrets/ # print a configuration option :p nixosConfigurations.omega.options.services.openssh.ports.declarationPositions # declaration diff --git a/flake.lock b/flake.lock index 3a54462..7032229 100644 --- a/flake.lock +++ b/flake.lock @@ -32,11 +32,11 @@ ] }, "locked": { - "lastModified": 1706981411, - "narHash": "sha256-cLbLPTL1CDmETVh4p0nQtvoF+FSEjsnJTFpTxhXywhQ=", + "lastModified": 1710888565, + "narHash": "sha256-s9Hi4RHhc6yut4EcYD50sZWRDKsugBJHSbON8KFwoTw=", "owner": "nix-community", "repo": "home-manager", - "rev": "652fda4ca6dafeb090943422c34ae9145787af37", + "rev": "f33900124c23c4eca5831b9b5eb32ea5894375ce", "type": "github" }, "original": { @@ -53,11 +53,11 @@ ] }, "locked": { - "lastModified": 1710820906, - "narHash": "sha256-2bNMraoRB4pdw/HtxgYTFeMhEekBZeQ53/a8xkqpbZc=", + "lastModified": 1711625603, + "narHash": "sha256-W+9dfqA9bqUIBV5u7jaIARAzMe3kTq/Hp2SpSVXKRQw=", "owner": "nix-community", "repo": "home-manager", - "rev": "022464438a85450abb23d93b91aa82e0addd71fb", + "rev": "c0ef0dab55611c676ad7539bf4e41b3ec6fa87d2", "type": "github" }, "original": { @@ -89,11 +89,11 @@ ] }, "locked": { - "lastModified": 1710644923, - "narHash": "sha256-0fjbN5GYYDKPyPay0l8gYoH+tFfNqPPwP5sxxBreeA4=", + "lastModified": 1711249705, + "narHash": "sha256-h/NQECj6mIzF4XR6AQoSpkCnwqAM+ol4+qOdYi2ykmQ=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "e25efda85e39fcdc845e371971ac4384989c4295", + "rev": "34519f3bb678a5abbddf7b200ac5347263ee781b", "type": "github" }, "original": { @@ -104,11 +104,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1710783728, - "narHash": "sha256-eIsfu3c9JUBgm3cURSKTXLEI9Dlk1azo+MWKZVqrmkc=", + "lastModified": 1711352745, + "narHash": "sha256-luvqik+i3HTvCbXQZgB6uggvEcxI9uae0nmrgtXJ17U=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "1e679b9a9970780cd5d4dfe755a74a8f96d33388", + "rev": "9a763a7acc4cfbb8603bb0231fec3eda864f81c0", "type": "github" }, "original": { @@ -120,11 +120,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1710695816, - "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", + "lastModified": 1711460390, + "narHash": "sha256-akSgjDZL6pVHEfSE6sz1DNSXuYX6hq+P/1Z5IoYWs7E=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "614b4613980a522ba49f0d194531beddbb7220d3", + "rev": "44733514b72e732bd49f5511bd0203dea9b9a434", "type": "github" }, "original": { @@ -136,11 +136,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1710806803, - "narHash": "sha256-qrxvLS888pNJFwJdK+hf1wpRCSQcqA6W5+Ox202NDa0=", + "lastModified": 1711523803, + "narHash": "sha256-UKcYiHWHQynzj6CN/vTcix4yd1eCu1uFdsuarupdCQQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b06025f1533a1e07b6db3e75151caa155d1c7eb3", + "rev": "2726f127c15a4cc9810843b96cad73c7eb39e443", "type": "github" }, "original": { @@ -159,7 +159,23 @@ "nix-index-database": "nix-index-database", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs", - "nixpkgs-unstable": "nixpkgs-unstable" + "nixpkgs-unstable": "nixpkgs-unstable", + "secrets": "secrets" + } + }, + "secrets": { + "locked": { + "lastModified": 1711637855, + "narHash": "sha256-ZFMl20Qils3CWuAqvDqKjyyMgwz1pDb7PlfgaUAle38=", + "ref": "refs/heads/master", + "rev": "ac8e242cc499ae120136022f30aaf315ef08da93", + "revCount": 4, + "type": "git", + "url": "ssh://git@git.caspervk.net/caspervk/nixos-secrets.git" + }, + "original": { + "type": "git", + "url": "ssh://git@git.caspervk.net/caspervk/nixos-secrets.git" } }, "systems": { diff --git a/flake.nix b/flake.nix index cfd8e79..7c1786f 100644 --- a/flake.nix +++ b/flake.nix @@ -2,6 +2,9 @@ description = "NixOS system"; inputs = { + secrets = { + url = "git+ssh://git@git.caspervk.net/caspervk/nixos-secrets.git"; + }; nixpkgs = { url = "github:NixOS/nixpkgs/nixos-23.11"; }; diff --git a/hosts/alpha/network.nix b/hosts/alpha/network.nix index 6d12a97..31b61f2 100644 --- a/hosts/alpha/network.nix +++ b/hosts/alpha/network.nix @@ -1,4 +1,8 @@ -{config, ...}: { +{ + config, + secrets, + ... +}: { systemd.network = { # Main interface networks."10-lan" = { @@ -80,14 +84,14 @@ }; age.secrets.wireguard-preshared-key-file = { - file = ../../secrets/wireguard-preshared-key-file.age; + file = "${secrets}/secrets/wireguard-preshared-key-file.age"; mode = "640"; owner = "root"; group = "systemd-network"; }; age.secrets.wireguard-private-key-file-alpha = { - file = ../../secrets/wireguard-private-key-file-alpha.age; + file = "${secrets}/secrets/wireguard-private-key-file-alpha.age"; mode = "640"; owner = "root"; group = "systemd-network"; diff --git a/hosts/omega/borg.nix b/hosts/omega/borg.nix index 4ee4a92..eb8645a 100644 --- a/hosts/omega/borg.nix +++ b/hosts/omega/borg.nix @@ -1,8 +1,14 @@ -{...}: { +{secrets, ...}: { imports = [ ../../modules/borg.nix ]; services.borgbackup.jobs.root.repo = "ssh://u394155-sub1@u394155.your-storagebox.de:23/./root"; - age.secrets.borg-passphrase-file.file = ../../secrets/borg-passphrase-file-omega.age; + + age.secrets.borg-passphrase-file = { + file = "${secrets}/secrets/borg-passphrase-file-omega.age"; + mode = "400"; + owner = "root"; + group = "root"; + }; } diff --git a/hosts/omega/network.nix b/hosts/omega/network.nix index 68bb353..c0a9d30 100644 --- a/hosts/omega/network.nix +++ b/hosts/omega/network.nix @@ -1,4 +1,8 @@ -{config, ...}: { +{ + config, + secrets, + ... +}: { systemd.network = { config = { routeTables = { @@ -94,14 +98,14 @@ }; age.secrets.wireguard-preshared-key-file = { - file = ../../secrets/wireguard-preshared-key-file.age; + file = "${secrets}/secrets/wireguard-preshared-key-file.age"; mode = "640"; owner = "root"; group = "systemd-network"; }; age.secrets.wireguard-private-key-file-omega = { - file = ../../secrets/wireguard-private-key-file-omega.age; + file = "${secrets}/secrets/wireguard-private-key-file-omega.age"; mode = "640"; owner = "root"; group = "systemd-network"; diff --git a/hosts/zeta/borg.nix b/hosts/zeta/borg.nix index 25fed66..9c57a1c 100644 --- a/hosts/zeta/borg.nix +++ b/hosts/zeta/borg.nix @@ -1,8 +1,13 @@ -{...}: { +{secrets, ...}: { imports = [ ../../modules/borg.nix ]; services.borgbackup.jobs.root.repo = "ssh://u394155-sub2@u394155.your-storagebox.de:23/./root"; - age.secrets.borg-passphrase-file.file = ../../secrets/borg-passphrase-file-zeta.age; + age.secrets.borg-passphrase-file = { + file = "${secrets}/secrets/borg-passphrase-file-zeta.age"; + mode = "400"; + owner = "root"; + group = "root"; + }; } diff --git a/modules/base/users.nix b/modules/base/users.nix index 8da8597..1b3f145 100644 --- a/modules/base/users.nix +++ b/modules/base/users.nix @@ -1,6 +1,7 @@ { config, pkgs, + secrets, ... }: { users = { @@ -27,7 +28,7 @@ }; age.secrets.users-hashed-password-file = { - file = ../../secrets/users-hashed-password-file.age; + file = "${secrets}/secrets/users-hashed-password-file.age"; mode = "400"; owner = "root"; group = "root"; diff --git a/modules/borg.nix b/modules/borg.nix index 43da5bf..2502c68 100644 --- a/modules/borg.nix +++ b/modules/borg.nix @@ -117,11 +117,4 @@ programs.ssh.knownHosts = { "[u394155.your-storagebox.de]:23".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs"; }; - - age.secrets.borg-passphrase-file = { - # file set on each host - mode = "400"; - owner = "root"; - group = "root"; - }; } diff --git a/modules/server/system.nix b/modules/server/system.nix index 791cd8d..dcc65ca 100644 --- a/modules/server/system.nix +++ b/modules/server/system.nix @@ -1,4 +1,8 @@ -{...}: { +{ + config, + secrets, + ... +}: { # Automatically `nixos-rebuild switch` daily with the latest configuration # from git. This overwrites any uncommitted changes in ~/nixos/, which is why # it is only enabled on servers. Note that this requires updating flake.lock @@ -10,4 +14,14 @@ enable = true; flake = "git+https://git.caspervk.net/caspervk/nixos.git"; }; + + # The `nixos-secrets` flake input requires authentication + systemd.services.nixos-upgrade.environment.GIT_SSH_COMMAND = "ssh -i ${config.age.secrets.autoupgrade-deploy-key.path}"; + + age.secrets.autoupgrade-deploy-key = { + file = "${secrets}/secrets/autoupgrade-deploy-key.age"; + mode = "400"; + owner = "root"; + group = "root"; + }; }