greenhouse

kore

my public infrastructure monorepo

git clone [email protected]:kore.git

kore / nixos / features / global.nix195 lines · 4582B · raw

1{ inputs, outputs, config, lib, pkgs, utils, modulesPath, ... }:
2
3# Policy for every host. Values under mkForce are invariants: roles and
4# hosts must not weaken them.
5let
6  impermanence = config.kore.impermanence.enable;
7  rollback = impermanence && config ? disko && config.disko.devices.disk ? main;
8
9  rootDevice = config.fileSystems."/".device;
10  rootUnit = "${utils.escapeSystemdPath rootDevice}.device";
11in {
12  imports = [
13    inputs.impermanence.nixosModules.impermanence
14
15    ( modulesPath + "/profiles/minimal.nix" )
16  ];
17
18  i18n = {
19    defaultLocale = "en_US.UTF-8";
20    supportedLocales = [ "en_US.UTF-8/UTF-8" ];
21  };
22  time.timeZone = "UTC";
23
24  nix = {
25    package = pkgs.nixVersions.latest;
26
27    gc = {
28      automatic = true;
29      dates = "daily";
30      options = "--delete-older-than 7d";
31    };
32
33    settings = {
34      keep-outputs = false;
35      keep-derivations = false;
36      auto-optimise-store = true;
37
38      trusted-users = [ "root" "@wheel" ];
39      experimental-features = [ "nix-command" "flakes" ];
40    };
41  };
42
43  nixpkgs = {
44    overlays = builtins.attrValues outputs.overlays;
45
46    flake = {
47      setFlakeRegistry = false;
48      setNixPath = false;
49    };
50
51    config = {
52      allowUnfree = lib.mkForce false;
53      allowBroken = lib.mkForce false;
54    };
55  };
56
57  system.tools = {
58    nixos-build-vms.enable = false;
59    nixos-enter.enable = false;
60    nixos-generate-config.enable = false;
61    nixos-install.enable = false;
62    nixos-option.enable = false;
63  };
64
65  networking = {
66    domain = "lostduk.com";
67
68    useDHCP = true;
69    enableIPv6 = lib.mkForce false;
70
71    firewall = {
72      enable = lib.mkForce true;
73      allowPing = lib.mkForce false;
74      allowedTCPPorts = [];
75      allowedUDPPorts = [];
76    };
77  };
78
79  services = {
80    pcscd.enable = true;
81
82    openssh = {
83      enable = true;
84      settings = {
85        PermitRootLogin = "no";
86        PasswordAuthentication = false;
87        KbdInteractiveAuthentication = false;
88      };
89      hostKeys = [{
90        path = "${lib.optionalString impermanence "/persist"}/etc/ssh/ssh_host_ed25519_key";
91        type = "ed25519";
92      }];
93    };
94  };
95
96  security = {
97    protectKernelImage = true;
98
99    audit = {
100      enable = true;
101      rules = [ "-a exit,always -F arch=b64 -S execve" ];
102    };
103
104    sudo = {
105      execWheelOnly = true;
106      wheelNeedsPassword = lib.mkForce true;
107    };
108
109    auditd.enable = true;
110    pam.sshAgentAuth.enable = true;
111  };
112
113  users = {
114    mutableUsers = lib.mkForce false;
115
116    users.root.hashedPassword = lib.mkForce "!";
117  };
118
119  environment = {
120    defaultPackages = lib.mkForce [];
121
122    persistence."/persist" = {
123      enable = impermanence;
124      hideMounts = false;
125
126      directories = [
127        "/srv"
128        "/var/lib/nixos"
129        "/var/lib/systemd"
130      ];
131    };
132  };
133
134  programs.nano.enable = false;
135
136  fileSystems = lib.mkIf impermanence {
137    "/persist".neededForBoot = true;
138  };
139
140  system.activationScripts.persistent-dirs = lib.mkIf impermanence {
141    deps = [ "users" ];
142    text =
143      let
144        mkHomePersist = user: lib.optionalString user.createHome ''
145          mkdir -p /persist${user.home}
146          chown ${user.name}:${user.group} /persist${user.home}
147          chmod ${user.homeMode} /persist${user.home}
148        '';
149      in
150        lib.concatLines (map mkHomePersist (lib.attrValues config.users.users));
151  };
152
153  assertions = [{
154    assertion = rollback -> config.boot.initrd.systemd.enable;
155    message = "kore: root rollback needs boot.initrd.systemd.enable";
156  }];
157
158  boot.initrd = lib.mkIf rollback {
159    supportedFilesystems = [ "btrfs" ];
160
161    systemd.services.wipe-root = {
162      wantedBy = [ "initrd.target" ];
163      requires = [ rootUnit ];
164      after = [ rootUnit ];
165      before = [ "sysroot.mount" ];
166      unitConfig.DefaultDependencies = "no";
167      serviceConfig = {
168        Type = "oneshot";
169        RemainAfterExit = true;
170      };
171      script = ''
172        mkdir -p /tmp
173        MNTPOINT=$(mktemp -d)
174        (
175          mount ${rootDevice} "$MNTPOINT"
176          trap 'umount "$MNTPOINT"' EXIT
177
178          if [[ -e $MNTPOINT/@ ]]; then
179            echo "Backing up root..."
180            mkdir -p $MNTPOINT/old_roots
181            mv "$MNTPOINT/@" "$MNTPOINT/old_roots/@_$(date "+%Y-%m-%-d_%H:%M:%S")"
182          fi
183
184          echo "Deleting 7+ days old roots..."
185          find "$MNTPOINT/old_roots" -mindepth 1 -maxdepth 1 \
186            -mtime +7 \
187            -exec btrfs sub del -R {} +
188
189          echo "Creating new root..."
190          btrfs sub cre "$MNTPOINT/@"
191        )
192      '';
193    };
194  };
195}