summaryrefslogtreecommitdiff
path: root/hosts/skadhi
diff options
context:
space:
mode:
Diffstat (limited to 'hosts/skadhi')
-rw-r--r--hosts/skadhi/default.nix118
-rw-r--r--hosts/skadhi/fs.nix84
-rw-r--r--hosts/skadhi/hw.nix20
-rw-r--r--hosts/skadhi/networking/default.nix38
-rw-r--r--hosts/skadhi/networking/ruleset.nft223
5 files changed, 483 insertions, 0 deletions
diff --git a/hosts/skadhi/default.nix b/hosts/skadhi/default.nix
new file mode 100644
index 00000000..cf25777b
--- /dev/null
+++ b/hosts/skadhi/default.nix
@@ -0,0 +1,118 @@
1{ flake, flakeInputs, pkgs, config, lib, ... }:
2{
3 imports = with flake.nixosModules.systemProfiles; [
4 ./hw.nix ./fs.nix ./networking
5 tmpfs-root default-locale openssh lanzaboote zswap initrd-all-crypto-modules
6 ];
7
8 config = {
9 system.stateVersion = "26.05";
10
11 boot = {
12 initrd = {
13 systemd = {
14 emergencyAccess = config.users.users.root.hashedPassword;
15 extraBin = {
16 "vim" = lib.getExe pkgs.vim;
17 "grep" = lib.getExe pkgs.gnugrep;
18 };
19 };
20
21 kernelModules = [ "dm-integrity" ];
22 };
23
24 lanzaboote.configurationLimit = 15;
25 loader = {
26 efi.canTouchEfiVariables = true;
27 timeout = null;
28 };
29
30 plymouth.enable = true;
31
32 kernelPackages = pkgs.linuxPackages_7_2;
33 consoleLogLevel = 3;
34 kernelParams = [
35 "quiet"
36 "boot.shell_on_fail"
37 "udev.log_priority=3"
38 "rd.systemd.show_status=auto"
39 "plymouth.use-simpledrm"
40 ];
41
42 tmp.useTmpfs = true;
43 };
44
45 services.timesyncd.enable = false;
46 services.chrony = {
47 enable = true;
48 enableNTS = true;
49 servers = [];
50 extraConfig = ''
51 pool time.cloudflare.com iburst nts
52 pool nts.netnod.se prefer iburst nts
53 server ptbtime1.ptb.de prefer iburst nts
54 server ptbtime2.ptb.de prefer iburst nts
55 server ptbtime3.ptb.de prefer iburst nts
56 server ptbtime4.ptb.de prefer iburst nts
57 pool ntppool1.time.nl prefer iburst nts
58 pool ntppool2.time.nl prefer iburst nts
59
60 authselectmode require
61 minsources 3
62
63 nocerttimecheck 1
64
65 leapsectz right/UTC
66
67 makestep 0.1 3
68
69 cmdport 0
70 '';
71 };
72
73 services.userborn.importLegacyState = false;
74
75 services.kmscon = {
76 enable = true;
77 config.hwaccel = true;
78 };
79
80 environment.persistence."/persistent".timezone = true;
81 time.timeZone = null;
82 systemd.tmpfiles.settings = {
83 "10-localtime"."/etc/localtime".L.argument = "/persistent/etc/localtime";
84 };
85
86 services.openssh.enable = true;
87
88 services.logind.settings.Login = {
89 HandleLidSwitch = "sleep";
90 HandleLidSwitchExternalPower = "ignore";
91 };
92
93 systemd.timers.nix-gc = lib.mkForce {
94 timerConfig = {
95 RandomizedDelaySec = "12h";
96 Persistent = true;
97 OnCalendar = "*-*-* 18:00:00 Europe/Berlin";
98 };
99 wantedBy = [ "timers.target" ];
100 };
101 systemd.services.nix-gc = lib.mkForce {
102 description = "Nix Garbage Collector";
103 serviceConfig = {
104 Type = "oneshot";
105 ExecStart = pkgs.resholve.writeScript "nix-gc" {
106 interpreter = lib.getExe pkgs.zsh;
107 inputs = [ pkgs.coreutils config.nix.package ];
108 execer = [ "cannot:${lib.getExe' config.nix.package "nix-collect-garbage"}" ];
109 } ''
110 max_size=$(($(du -bs /nix/store | cut -f 1) - 1024**4))
111 [[ $max_size -gt 0 ]] || exit 0
112 exec nix-collect-garbage -vv --max-freed $max_size --delete-older-than 30d
113 '';
114 };
115 restartIfChanged = false;
116 };
117 };
118}
diff --git a/hosts/skadhi/fs.nix b/hosts/skadhi/fs.nix
new file mode 100644
index 00000000..1c423afa
--- /dev/null
+++ b/hosts/skadhi/fs.nix
@@ -0,0 +1,84 @@
1{ flake, flakeInputs, pkgs, config, lib, ... }:
2{
3 imports = with flake.nixosModules.systemProfiles; [
4 disko
5 ];
6
7 config = {
8 fileSystems."/persistent".neededForBoot = true;
9 environment.persistence."/persistent" = {
10 hideMounts = true;
11 directories = [
12 "/nix"
13 "/root"
14 "/var/log"
15 "/var/lib/nixos"
16 "/var/lib/sops-nix"
17 "/var/lib/systemd"
18 "/var/lib/fprintd"
19 config.boot.lanzaboote.pkiBundle
20 ];
21 };
22
23 disko.devices = {
24 disk.nvm = {
25 type = "disk";
26 device = "/dev/nvme0n1";
27 content = {
28 type = "gpt";
29 partitions = {
30 ESP = {
31 size = "512M";
32 type = "EF00";
33 content = {
34 type = "filesystem";
35 format = "vfat";
36 mountpoint = "/boot";
37 mountOptions = [
38 "fmask=0033" "dmask=0022"
39 ];
40 };
41 };
42 luks = {
43 size = "100%";
44 content = {
45 type = "luks";
46 name = "nvm";
47 extraFormatArgs = [
48 "--cipher" "aegis128-random"
49 "--key-size" "128"
50 "--integrity" "aead"
51 ];
52 content = {
53 type = "btrfs";
54 extraArgs = let
55 dirs = map (p: "/persistent/${p}") ["/etc"];
56 subvols = ["/persistent"] ++ map (p: "/persistent/${p}") ["/nix" "/var/log"];
57 restricted = map (p: "/persistent/${p}") ["/root"];
58 in [
59 "--csum" "blake2"
60 "--compress" "zstd:15"
61 "--rootdir" (toString (pkgs.runCommand "rootdir" {
62 } ''
63 mkdir $out
64 install -d ${lib.concatMapStringsSep " " (p: "$out/${p}") (dirs ++ subvols)}
65 install -m 0700 -d ${lib.concatMapStringsSep " " (p: "$out/${p}") restricted}
66 ln -s /etc/zoneinfo/UTC /persistent/etc/localtime
67 ''))
68 ] ++ lib.concatMap (p: ["--subvol" p]) (subvols ++ restricted);
69 subvolumes = {
70 "/persistent".mountpoint = "/persistent";
71 "/swap" = {
72 mountpoint = "/.swap";
73 swap.swapfile.size = "96G";
74 };
75 };
76 };
77 };
78 };
79 };
80 };
81 };
82 };
83 };
84}
diff --git a/hosts/skadhi/hw.nix b/hosts/skadhi/hw.nix
new file mode 100644
index 00000000..687f04d8
--- /dev/null
+++ b/hosts/skadhi/hw.nix
@@ -0,0 +1,20 @@
1{ flake, flakeInputs, pkgs, config, lib, ... }:
2{
3 imports = [
4 flakeInputs.nixos-hardware.nixosModules.framework-13-7040-amd
5 ];
6
7 config = {
8 hardware.framework.laptop13.audioEnhancement.enable = false;
9 hardware.enableRedistributableFirmware = true;
10 services.fstrim.enable = false;
11
12 services.udev.extraRules = ''
13 ACTION=="add", SUBSYSTEM=="platform", DRIVER=="acpi-button", KERNEL=="PNP0C0D:00", ATTR{power/wakeup}="disabled"
14 ACTION=="add", SUBSYSTEM=="serio", DRIVERS=="atkbd", ATTR{power/wakeup}="disabled"
15 ACTION=="add", SUBSYSTEM=="i2c", DRIVERS=="i2c_hid_acpi", ATTRS{name}=="PIXA3854:00", ATTR{power/wakeup}="disabled"
16 '';
17
18 nixpkgs.system = "x86_64-linux";
19 };
20}
diff --git a/hosts/skadhi/networking/default.nix b/hosts/skadhi/networking/default.nix
new file mode 100644
index 00000000..4d6edd97
--- /dev/null
+++ b/hosts/skadhi/networking/default.nix
@@ -0,0 +1,38 @@
1{ flake, config, ... }:
2{
3 imports = with flake.nixosModules.systemProfiles; [
4 networkmanager
5 ];
6
7 config = {
8 environment.persistence."/persistent".directories = [
9 "/etc/NetworkManager/system-connections"
10 ];
11
12 networking = {
13 domain = "yggdrasil";
14 search = [ "yggdrasil" ];
15 hosts = {
16 "127.0.0.1" = [ "${config.networking.hostName}.yggdrasil" config.networking.hostName ];
17 "::1" = [ "${config.networking.hostName}.yggdrasil" config.networking.hostName ];
18 };
19
20 firewall.enable = false;
21 nftables = {
22 enable = true;
23 rulesetFile = ./ruleset.nft;
24 };
25
26 useDHCP = false;
27 useNetworkd = true;
28 };
29
30 environment.etc."NetworkManager/dnsmasq.d/yggdrasil.conf" = {
31 text = ''
32 server=/yggdrasil/2a03:4000:52:ada:1:1::@yggdrasil
33 server=/141.10.in-addr.arpa/2a03:4000:52:ada:1:1::@yggdrasil
34 server=/1.0.0.0.a.d.a.0.2.5.0.0.0.0.0.4.3.0.a.2.ip6.arpa/2a03:4000:52:ada:1:1::@yggdrasil
35 '';
36 };
37 };
38}
diff --git a/hosts/skadhi/networking/ruleset.nft b/hosts/skadhi/networking/ruleset.nft
new file mode 100644
index 00000000..62339f69
--- /dev/null
+++ b/hosts/skadhi/networking/ruleset.nft
@@ -0,0 +1,223 @@
1define icmp_protos = { ipv6-icmp, icmp, igmp }
2
3table arp filter {
4 limit lim_arp {
5 rate over 50 mbytes/second burst 50 mbytes
6 }
7
8 counter arp-rx {}
9 counter arp-tx {}
10
11 counter arp-ratelimit-rx {}
12 counter arp-ratelimit-tx {}
13
14 chain input {
15 type filter hook input priority filter
16 policy accept
17
18 limit name lim_arp counter name arp-ratelimit-rx drop
19
20 counter name arp-rx
21 }
22
23 chain output {
24 type filter hook output priority filter
25 policy accept
26
27 limit name lim_arp counter name arp-ratelimit-tx drop
28
29 counter name arp-tx
30 }
31}
32
33table inet filter {
34 limit lim_reject {
35 rate over 1000/second burst 1000 packets
36 }
37
38 limit lim_icmp {
39 rate over 50 mbytes/second burst 50 mbytes
40 }
41
42 counter invalid-fw {}
43
44 counter fw-lo {}
45
46 counter reject-ratelimit-fw {}
47 counter reject-fw {}
48 counter reject-tcp-fw {}
49 counter reject-icmp-fw {}
50
51
52 counter invalid-rx {}
53 counter rx-lo {}
54 counter invalid-local4-rx {}
55 counter invalid-local6-rx {}
56
57 counter icmp-ratelimit-rx {}
58 counter icmp-rx {}
59
60 counter ssh-rx {}
61 counter mosh-rx {}
62 counter wg-rx {}
63 counter yggdrasil-gre-rx {}
64 counter miniserve-rx {}
65 counter ausweisapp2-rx {}
66
67 counter established-rx {}
68
69 counter reject-ratelimit-rx {}
70 counter reject-rx {}
71 counter reject-tcp-rx {}
72 counter reject-icmp-rx {}
73
74
75 counter tx-lo {}
76
77 counter icmp-ratelimit-tx {}
78 counter icmp-tx {}
79
80 counter ssh-tx {}
81 counter mosh-tx {}
82 counter wg-tx {}
83 counter yggdrasil-gre-tx {}
84 counter miniserve-tx {}
85
86 counter tx {}
87
88 counter fw-libvirt {}
89 counter libvirt-dhcp {}
90 counter libvirt-dns {}
91
92
93 chain forward_tmp {}
94 chain forward {
95 type filter hook forward priority filter
96 policy drop
97
98
99 ct state invalid log level debug prefix "drop invalid forward: " counter name invalid-fw drop
100
101
102 iifname lo counter name fw-lo accept
103
104 jump forward_tmp
105
106 iifname virbr0 oifname != {lo, wgrz, yggdrasil-wg-4, yggdrasil-wg-6, yggdrasil, ip6tnl, ip6gre, yggre-surtr-6, yggre-surtr-4, yggre-vidhar-4} counter name fw-libvirt accept
107 oifname virbr0 ct state {established, related} counter name fw-libvirt accept
108
109
110 limit name lim_reject log level debug prefix "drop forward: " counter name reject-ratelimit-fw drop
111 log level debug prefix "reject forward: " counter name reject-fw
112 meta l4proto tcp ct state new counter name reject-tcp-fw reject with tcp reset
113 ct state new counter name reject-icmp-fw reject
114 }
115
116 chain input_tmp {}
117 chain input {
118 type filter hook input priority filter
119 policy drop
120
121
122 ct state invalid log level debug prefix "drop invalid input: " counter name invalid-rx drop
123
124
125 iifname lo counter name rx-lo accept
126 iif != lo ip daddr 127.0.0.1/8 counter name invalid-local4-rx reject
127 iif != lo ip6 daddr ::1/128 counter name invalid-local6-rx reject
128
129 meta l4proto $icmp_protos limit name lim_icmp counter name icmp-ratelimit-rx drop
130 meta l4proto $icmp_protos counter name icmp-rx accept
131
132 jump input_tmp
133
134 tcp dport 22 counter name ssh-rx accept
135 udp dport 60000-61000 counter name mosh-rx accept
136
137 tcp dport 8080 counter name miniserve-rx accept
138 udp dport 24727 counter name ausweisapp2-rx accept
139
140 udp dport 51820-51822 counter name wg-rx accept
141 iifname "yggdrasil-wg-*" meta l4proto gre counter name yggdrasil-gre-rx accept
142
143 iifname virbr0 udp dport 67 counter name libvirt-dhcp accept
144 iifname virbr0 udp dport 547 counter name libvirt-dhcp accept
145 iifname virbr0 udp dport 53 counter name libvirt-dns accept
146 iifname virbr0 tcp dport 53 counter name libvirt-dns accept
147
148 iifname wgrz ip saddr 10.200.116.1 meta l4proto gre counter accept
149
150 ct state {established, related} counter name established-rx accept
151
152
153 limit name lim_reject log level debug prefix "drop input: " counter name reject-ratelimit-rx drop
154 log level debug prefix "reject input: " counter name reject-rx
155 meta l4proto tcp ct state new counter name reject-tcp-rx reject with tcp reset
156 ct state new counter name reject-icmp-rx reject
157 }
158
159 chain output {
160 type filter hook output priority filter
161 policy accept
162
163
164 oifname lo counter name tx-lo accept
165
166 meta l4proto $icmp_protos limit name lim_icmp counter name icmp-ratelimit-tx drop
167 meta l4proto $icmp_protos counter name icmp-tx accept
168
169
170 tcp sport 22 counter name ssh-tx
171 udp sport 60000-61000 counter name mosh-tx
172
173 udp sport 51820-51822 counter name wg-tx
174 iifname "yggdrasil-wg-*" meta l4proto gre counter name yggdrasil-gre-tx
175
176 tcp sport 8080 counter name miniserve-tx accept
177
178 oifname virbr0 udp sport 67 counter name libvirt-dhcp accept
179 oifname virbr0 udp sport 547 counter name libvirt-dhcp accept
180 oifname virbr0 udp sport 53 counter name libvirt-dns accept
181 oifname virbr0 tcp sport 53 counter name libvirt-dns accept
182
183
184 counter name tx
185 }
186}
187
188table ip nat {
189 counter libvirt-nat {}
190
191 chain postrouting_tmp {}
192 chain postrouting {
193 type nat hook postrouting priority srcnat
194 policy accept
195
196 iifname virbr0 oifname != virbr0 counter name libvirt-nat masquerade
197 jump postrouting_tmp
198 }
199}
200
201table ip6 nat {
202 counter libvirt-nat {}
203
204 chain postrouting {
205 type nat hook postrouting priority srcnat
206 policy accept
207
208 iifname virbr0 oifname != virbr0 counter name libvirt-nat masquerade
209 }
210}
211
212table ip mss_clamp {
213 counter libvirt-mss-clamp {}
214
215 chain postrouting_tmp {}
216 chain postrouting {
217 type filter hook postrouting priority mangle
218 policy accept
219
220 iifname virbr0 oifname != virbr0 tcp flags & (syn|rst) == syn counter name libvirt-mss-clamp tcp option maxseg size set rt mtu
221 jump postrouting_tmp
222 }
223}