summaryrefslogtreecommitdiff
path: root/hosts/vidhar/network/dhcp/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'hosts/vidhar/network/dhcp/default.nix')
-rw-r--r--hosts/vidhar/network/dhcp/default.nix258
1 files changed, 151 insertions, 107 deletions
diff --git a/hosts/vidhar/network/dhcp/default.nix b/hosts/vidhar/network/dhcp/default.nix
index 4151111d..e4c3f16e 100644
--- a/hosts/vidhar/network/dhcp/default.nix
+++ b/hosts/vidhar/network/dhcp/default.nix
@@ -1,9 +1,32 @@
1{ flake, config, pkgs, lib, ... }: 1{ flake, config, pkgs, lib, sources, ... }:
2 2
3with lib; 3with lib;
4 4
5let 5let
6 nfsrootBaseUrl = "http://nfsroot.vidhar.yggdrasil"; 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 };
7in { 30in {
8 config = { 31 config = {
9 services.kea = { 32 services.kea = {
@@ -25,41 +48,67 @@ in {
25 }; 48 };
26 49
27 client-classes = [ 50 client-classes = [
28 { name = "eostre-ipxe"; 51 # { name = "ipxe-eostre";
29 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'";
30 next-server = "10.141.0.1"; 53 # next-server = tftpIp;
31 boot-file-name = "${nfsrootBaseUrl}/eostre.menu.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";
32 only-if-required = true; 61 only-if-required = true;
33 } 62 }
34 { name = "ipxe"; 63
35 test = "option[77].hex == 'iPXE'"; 64 { name = "uefi-http";
36 next-server = "10.141.0.1"; 65 test = "option[client-system].hex == 0x0010";
37 boot-file-name = "${nfsrootBaseUrl}/installer-x86_64-linux.menu.ipxe"; 66 option-data = [
67 { name = "vendor-class-identifier"; data = "HTTPClient"; }
68 ];
69 boot-file-name = "${nfsrootBaseUrl}/ipxe.efi";
38 only-if-required = true; 70 only-if-required = true;
39 } 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";
81 only-if-required = true;
82 }
83 { name = "ipxe-legacy";
84 test = "option[77].hex == 'iPXE' and substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'";
85 boot-file-name = "${nfsrootBaseUrl}/ipxe.lkrn";
86 only-if-required = true;
87 }
88
40 { name = "uefi-64"; 89 { name = "uefi-64";
41 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'";
42 only-if-required = true;
43 option-data = [ 91 option-data = [
44 { name = "tftp-server-name"; data = "10.141.0.1"; } 92 { name = "tftp-server-name"; data = tftpIp; }
45 ]; 93 ];
46 boot-file-name = "ipxe.efi"; 94 boot-file-name = "ipxe.efi";
95 only-if-required = true;
47 } 96 }
48 { name = "uefi-32"; 97 { name = "uefi-32";
49 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'";
50 only-if-required = true;
51 option-data = [ 99 option-data = [
52 { name = "tftp-server-name"; data = "10.141.0.1"; } 100 { name = "tftp-server-name"; data = tftpIp; }
53 ]; 101 ];
54 boot-file-name = "i386-ipxe.efi"; 102 boot-file-name = "i386-ipxe.efi";
103 only-if-required = true;
55 } 104 }
56 { name = "legacy"; 105 { name = "legacy";
57 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'"; 106 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'";
58 only-if-required = true;
59 option-data = [ 107 option-data = [
60 { name = "tftp-server-name"; data = "10.141.0.1"; } 108 { name = "tftp-server-name"; data = tftpIp; }
61 ]; 109 ];
62 boot-file-name = "undionly.kpxe"; 110 boot-file-name = "ipxe.lkrn";
111 only-if-required = true;
63 } 112 }
64 ]; 113 ];
65 114
@@ -207,40 +256,27 @@ in {
207 } 256 }
208 ]; 257 ];
209 }; 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 ];
210 }; 265 };
211 }; 266 };
212 }; 267 };
213 268
214 systemd.services.kea-dhcp-ddns-server = { 269 systemd.services.kea-dhcp-ddns-server = {
215 preStart = let
216 configLines = [
217 "<?include \"\${CREDENTIALS_DIRECTORY}/knot-tsig.json.frag\"?>"
218 ] ++ mapAttrsToList (k: v:
219 "\"${k}\": ${builtins.toJSON v}"
220 ) config.services.kea.dhcp-ddns.settings;
221
222 config-template = pkgs.writeText "dhcp-ddns.conf" ''
223 {"DhcpDdns": {
224 ${concatStringsSep ",\n " configLines}
225 }}
226 '';
227 in ''
228 ${pkgs.envsubst}/bin/envsubst -i "${config-template}" -o "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf"
229 '';
230
231 serviceConfig = { 270 serviceConfig = {
232 ExecStart = mkForce ''
233 ${pkgs.kea}/bin/kea-dhcp-ddns -c "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf" ${escapeShellArgs config.services.kea.dhcp-ddns.extraArgs}
234 '';
235 LoadCredential = [ 271 LoadCredential = [
236 "knot-tsig.json.frag:${config.sops.secrets."kea-knot-tsig.json.frag".path}" 272 "local_key:${config.sops.secrets."kea-knot-tsig".path}"
237 ]; 273 ];
238 }; 274 };
239 }; 275 };
240 276
241 sops.secrets."kea-knot-tsig.json.frag" = { 277 sops.secrets."kea-knot-tsig" = {
242 format = "binary"; 278 format = "binary";
243 sopsFile = ./knot-tsig.json.frag; 279 sopsFile = ./knot-tsig;
244 }; 280 };
245 281
246 services.nginx.virtualHosts."nfsroot.vidhar.yggdrasil" = { 282 services.nginx.virtualHosts."nfsroot.vidhar.yggdrasil" = {
@@ -257,30 +293,31 @@ in {
257 pkgs.symlinkJoin { 293 pkgs.symlinkJoin {
258 name = "installer-${system}"; 294 name = "installer-${system}";
259 paths = [ 295 paths = [
260 (let 296 (builtins.addErrorContext "while evaluating installer-${system}-nfsroot" (let
261 installerBuild = (flake.nixosConfigurations.${"installer-${system}-nfsroot"}.extendModules { 297 installerBuild' = (flake.nixosConfigurations.${"installer-${system}-nfsroot"}.extendModules {
262 modules = [ 298 modules = [
263 ({ ... }: { 299 ({ ... }: {
264 config.nfsroot.storeDevice = "10.141.0.1:nix-store"; 300 config.nfsroot.storeDevice = "${nfsIp}:nix-store";
265 config.nfsroot.registrationUrl = "${nfsrootBaseUrl}/installer-${system}/registration"; 301 config.nfsroot.registrationUrl = "${nfsrootBaseUrl}/installer-${system}/registration";
302 config.system.nixos.label = "installer-${system}";
266 }) 303 })
267 ]; 304 ];
268 }).config.system.build; 305 });
269 in builtins.toPath (pkgs.runCommandLocal "install-${system}" {} '' 306 installerBuild = installerBuild'.config.system.build;
307 in builtins.toPath (pkgs.runCommandLocal "installer-${system}" {} ''
270 mkdir -p $out/installer-${system} 308 mkdir -p $out/installer-${system}
271 install -m 0444 -t $out/installer-${system} \ 309 install -m 0444 -t $out/installer-${system} \
272 ${installerBuild.initialRamdisk}/initrd \ 310 ${installerBuild.initialRamdisk}/initrd \
273 ${installerBuild.kernel}/bzImage \ 311 ${installerBuild.kernel}/bzImage \
274 ${installerBuild.netbootIpxeScript}/netboot.ipxe \ 312 ${installerBuild.netbootIpxeScript}/netboot.ipxe \
275 ${pkgs.closureInfo { rootPaths = installerBuild.storeContents; }}/registration 313 ${pkgs.closureInfo { rootPaths = installerBuild.storeContents; }}/registration
276 '')) 314 install -m 0444 ${pkgs.writeText "installer-${system}.menu.ipxe" ''
277 (pkgs.writeTextFile { 315 #!ipxe
278 name = "installer-${system}.menu.ipxe"; 316
279 destination = "/installer-${system}.menu.ipxe";
280 text = ''
281 :start 317 :start
282 menu iPXE boot menu for installer-${system} 318 menu iPXE boot menu for installer-${system}
283 item installer Boot 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
284 item netboot netboot.xyz 321 item netboot netboot.xyz
285 item shell iPXE shell 322 item shell iPXE shell
286 choose --timeout 0 --default installer selected || goto shell 323 choose --timeout 0 --default installer selected || goto shell
@@ -291,65 +328,80 @@ in {
291 goto start 328 goto start
292 329
293 :installer 330 :installer
294 chain ${nfsrootBaseUrl}/installer-${system}/netboot.ipxe 331 chain installer-${system}/netboot.ipxe
295 goto start 332 goto start
296 333
297 :netboot 334 :netboot
298 chain --autofree ${nfsrootBaseUrl}/netboot.xyz.efi 335 iseq ''${platform} efi && chain --autofree netboot.xyz.efi || chain --autofree netboot.xyz.lkrn
299 goto start 336 goto start
300 ''; 337
301 }) 338 :memtest
339 chain --autofree mt86plus.efi
340 goto start
341 ''} $out/installer-${system}.menu.ipxe
342 '')))
302 ]; 343 ];
303 }) ["x86_64-linux"] 344 }) ["x86_64-linux"]
304 ) ++ [ 345 ) ++ [
305 (pkgs.linkFarm "netbootxyz-efi" [ 346 (pkgs.runCommandLocal "utils" {} ''
306 { name = "netboot.xyz.efi"; path = pkgs.netbootxyz-efi; } 347 mkdir $out
307 ]) 348 install -m 0444 -t $out \
308 (let 349 ${ipxe}/{ipxe.efi,i386-ipxe.efi,ipxe.lkrn} \
309 eostreBuild = (flake.nixosConfigurations.eostre.extendModules { 350 ${pkgs.memtest86plus}/mt86plus.efi
310 modules = [ 351 install -m 0444 ${sources.netbootxyz-efi.src} $out/netboot.xyz.efi
311 ({ ... }: { 352 install -m 0444 ${sources.netbootxyz-lkrn.src} $out/netboot.xyz.lkrn
312 config.nfsroot.storeDevice = "10.141.0.1:nix-store"; 353 '')
313 config.nfsroot.registrationUrl = "${nfsrootBaseUrl}/eostre/registration"; 354 # (builtins.addErrorContext "while evaluating eostre" (let
314 }) 355 # eostreBuild' = (flake.nixosConfigurations.eostre.extendModules {
315 ]; 356 # modules = [
316 }).config.system.build; 357 # ({ ... }: {
317 in builtins.toPath (pkgs.runCommandLocal "eostre" {} '' 358 # config.nfsroot.storeDevice = "${nfsIp}:nix-store";
318 mkdir -p $out/eostre 359 # config.nfsroot.registrationUrl = "${nfsrootBaseUrl}/eostre/registration";
319 install -m 0444 -t $out/eostre \ 360 # config.system.nixos.label = "eostre";
320 ${eostreBuild.initialRamdisk}/initrd \ 361 # })
321 ${eostreBuild.kernel}/bzImage \ 362 # ];
322 ${eostreBuild.netbootIpxeScript}/netboot.ipxe \ 363 # });
323 ${pkgs.closureInfo { rootPaths = eostreBuild.storeContents; }}/registration 364 # eostreBuild = eostreBuild'.config.system.build;
324 '')) 365 # in builtins.toPath (pkgs.runCommandLocal "eostre" {} ''
325 (pkgs.writeTextFile { 366 # mkdir -p $out/eostre
326 name = "eostre.menu.ipxe"; 367 # install -m 0444 -t $out/eostre \
327 destination = "/eostre.menu.ipxe"; 368 # ${eostreBuild.initialRamdisk}/initrd \
328 text = '' 369 # ${eostreBuild.kernel}/bzImage \
329 set menu-timeout 5000 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
330 376
331 :start 377 # :start
332 menu iPXE boot menu for eostre 378 # menu iPXE boot menu for eostre
333 item eostre Boot eostre 379 # item eostre ${with eostreBuild'; "${config.system.nixos.distroName} ${config.system.nixos.codeName} ${config.system.nixos.label} (Linux ${config.boot.kernelPackages.kernel.modDirVersion})"}
334 item netboot netboot.xyz 380 # item memtest memtest86plus
335 item shell iPXE shell 381 # item netboot netboot.xyz
336 choose --timeout ''${menu-timeout} --default eostre selected || goto shell 382 # item shell iPXE shell
337 goto ''${selected} 383 # choose --timeout ''${menu-timeout} --default eostre selected || goto shell
384 # set menu-timeout 0
385 # goto ''${selected}
338 386
339 :shell 387 # :shell
340 shell 388 # set menu-timeout 0
341 set menu-timeout 0 389 # shell
342 goto start 390 # goto start
343 391
344 :eostre 392 # :eostre
345 chain ${nfsrootBaseUrl}/eostre/netboot.ipxe 393 # chain eostre/netboot.ipxe
346 goto start 394 # goto start
347 395
348 :netboot 396 # :netboot
349 chain --autofree ${nfsrootBaseUrl}/netboot.xyz.efi 397 # iseq ''${platform} efi && chain --autofree netboot.xyz.efi || chain --autofree netboot.xyz.lkrn
350 goto start 398 # goto start
351 ''; 399
352 }) 400 # :memtest
401 # chain --autofree mt86plus.efi
402 # goto start
403 # ''} $out/eostre.menu.ipxe
404 # '')))
353 ]; 405 ];
354 }; 406 };
355 }; 407 };
@@ -360,20 +412,12 @@ in {
360 after = [ "network.target" ]; 412 after = [ "network.target" ];
361 wantedBy = [ "multi-user.target" ]; 413 wantedBy = [ "multi-user.target" ];
362 serviceConfig.ExecStart = let 414 serviceConfig.ExecStart = let
363 ipxe = pkgs.ipxe.override {
364 additionalTargets = {
365 "bin-i386-efi/ipxe.efi" = "i386-ipxe.efi";
366 };
367 additionalOptions = [
368 "NSLOOKUP_CMD"
369 ];
370 };
371 tftpRoot = pkgs.runCommandLocal "netboot" {} '' 415 tftpRoot = pkgs.runCommandLocal "netboot" {} ''
372 mkdir -p $out 416 mkdir -p $out
373 install -m 0444 -t $out \ 417 install -m 0444 -t $out \
374 ${ipxe}/ipxe.efi ${ipxe}/i386-ipxe.efi ${ipxe}/undionly.kpxe 418 ${ipxe}/{ipxe.efi,i386-ipxe.efi,ipxe.lkrn}
375 ''; 419 '';
376 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}";
377 }; 421 };
378 }; 422 };
379} 423}