From 88f6014fc4a403f0f2c9b40e37d3b114c4972882 Mon Sep 17 00:00:00 2001 From: Dennis Frieberg Date: Thu, 28 Sep 2023 17:12:34 +0200 Subject: [PATCH 1/6] [#9] first impermanence config support --- flake.lock | 16 +++++++++++++ flake.nix | 3 +++ nixos/flake-module.nix | 1 + nixos/modules/impermanence.nix | 42 ++++++++++++++++++++++++++++++++++ nixos/roles/default.nix | 30 +++++++++++++++++++++++- 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 nixos/modules/impermanence.nix 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..0f955fd --- /dev/null +++ b/nixos/modules/impermanence.nix @@ -0,0 +1,42 @@ +{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/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" + "/etc/ssh" + "/var/lib/nixos" + ]; + }; + environment.etc.machine-id.source = "${cfg.storagePath}/machine-id"; +}; + +} diff --git a/nixos/roles/default.nix b/nixos/roles/default.nix index 3c24242..adf1200 100644 --- a/nixos/roles/default.nix +++ b/nixos/roles/default.nix @@ -1,4 +1,32 @@ -{ ... } : { +{pkgs, config, lib, ...} : { + +imports = [ + ./admins.nix + ./nix_keys.nix + ../modules/impermanence.nix + ]; +nix = { + extraOptions = '' + experimental-features = nix-command flakes + builders-use-substitutes = true + ''; +}; + +networking = { + firewall = { # these shoud be default, but better make sure! + enable = true; + allowPing = true; + }; + nftables.enable = true; + useDHCP = false; # We don't speak DHCP and even if we would, we should enable it per interface + # hosts = # TODO write something to autogenerate ip adresses! +}; + +users = { + mutableUsers = false; +}; + +impermanence.enable = true; sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; } From 1639b071d857ba84c5eb089a7d0a1e9a61a9f8e0 Mon Sep 17 00:00:00 2001 From: Dennis Frieberg Date: Thu, 28 Sep 2023 23:34:34 +0200 Subject: [PATCH 2/6] changed impermanence config for subvolumes --- nixos/modules/impermanence.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/impermanence.nix b/nixos/modules/impermanence.nix index 0f955fd..9fe8998 100644 --- a/nixos/modules/impermanence.nix +++ b/nixos/modules/impermanence.nix @@ -17,7 +17,7 @@ options.impermanence = { enable = mkEnableOption "impermanence"; storagePath = mkOption { type = types.path; - default = "/persist/persist"; + default = "/persist"; description = "The path where persistent data is stored"; }; name = mkOption { From 94966307f7f85422cf11585e8c5ff24bf7d04a23 Mon Sep 17 00:00:00 2001 From: Dennis Frieberg Date: Sun, 1 Oct 2023 11:54:35 +0200 Subject: [PATCH 3/6] added impermanence documentation --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/README.md b/README.md index 44e28aa..c1b896e 100644 --- a/README.md +++ b/README.md @@ -36,3 +36,46 @@ If the accessing process is not root it must be member of the group `config.user for systemd services this can be archived by setting `serviceConfig.SupplementaryGroups = [ config.users.groups.keys.name ];` it the service config. +## 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 don'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, ...} : + +``` + From 3d9fb42fd4abf51eddb307622f304556473bcea2 Mon Sep 17 00:00:00 2001 From: Dennis Frieberg Date: Sat, 30 Sep 2023 15:07:12 +0200 Subject: [PATCH 4/6] fixed ssh paths for impermanence --- nixos/modules/impermanence.nix | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nixos/modules/impermanence.nix b/nixos/modules/impermanence.nix index 9fe8998..267c9d1 100644 --- a/nixos/modules/impermanence.nix +++ b/nixos/modules/impermanence.nix @@ -32,9 +32,14 @@ config = mkIf cfg.enable { persistentStoragePath = cfg.storagePath; directories = [ "/var/log" - "/etc/ssh" "/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"; }; From 71c5d34cdbe1ce8b039a21fdf8dfb648d1d48dc6 Mon Sep 17 00:00:00 2001 From: Dennis Frieberg Date: Mon, 2 Oct 2023 11:55:55 +0200 Subject: [PATCH 5/6] Fixed typo in README.md in curtosy of Gonne see [#13] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1b896e..2e335a9 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ If you keep your application data (like recommended) on a separate partition, th 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 don't want to manage that with +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 From fb002f7c829f2bf3ce878f139b5450bcf7c0d1e4 Mon Sep 17 00:00:00 2001 From: Dennis Frieberg Date: Wed, 4 Oct 2023 23:42:17 +0200 Subject: [PATCH 6/6] Fixed a comma Gonne found [#13] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e335a9..69119a7 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ some default files to bind mount (ssh keys, machine-id some nixos specific thing 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 +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).