greenhouse

kore

my public infrastructure monorepo

git clone [email protected]:kore.git

kore / nixos / features / global.nix284 lines · 7312B · 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  wsl = config ? wsl && config.wsl.enable;
7
8  rootDevice = config.fileSystems."/".device;
9  rootUnit = "${utils.escapeSystemdPath rootDevice}.device";
10in {
11  imports = [
12    inputs.impermanence.nixosModules.impermanence
13
14    ( modulesPath + "/profiles/minimal.nix" )
15  ];
16
17  i18n = {
18    defaultLocale = "en_US.UTF-8";
19    supportedLocales = [ "en_US.UTF-8/UTF-8" ];
20  };
21  time.timeZone = lib.mkDefault "UTC";
22
23  nix = {
24    package = pkgs.nixVersions.latest;
25
26    gc = {
27      automatic = true;
28      dates = "daily";
29      options = "--delete-older-than 7d";
30    };
31
32    settings = {
33      keep-outputs = false;
34      keep-derivations = false;
35      auto-optimise-store = true;
36
37      trusted-users = [ "root" "@wheel" ];
38      experimental-features = [ "nix-command" "flakes" ];
39    };
40
41    registry.nixpkgs.to = {
42      type = "github";
43      owner = "NixOS";
44      repo = "nixpkgs";
45      inherit (inputs.nixpkgs) rev narHash;
46    };
47    nixPath = [ "nixpkgs=flake:nixpkgs" ];
48  };
49
50  nixpkgs = {
51    overlays = builtins.attrValues outputs.overlays;
52
53    flake = {
54      setFlakeRegistry = false;
55      setNixPath = false;
56    };
57
58    config = {
59      allowUnfree = lib.mkForce false;
60      allowBroken = lib.mkForce false;
61    };
62  };
63
64  system.tools = {
65    nixos-build-vms.enable = false;
66    nixos-enter.enable = false;
67    nixos-generate-config.enable = false;
68    nixos-install.enable = false;
69    nixos-option.enable = false;
70  };
71
72  networking = {
73    domain = "lostduk.com";
74
75    useDHCP = lib.mkDefault true;
76    enableIPv6 = lib.mkForce false;
77
78    firewall = {
79      enable = lib.mkForce true;
80      allowPing = lib.mkForce false;
81      allowedTCPPorts = [];
82      allowedUDPPorts = [];
83    };
84  };
85
86  networking.dhcpcd.extraConfig = lib.mkIf (!wsl) "nohook resolv.conf";
87
88  services = {
89    pcscd.enable = true;
90
91    resolved = lib.mkIf (!wsl) {
92      enable = true;
93
94      settings.Resolve = {
95        DNS = [
96          "194.242.2.2#dns.mullvad.net"
97          "9.9.9.9#dns.quad9.net"
98          "149.112.112.112#dns.quad9.net"
99        ];
100        FallbackDNS = [];
101        Domains = [ "~." ];
102        DNSOverTLS = true;
103        DNSSEC = false;
104      };
105    };
106
107    openssh = {
108      enable = lib.mkDefault true;
109      settings = {
110        PermitRootLogin = "no";
111        PasswordAuthentication = false;
112        KbdInteractiveAuthentication = false;
113      };
114      hostKeys = [{
115        path = "${lib.optionalString impermanence "/persist"}/etc/ssh/ssh_host_ed25519_key";
116        type = "ed25519";
117      }];
118    };
119  };
120
121  security = {
122    protectKernelImage = true;
123
124    audit = {
125      enable = true;
126      rules = [ "-a exit,always -F arch=b64 -S execve" ];
127    };
128
129    sudo = {
130      execWheelOnly = true;
131      wheelNeedsPassword = lib.mkForce true;
132    };
133
134    auditd.enable = true;
135    pam.sshAgentAuth.enable = true;
136  };
137
138  users = {
139    mutableUsers = lib.mkForce false;
140
141    users.root.hashedPassword = lib.mkForce "!";
142  };
143
144  boot = {
145    kernelParams = [
146      "slab_nomerge"
147      "init_on_alloc=1"
148      "init_on_free=1"
149      "page_alloc.shuffle=1"
150      "randomize_kstack_offset=on"
151      "vsyscall=none"
152      "debugfs=off"
153    ];
154
155    kernel.sysctl = {
156      "kernel.kptr_restrict" = 2;
157      "kernel.dmesg_restrict" = 1;
158      "kernel.printk" = "3 3 3 3";
159      "kernel.unprivileged_bpf_disabled" = 1;
160      "net.core.bpf_jit_harden" = 2;
161      "kernel.yama.ptrace_scope" = 1;
162      "kernel.sysrq" = 0;
163      "kernel.perf_event_paranoid" = 3;
164      "dev.tty.ldisc_autoload" = 0;
165      "vm.unprivileged_userfaultfd" = 0;
166      "fs.suid_dumpable" = 0;
167      "fs.protected_fifos" = 2;
168      "fs.protected_regular" = 2;
169      "fs.protected_symlinks" = 1;
170      "fs.protected_hardlinks" = 1;
171
172      "net.ipv4.tcp_syncookies" = 1;
173      "net.ipv4.tcp_rfc1337" = 1;
174      "net.ipv4.conf.all.rp_filter" = 1;
175      "net.ipv4.conf.default.rp_filter" = 1;
176      "net.ipv4.conf.all.accept_redirects" = 0;
177      "net.ipv4.conf.default.accept_redirects" = 0;
178      "net.ipv4.conf.all.secure_redirects" = 0;
179      "net.ipv4.conf.default.secure_redirects" = 0;
180      "net.ipv4.conf.all.send_redirects" = 0;
181      "net.ipv4.conf.default.send_redirects" = 0;
182      "net.ipv4.conf.all.accept_source_route" = 0;
183      "net.ipv4.conf.default.accept_source_route" = 0;
184      "net.ipv4.icmp_echo_ignore_broadcasts" = 1;
185    };
186
187    blacklistedKernelModules = [
188      "dccp" "sctp" "rds" "tipc" "n-hdlc" "ax25" "netrom" "x25" "rose"
189      "decnet" "econet" "af_802154" "ipx" "appletalk" "psnap" "p8023"
190      "p8022" "can" "atm"
191      "cramfs" "freevxfs" "jffs2" "hfs" "hfsplus"
192      "firewire-core" "thunderbolt" "vivid"
193    ];
194  };
195
196  systemd.coredump.settings.Coredump = {
197    Storage = "none";
198    ProcessSizeMax = 0;
199  };
200
201  environment = {
202    defaultPackages = lib.mkForce [];
203
204    etc = lib.mkIf (!config.services.openssh.enable) (lib.mapAttrs' (name: user:
205      lib.nameValuePair "ssh/authorized_keys.d/${name}" {
206        mode = "0444";
207        text = lib.concatLines user.openssh.authorizedKeys.keys;
208      }) (lib.filterAttrs (_: user: user.openssh.authorizedKeys.keys != []) config.users.users));
209
210    persistence."/persist" = {
211      enable = impermanence;
212      hideMounts = false;
213
214      directories = [
215        "/srv"
216        "/var/log"
217        "/var/lib/nixos"
218        "/var/lib/systemd"
219      ];
220    };
221  };
222
223  programs.nano.enable = false;
224
225  fileSystems = lib.mkIf impermanence {
226    "/persist".neededForBoot = true;
227  };
228
229  system.activationScripts.persistent-dirs = lib.mkIf impermanence {
230    deps = [ "users" ];
231    text =
232      let
233        mkHomePersist = user: lib.optionalString user.createHome ''
234          mkdir -p /persist${user.home}
235          chown ${user.name}:${user.group} /persist${user.home}
236          chmod ${user.homeMode} /persist${user.home}
237        '';
238      in
239        lib.concatLines (map mkHomePersist (lib.attrValues config.users.users));
240  };
241
242  assertions = [{
243    assertion = rollback -> config.boot.initrd.systemd.enable;
244    message = "kore: root rollback needs boot.initrd.systemd.enable";
245  }];
246
247  boot.initrd = lib.mkIf rollback {
248    supportedFilesystems = [ "btrfs" ];
249
250    systemd.services.wipe-root = {
251      wantedBy = [ "initrd.target" ];
252      requires = [ rootUnit ];
253      after = [ rootUnit ];
254      before = [ "sysroot.mount" ];
255      unitConfig.DefaultDependencies = "no";
256      serviceConfig = {
257        Type = "oneshot";
258        RemainAfterExit = true;
259      };
260      script = ''
261        mkdir -p /tmp
262        MNTPOINT=$(mktemp -d)
263        (
264          mount ${rootDevice} "$MNTPOINT"
265          trap 'umount "$MNTPOINT"' EXIT
266
267          if [[ -e $MNTPOINT/@ ]]; then
268            echo "Backing up root..."
269            mkdir -p $MNTPOINT/old_roots
270            mv "$MNTPOINT/@" "$MNTPOINT/old_roots/@_$(date "+%Y-%m-%-d_%H:%M:%S")"
271          fi
272
273          echo "Deleting 7+ days old roots..."
274          find "$MNTPOINT/old_roots" -mindepth 1 -maxdepth 1 \
275            -mtime +7 \
276            -exec btrfs sub del -R {} +
277
278          echo "Creating new root..."
279          btrfs sub cre "$MNTPOINT/@"
280        )
281      '';
282    };
283  };
284}