diff --git a/README.md b/README.md index 853b2e5..2c6a796 100644 --- a/README.md +++ b/README.md @@ -235,3 +235,46 @@ Afterwards the secret should be available in `/run/secrets/example-key`. If the accessing process is not root it must be member of the group `config.users.groups.keys` for systemd services this can be archived by setting `serviceConfig.SupplementaryGroups = [ config.users.groups.keys.name ];` it the service configuration. + +## impermanence + +These machines are setup with `"/"` as a tmpfs. This is there to keep the machines clean. So no clutter in home +directories, no weird ad-hoc solutions of botching something into `/opt/` or something like this. All will be +gone at reboot. + +But there are some files that we want to survive reboots, for example logs or ssh keys. The solution to this is +to have a persistent storage mounted at `/persist` and automatically bind mount the paths of persistent things +to the right places. To set this up we are using the impermanence module. In our configuration this is loaded with +some default files to bind mount (ssh keys, machine-id some nixos specific things). That we have on all machines. + +If you keep your application data (like recommended) on a separate partition, the chances are you don't need +to interact with this, as most configuration files will be in the nix store anyway. If the application wants these nix +store files in certain directories, you should use `environment.etc` family of options (consult the nixos documentation +for this). This is for mutable files that are not core application data. (Like ssh keys, for a mailserver one could +think about the hash files (not the db files) of an alias map (if one doesn't want to manage that with +the nix store), things like that). + +This should not be (but could be) used for large application databases. It would be more appropriate to mount +its own filesystem for things like that. For small configuration files that are not in the nix-store, +that might be the appropriate solution. + +By default the storage is called `persist` and the default path for it is `/persist`. These can be changed +with the `impermanence.name` and `impermanence.storagePath` options. To add paths to this storage you do the +following. + +``` +environment.persistence.${config.impermanence.name} = { + directories = [ + "" + ]; + files = [ + "" + ]; +}; +``` +For this to work `config` must be binded by the function arguments of you module. So the start of your module looks +something like this: +``` +{lib, pkgs, config, ...} : + +``` diff --git a/flake.lock b/flake.lock index e3f7e40..8cc319d 100644 --- a/flake.lock +++ b/flake.lock @@ -33,6 +33,21 @@ "type": "indirect" } }, + "impermanence": { + "locked": { + "lastModified": 1694622745, + "narHash": "sha256-z397+eDhKx9c2qNafL1xv75lC0Q4nOaFlhaU1TINqb8=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "e9643d08d0d193a2e074a19d4d90c67a874d932e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, "nixos-mailserver": { "inputs": { "blobs": "blobs", @@ -123,6 +138,7 @@ "root": { "inputs": { "flake-parts": "flake-parts", + "impermanence": "impermanence", "nixos-mailserver": "nixos-mailserver", "nixpkgs": "nixpkgs", "sops-nix": "sops-nix" diff --git a/flake.nix b/flake.nix index 727dd91..0c61327 100644 --- a/flake.nix +++ b/flake.nix @@ -14,6 +14,9 @@ url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + impermanence = { + url = "github:nix-community/impermanence"; + }; }; outputs = inputs@{ flake-parts, ... }: diff --git a/nixos/flake-module.nix b/nixos/flake-module.nix index ef87e41..8c44964 100644 --- a/nixos/flake-module.nix +++ b/nixos/flake-module.nix @@ -12,6 +12,7 @@ imports = [ (import (./. + "/machines/${name}/configuration.nix") inputs) inputs.sops-nix.nixosModules.sops + inputs.impermanence.nixosModules.impermanence ]; }; in lib.genAttrs machines makeSystem); diff --git a/nixos/modules/impermanence.nix b/nixos/modules/impermanence.nix new file mode 100644 index 0000000..267c9d1 --- /dev/null +++ b/nixos/modules/impermanence.nix @@ -0,0 +1,47 @@ +{lib, config, ...} : + +let + inherit (lib) + mkEnableOption + mkIf + mkOption + types + ; + cfg = config.impermanence; +in + +{ +imports = [ ]; + +options.impermanence = { + enable = mkEnableOption "impermanence"; + storagePath = mkOption { + type = types.path; + default = "/persist"; + description = "The path where persistent data is stored"; + }; + name = mkOption { + type = types.str; + default = "persist"; + description = "the name of the persistent data store"; + }; +}; + +config = mkIf cfg.enable { + environment.persistence.${cfg.name} = { + persistentStoragePath = cfg.storagePath; + directories = [ + "/var/log" + "/var/lib/nixos" + ]; + files = [ + "/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" + ]; + }; + environment.etc.machine-id.source = "${cfg.storagePath}/machine-id"; +}; + +} diff --git a/nixos/roles/default.nix b/nixos/roles/default.nix index 7296a1d..1968de3 100644 --- a/nixos/roles/default.nix +++ b/nixos/roles/default.nix @@ -4,6 +4,7 @@ imports = [ ./admins.nix ./nix_keys.nix (modulesPath + "/virtualisation/xen-domU.nix") + ../modules/impermanence.nix ]; nix = { extraOptions = '' @@ -27,6 +28,8 @@ users = { users.root.hashedPassword = "!"; }; +impermanence.enable = true; + sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; environment = {