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}