greenhouse

kore

my public infrastructure monorepo

git clone [email protected]:kore.git

kore / nixos / features / global.nix193 lines · 4494B · raw

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