summaryrefslogtreecommitdiff
path: root/hosts/vidhar/network/dhcp
diff options
context:
space:
mode:
Diffstat (limited to 'hosts/vidhar/network/dhcp')
-rw-r--r--hosts/vidhar/network/dhcp/default.nix274
-rw-r--r--hosts/vidhar/network/dhcp/knot-tsig (renamed from hosts/vidhar/network/dhcp/knot-tsig.json.frag)18
2 files changed, 197 insertions, 95 deletions
diff --git a/hosts/vidhar/network/dhcp/default.nix b/hosts/vidhar/network/dhcp/default.nix
index 07a83351..e4c3f16e 100644
--- a/hosts/vidhar/network/dhcp/default.nix
+++ b/hosts/vidhar/network/dhcp/default.nix
@@ -1,8 +1,33 @@
1{ flake, config, pkgs, lib, ... }: 1{ flake, config, pkgs, lib, sources, ... }:
2 2
3with lib; 3with lib;
4 4
5{ 5let
6 nfsrootBaseUrl = "http://nfsroot.vidhar.yggdrasil";
7 tftpIp = "10.141.0.1";
8 nfsIp = tftpIp;
9 ipxe = pkgs.ipxe.override {
10 additionalTargets = {
11 "bin-i386-efi/ipxe.efi" = "i386-ipxe.efi";
12 };
13 additionalOptions = [
14 "NSLOOKUP_CMD"
15 "PING_CMD"
16 "CONSOLE_CMD"
17 ];
18 embedScript = pkgs.writeText "yggdrasil.ipxe" ''
19 #!ipxe
20
21 cpair --background 9 1
22 cpair --background 9 3
23 cpair --background 9 6
24
25 set user-class iPXE-yggdrasil
26
27 autoboot
28 '';
29 };
30in {
6 config = { 31 config = {
7 services.kea = { 32 services.kea = {
8 dhcp4 = { 33 dhcp4 = {
@@ -23,41 +48,67 @@ with lib;
23 }; 48 };
24 49
25 client-classes = [ 50 client-classes = [
26 { name = "eostre-ipxe"; 51 # { name = "ipxe-eostre";
27 test = "hexstring(pkt4.mac, ':') == '00:d8:61:79:c5:40' and option[77].hex == 'iPXE'"; 52 # test = "hexstring(pkt4.mac, ':') == '00:d8:61:79:c5:40' and option[77].hex == 'iPXE-yggdrasil'";
28 next-server = "10.141.0.1"; 53 # next-server = tftpIp;
29 boot-file-name = "http://nfsroot.vidhar.yggdrasil/eostre/netboot.ipxe"; 54 # boot-file-name = "${nfsrootBaseUrl}/eostre.menu.ipxe";
55 # only-if-required = true;
56 # }
57 { name = "ipxe-yggdrasil";
58 test = "option[77].hex == 'iPXE-yggdrasil'";
59 next-server = tftpIp;
60 boot-file-name = "${nfsrootBaseUrl}/installer-x86_64-linux.menu.ipxe";
61 only-if-required = true;
62 }
63
64 { name = "uefi-http";
65 test = "option[client-system].hex == 0x0010";
66 option-data = [
67 { name = "vendor-class-identifier"; data = "HTTPClient"; }
68 ];
69 boot-file-name = "${nfsrootBaseUrl}/ipxe.efi";
70 only-if-required = true;
71 }
72
73 { name = "ipxe-uefi-64";
74 test = "option[77].hex == 'iPXE' and (substring(option[60].hex,0,20) == 'PXEClient:Arch:00007' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00008' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00009')";
75 boot-file-name = "${nfsrootBaseUrl}/ipxe.efi";
76 only-if-required = true;
77 }
78 { name = "ipxe-uefi-32";
79 test = "option[77].hex == 'iPXE' and (substring(option[60].hex,0,20) == 'PXEClient:Arch:00002' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00006')";
80 boot-file-name = "${nfsrootBaseUrl}/i386-ipxe.efi";
30 only-if-required = true; 81 only-if-required = true;
31 } 82 }
32 { name = "ipxe"; 83 { name = "ipxe-legacy";
33 test = "option[77].hex == 'iPXE'"; 84 test = "option[77].hex == 'iPXE' and substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'";
34 next-server = "10.141.0.1"; 85 boot-file-name = "${nfsrootBaseUrl}/ipxe.lkrn";
35 boot-file-name = "http://nfsroot.vidhar.yggdrasil/installer-x86_64-linux/netboot.ipxe";
36 only-if-required = true; 86 only-if-required = true;
37 } 87 }
88
38 { name = "uefi-64"; 89 { name = "uefi-64";
39 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00007' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00008' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00009'"; 90 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00007' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00008' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00009'";
40 only-if-required = true;
41 option-data = [ 91 option-data = [
42 { name = "tftp-server-name"; data = "10.141.0.1"; } 92 { name = "tftp-server-name"; data = tftpIp; }
43 ]; 93 ];
44 boot-file-name = "ipxe.efi"; 94 boot-file-name = "ipxe.efi";
95 only-if-required = true;
45 } 96 }
46 { name = "uefi-32"; 97 { name = "uefi-32";
47 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00002' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00006'"; 98 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00002' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00006'";
48 only-if-required = true;
49 option-data = [ 99 option-data = [
50 { name = "tftp-server-name"; data = "10.141.0.1"; } 100 { name = "tftp-server-name"; data = tftpIp; }
51 ]; 101 ];
52 boot-file-name = "i386-ipxe.efi"; 102 boot-file-name = "i386-ipxe.efi";
103 only-if-required = true;
53 } 104 }
54 { name = "legacy"; 105 { name = "legacy";
55 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'"; 106 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'";
56 only-if-required = true;
57 option-data = [ 107 option-data = [
58 { name = "tftp-server-name"; data = "10.141.0.1"; } 108 { name = "tftp-server-name"; data = tftpIp; }
59 ]; 109 ];
60 boot-file-name = "undionly.kpxe"; 110 boot-file-name = "ipxe.lkrn";
111 only-if-required = true;
61 } 112 }
62 ]; 113 ];
63 114
@@ -205,40 +256,27 @@ with lib;
205 } 256 }
206 ]; 257 ];
207 }; 258 };
259 tsig-keys = [
260 { name = "local_key";
261 algorithm = "HMAC-SHA256";
262 secret-file = "/run/credentials/kea-dhcp-ddns-server.service/local_key";
263 }
264 ];
208 }; 265 };
209 }; 266 };
210 }; 267 };
211 268
212 systemd.services.kea-dhcp-ddns-server = { 269 systemd.services.kea-dhcp-ddns-server = {
213 preStart = let
214 configLines = [
215 "<?include \"\${CREDENTIALS_DIRECTORY}/knot-tsig.json.frag\"?>"
216 ] ++ mapAttrsToList (k: v:
217 "\"${k}\": ${builtins.toJSON v}"
218 ) config.services.kea.dhcp-ddns.settings;
219
220 config-template = pkgs.writeText "dhcp-ddns.conf" ''
221 {"DhcpDdns": {
222 ${concatStringsSep ",\n " configLines}
223 }}
224 '';
225 in ''
226 ${pkgs.envsubst}/bin/envsubst -i "${config-template}" -o "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf"
227 '';
228
229 serviceConfig = { 270 serviceConfig = {
230 ExecStart = mkForce ''
231 ${pkgs.kea}/bin/kea-dhcp-ddns -c "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf" ${escapeShellArgs config.services.kea.dhcp-ddns.extraArgs}
232 '';
233 LoadCredential = [ 271 LoadCredential = [
234 "knot-tsig.json.frag:${config.sops.secrets."kea-knot-tsig.json.frag".path}" 272 "local_key:${config.sops.secrets."kea-knot-tsig".path}"
235 ]; 273 ];
236 }; 274 };
237 }; 275 };
238 276
239 sops.secrets."kea-knot-tsig.json.frag" = { 277 sops.secrets."kea-knot-tsig" = {
240 format = "binary"; 278 format = "binary";
241 sopsFile = ./knot-tsig.json.frag; 279 sopsFile = ./knot-tsig;
242 }; 280 };
243 281
244 services.nginx.virtualHosts."nfsroot.vidhar.yggdrasil" = { 282 services.nginx.virtualHosts."nfsroot.vidhar.yggdrasil" = {
@@ -252,42 +290,118 @@ with lib;
252 name = "nfsroot.vidhar.yggdrasil"; 290 name = "nfsroot.vidhar.yggdrasil";
253 paths = 291 paths =
254 (map (system: 292 (map (system:
255 let 293 pkgs.symlinkJoin {
256 installerBuild = (flake.nixosConfigurations.${"installer-${system}-nfsroot"}.extendModules { 294 name = "installer-${system}";
257 modules = [ 295 paths = [
258 ({ ... }: { 296 (builtins.addErrorContext "while evaluating installer-${system}-nfsroot" (let
259 config.nfsroot.storeDevice = "10.141.0.1:nix-store"; 297 installerBuild' = (flake.nixosConfigurations.${"installer-${system}-nfsroot"}.extendModules {
260 config.nfsroot.registrationUrl = "http://nfsroot.vidhar.yggdrasil/installer-${system}/registration"; 298 modules = [
261 }) 299 ({ ... }: {
262 ]; 300 config.nfsroot.storeDevice = "${nfsIp}:nix-store";
263 }).config.system.build; 301 config.nfsroot.registrationUrl = "${nfsrootBaseUrl}/installer-${system}/registration";
264 in builtins.toPath (pkgs.runCommandLocal "install-${system}" {} '' 302 config.system.nixos.label = "installer-${system}";
265 mkdir -p $out/installer-${system} 303 })
266 install -m 0444 -t $out/installer-${system} \ 304 ];
267 ${installerBuild.initialRamdisk}/initrd \ 305 });
268 ${installerBuild.kernel}/bzImage \ 306 installerBuild = installerBuild'.config.system.build;
269 ${installerBuild.netbootIpxeScript}/netboot.ipxe \ 307 in builtins.toPath (pkgs.runCommandLocal "installer-${system}" {} ''
270 ${pkgs.closureInfo { rootPaths = installerBuild.storeContents; }}/registration 308 mkdir -p $out/installer-${system}
271 '') 309 install -m 0444 -t $out/installer-${system} \
272 ) ["x86_64-linux"] 310 ${installerBuild.initialRamdisk}/initrd \
311 ${installerBuild.kernel}/bzImage \
312 ${installerBuild.netbootIpxeScript}/netboot.ipxe \
313 ${pkgs.closureInfo { rootPaths = installerBuild.storeContents; }}/registration
314 install -m 0444 ${pkgs.writeText "installer-${system}.menu.ipxe" ''
315 #!ipxe
316
317 :start
318 menu iPXE boot menu for installer-${system}
319 item installer ${with installerBuild'; "${config.system.nixos.distroName} ${config.system.nixos.codeName} ${config.system.nixos.label} (Linux ${config.boot.kernelPackages.kernel.modDirVersion})"}
320 item memtest memtest86plus
321 item netboot netboot.xyz
322 item shell iPXE shell
323 choose --timeout 0 --default installer selected || goto shell
324 goto ''${selected}
325
326 :shell
327 shell
328 goto start
329
330 :installer
331 chain installer-${system}/netboot.ipxe
332 goto start
333
334 :netboot
335 iseq ''${platform} efi && chain --autofree netboot.xyz.efi || chain --autofree netboot.xyz.lkrn
336 goto start
337
338 :memtest
339 chain --autofree mt86plus.efi
340 goto start
341 ''} $out/installer-${system}.menu.ipxe
342 '')))
343 ];
344 }) ["x86_64-linux"]
273 ) ++ [ 345 ) ++ [
274 (let 346 (pkgs.runCommandLocal "utils" {} ''
275 eostreBuild = (flake.nixosConfigurations.eostre.extendModules { 347 mkdir $out
276 modules = [ 348 install -m 0444 -t $out \
277 ({ ... }: { 349 ${ipxe}/{ipxe.efi,i386-ipxe.efi,ipxe.lkrn} \
278 config.nfsroot.storeDevice = "10.141.0.1:nix-store"; 350 ${pkgs.memtest86plus}/mt86plus.efi
279 config.nfsroot.registrationUrl = "http://nfsroot.vidhar.yggdrasil/eostre/registration"; 351 install -m 0444 ${sources.netbootxyz-efi.src} $out/netboot.xyz.efi
280 }) 352 install -m 0444 ${sources.netbootxyz-lkrn.src} $out/netboot.xyz.lkrn
281 ]; 353 '')
282 }).config.system.build; 354 # (builtins.addErrorContext "while evaluating eostre" (let
283 in builtins.toPath (pkgs.runCommandLocal "eostre" {} '' 355 # eostreBuild' = (flake.nixosConfigurations.eostre.extendModules {
284 mkdir -p $out/eostre 356 # modules = [
285 install -m 0444 -t $out/eostre \ 357 # ({ ... }: {
286 ${eostreBuild.initialRamdisk}/initrd \ 358 # config.nfsroot.storeDevice = "${nfsIp}:nix-store";
287 ${eostreBuild.kernel}/bzImage \ 359 # config.nfsroot.registrationUrl = "${nfsrootBaseUrl}/eostre/registration";
288 ${eostreBuild.netbootIpxeScript}/netboot.ipxe \ 360 # config.system.nixos.label = "eostre";
289 ${pkgs.closureInfo { rootPaths = eostreBuild.storeContents; }}/registration 361 # })
290 '')) 362 # ];
363 # });
364 # eostreBuild = eostreBuild'.config.system.build;
365 # in builtins.toPath (pkgs.runCommandLocal "eostre" {} ''
366 # mkdir -p $out/eostre
367 # install -m 0444 -t $out/eostre \
368 # ${eostreBuild.initialRamdisk}/initrd \
369 # ${eostreBuild.kernel}/bzImage \
370 # ${eostreBuild.netbootIpxeScript}/netboot.ipxe \
371 # ${pkgs.closureInfo { rootPaths = eostreBuild.storeContents; }}/registration
372 # install -m 0444 ${pkgs.writeText "eostre.menu.ipxe" ''
373 # #!ipxe
374
375 # set menu-timeout 5000
376
377 # :start
378 # menu iPXE boot menu for eostre
379 # item eostre ${with eostreBuild'; "${config.system.nixos.distroName} ${config.system.nixos.codeName} ${config.system.nixos.label} (Linux ${config.boot.kernelPackages.kernel.modDirVersion})"}
380 # item memtest memtest86plus
381 # item netboot netboot.xyz
382 # item shell iPXE shell
383 # choose --timeout ''${menu-timeout} --default eostre selected || goto shell
384 # set menu-timeout 0
385 # goto ''${selected}
386
387 # :shell
388 # set menu-timeout 0
389 # shell
390 # goto start
391
392 # :eostre
393 # chain eostre/netboot.ipxe
394 # goto start
395
396 # :netboot
397 # iseq ''${platform} efi && chain --autofree netboot.xyz.efi || chain --autofree netboot.xyz.lkrn
398 # goto start
399
400 # :memtest
401 # chain --autofree mt86plus.efi
402 # goto start
403 # ''} $out/eostre.menu.ipxe
404 # '')))
291 ]; 405 ];
292 }; 406 };
293 }; 407 };
@@ -298,20 +412,12 @@ with lib;
298 after = [ "network.target" ]; 412 after = [ "network.target" ];
299 wantedBy = [ "multi-user.target" ]; 413 wantedBy = [ "multi-user.target" ];
300 serviceConfig.ExecStart = let 414 serviceConfig.ExecStart = let
301 ipxe = pkgs.ipxe.override {
302 additionalTargets = {
303 "bin-i386-efi/ipxe.efi" = "i386-ipxe.efi";
304 };
305 additionalOptions = [
306 "NSLOOKUP_CMD"
307 ];
308 };
309 tftpRoot = pkgs.runCommandLocal "netboot" {} '' 415 tftpRoot = pkgs.runCommandLocal "netboot" {} ''
310 mkdir -p $out 416 mkdir -p $out
311 install -m 0444 -t $out \ 417 install -m 0444 -t $out \
312 ${ipxe}/ipxe.efi ${ipxe}/i386-ipxe.efi ${ipxe}/undionly.kpxe 418 ${ipxe}/{ipxe.efi,i386-ipxe.efi,ipxe.lkrn}
313 ''; 419 '';
314 in "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address=10.141.0.1 ${tftpRoot}"; 420 in "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address=${tftpIp} ${tftpRoot}";
315 }; 421 };
316 }; 422 };
317} 423}
diff --git a/hosts/vidhar/network/dhcp/knot-tsig.json.frag b/hosts/vidhar/network/dhcp/knot-tsig
index c10115cf..73a8f11d 100644
--- a/hosts/vidhar/network/dhcp/knot-tsig.json.frag
+++ b/hosts/vidhar/network/dhcp/knot-tsig
@@ -1,18 +1,14 @@
1{ 1{
2 "data": "ENC[AES256_GCM,data:cGcoqYZ341xQOFukDm4J5KDfG6+NaNbk2U2k4YGneRsAoPJZe/8KDmVr8TBWFCXXbuzeCGbiuXRVBmtYSEIqbqTN4u00RdQgpeL72cB3ZFd2c7cideEQV5z802pqFfXSlmLBC01OPG3TwAgk6xhQYSn5IcBTIL6fRF235Y9Q8k/X96rhfwPRVq84,iv:UoweWBcVuQIXeWFFl/WNUHLXG8nEri1UuTskC2I26hU=,tag:TJldVr2LDTmKA3ozZoX+cQ==,type:str]", 2 "data": "ENC[AES256_GCM,data:ZjPqKfUCRYD4iD7yC7qObZhBAMll0DXNzImZ43TM0D8SXRtANqG6YnfwQuJ7,iv:GXD5LutgEz6ktGEtpI9z41IJLLzIMj6OvPADQlZcvwk=,tag:v9ISQFDubtLWcb2mVHa4zA==,type:str]",
3 "sops": { 3 "sops": {
4 "kms": null,
5 "gcp_kms": null,
6 "azure_kv": null,
7 "hc_vault": null,
8 "age": [ 4 "age": [
9 { 5 {
10 "recipient": "age1qffdqvy9arld9zd5a5cylt0n98xhcns5shxhrhwjq5g4qa844ejselaa4l", 6 "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCYk5tM1lPRXc0MGpHZENQ\ndDU2M2VKY2t2VGFrcTUvd0NrU3VMZGQ3NHlNClNTaWVjdDNTQXh6WDFmMDk3SWtn\ncjJjRzUxODFFL25Ic0dabyt1ZW5xRE0KLS0tIDJlT0NTVDlXNWphQ1B0VTQ1U0NH\nNktRNlIrQzdhRjZ0SjR0T3oyRkZiWXMKX28S4SySQguT1cgMZpDY4o/OKY6IvjT9\n1oUzwx/BzBbC2JbpGYvQQgp/qfiM2k0oXmQlfdTv8kD/MoOqPO8E1Q==\n-----END AGE ENCRYPTED FILE-----\n",
11 "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCYk5tM1lPRXc0MGpHZENQ\ndDU2M2VKY2t2VGFrcTUvd0NrU3VMZGQ3NHlNClNTaWVjdDNTQXh6WDFmMDk3SWtn\ncjJjRzUxODFFL25Ic0dabyt1ZW5xRE0KLS0tIDJlT0NTVDlXNWphQ1B0VTQ1U0NH\nNktRNlIrQzdhRjZ0SjR0T3oyRkZiWXMKX28S4SySQguT1cgMZpDY4o/OKY6IvjT9\n1oUzwx/BzBbC2JbpGYvQQgp/qfiM2k0oXmQlfdTv8kD/MoOqPO8E1Q==\n-----END AGE ENCRYPTED FILE-----\n" 7 "recipient": "age1qffdqvy9arld9zd5a5cylt0n98xhcns5shxhrhwjq5g4qa844ejselaa4l"
12 } 8 }
13 ], 9 ],
14 "lastmodified": "2022-03-15T13:52:17Z", 10 "lastmodified": "2026-07-29T06:39:18Z",
15 "mac": "ENC[AES256_GCM,data:rTelaGx5S2E2oYPNGfctFbgDKdyRX8tpVTqLtpcCAJ8MS5ppFTjnSwYi4yQHvTicfAPNz7hGJYAnTdyC2QDTciJgkS6KC3CCXWCimkTybBdVW4Azwz9iBZCpWu+rB1vcQhSLlLCaKmKskkqDZZ5+mfuaXc+TT2uwTA0SDtZWvnM=,iv:ANCZ1fHy6w/svEE53o7rWsp5qU15qoriqyVMzClH6J0=,tag:H92RM5GuLIl9/kslq4tzkQ==,type:str]", 11 "mac": "ENC[AES256_GCM,data:hj/YR0N8NhGHQEcCOjt/r+rfM8plkaUZoee9sI25evvEvOlfX69YRxUv1vyd6Sqd9wPEgCsF5STnMXFQhq3zgGjoTFcdHU+olRVmRq9rkYQo/ButZ/NEIQ7uc5b4FRPdPwOGF14aSpgI67F35oRavv1vtk10zGme+X0I1VXTIqE=,iv:rMUL+CyTLhQBJrsQJQPhN75FjCf5uGFh1z6KAXKDeB8=,tag:bpeQZ3UPZ10tCrgveoDklg==,type:str]",
16 "pgp": [ 12 "pgp": [
17 { 13 {
18 "created_at": "2023-01-30T11:00:34Z", 14 "created_at": "2023-01-30T11:00:34Z",
@@ -21,6 +17,6 @@
21 } 17 }
22 ], 18 ],
23 "unencrypted_suffix": "_unencrypted", 19 "unencrypted_suffix": "_unencrypted",
24 "version": "3.7.1" 20 "version": "3.13.2"
25 } 21 }
26} \ No newline at end of file 22}