config of the Nix machines
Find a file
2023-10-01 11:59:39 +02:00
nixos fixed ssh paths for impermanence 2023-10-01 11:59:39 +02:00
.gitignore Initial commit 2023-06-11 12:59:47 +00:00
.sops.yaml [#5] adding sops support 2023-09-25 21:03:23 +02:00
flake-module.nix added some beginning docu 2023-06-12 12:02:01 +02:00
flake.lock [#9] first impermanence config support 2023-09-30 17:41:22 +02:00
flake.nix [#9] first impermanence config support 2023-09-30 17:41:22 +02:00
LICENSE changed License from GPL to AGPL 2023-06-12 11:42:12 +02:00
README.md added impermanence documentation 2023-10-01 11:54:35 +02:00

nixConfig

Build a machine

Local

If you want to build the machineconfiguration for machine run

nix build .#nixosConfiguration.<name>.config.system.build.toplevel

On the machine

clone this repo to /etc/nixos/ and nixos-rebuild that will select the appropriate machine based on hostname

sops

We are sharing secrets using sops and sops-nix As of right now we use only age keys. The machine keys are derived from their server ssh keys, that they generate at first boot. User keys are generated by the users. New keys and machines need entries into the .sops.yaml file within the root directory of this repo.

To make a secret available on a given machine you need to do the following. Configure the following keys

sops.secrets.example-key = {
  sopsFile = "relative path to file in the repo containing the secrets (optional else the sops.defaultSopsFile is used)
  path = "optinal path where the secret gets symlinked to, practical if some programm expects a specific path"
  owner = user that owns the secret file: config.users.users.nerf.name (for example)
  group = same as user just with groups: config.users.users.nerf.group
  mode = "premission in usual octet: 0400 (for example)"

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 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 = [
    "<your path to a directory to persist>"
  ];
  files = [
    "<your path to a file to persist>"
  ];
};

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, ...} :
<module code >