From 366cf64e848eebea98f9d9bb95e623597af74669 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Tue, 15 Mar 2022 16:37:42 +0100 Subject: vidhar: ddns --- hosts/vidhar/network/dhcp/default.nix | 264 ++++++++++++++++++++++++++ hosts/vidhar/network/dhcp/knot-tsig.json.frag | 26 +++ 2 files changed, 290 insertions(+) create mode 100644 hosts/vidhar/network/dhcp/default.nix create mode 100644 hosts/vidhar/network/dhcp/knot-tsig.json.frag (limited to 'hosts/vidhar/network/dhcp') diff --git a/hosts/vidhar/network/dhcp/default.nix b/hosts/vidhar/network/dhcp/default.nix new file mode 100644 index 00000000..ccc22c7f --- /dev/null +++ b/hosts/vidhar/network/dhcp/default.nix @@ -0,0 +1,264 @@ +{ flake, config, pkgs, lib, ... }: +{ + config = { + services.kea = { + dhcp4 = { + enable = true; + settings = { + valid-lifetime = 4000; + rebind-timer = 2000; + renew-timer = 1000; + + interfaces-config = { + interfaces = [ "lan" "mgmt" ]; + }; + + lease-database = { + name = "/var/lib/kea/dhcp4.leases"; + persist = true; + type = "memfile"; + }; + + client-classes = [ + { name = "ipxe"; + test = "option[77].hex == 'iPXE'"; + next-server = "10.141.0.1"; + boot-file-name = "netboot.ipxe"; + only-if-required = true; + } + { name = "uefi-64"; + 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'"; + only-if-required = true; + option-data = [ + { name = "tftp-server-name"; data = "10.141.0.1"; } + ]; + boot-file-name = "ipxe.efi"; + } + { name = "uefi-32"; + test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00002' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00006'"; + only-if-required = true; + option-data = [ + { name = "tftp-server-name"; data = "10.141.0.1"; } + ]; + boot-file-name = "i386-ipxe.efi"; + } + { name = "legacy"; + test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'"; + only-if-required = true; + option-data = [ + { name = "tftp-server-name"; data = "10.141.0.1"; } + ]; + boot-file-name = "undionly.kpxe"; + } + ]; + + dhcp-ddns.enable-updates = true; + ddns-send-updates = false; + ddns-override-client-update = true; + ddns-override-no-update = true; + ddns-replace-client-name = "when-not-present"; + ddns-generated-prefix = "noname"; + ddns-update-on-renew = true; + + subnet4 = [ + { subnet = "10.141.0.0/24"; + option-data = [ + { name = "domain-name-servers"; + data = "10.141.0.1"; + } + { name = "broadcast-address"; + data = "10.141.0.255"; + } + { name = "routers"; + data = "10.141.0.1"; + } + { name = "domain-name"; + data = "yggdrasil"; + } + { name = "domain-search"; + data = "lan.yggdrasil, yggdrasil"; + } + ]; + ddns-send-updates = true; + ddns-qualifying-suffix = "lan.yggdrasil"; + pools = [ { pool = "10.141.0.128 - 10.141.0.254"; } ]; + require-client-classes = ["ipxe" "uefi-64" "uefi-32" "legacy"]; + reservations = [ + { hostname = "sif"; + hw-address = "3c:e1:a1:52:24:35"; + } + { hostname = "sif"; + hw-address = "ee:32:68:76:83:ac"; + } + { hostname = "sif"; + hw-address = "48:2a:e3:64:62:97"; + } + { hostname = "eos"; + hw-address = "00:d8:61:79:c5:40"; + } + ]; + } + { subnet = "10.141.1.0/24"; + option-data = [ + { name = "domain-name-servers"; + data = "10.141.1.1"; + } + { name = "broadcast-address"; + data = "10.141.1.255"; + } + { name = "domain-name"; + data = "yggdrasil"; + } + { name = "domain-search"; + data = "mgmt.yggdrasil, yggdrasil"; + } + ]; + ddns-send-updates = true; + ddns-qualifying-suffix = "mgmt.yggdrasil"; + pools = [ { pool = "10.141.1.128 - 10.141.1.254"; } ]; + reservations = [ + { hostname = "switch01"; + hw-address = "60:a4:b7:53:94:b5"; + ip-address = "10.141.1.2"; + } + { hostname = "ap01"; + hw-address = "74:ac:b9:29:ad:9a"; + ip-address = "10.141.1.4"; + } + ]; + } + { subnet = "10.141.2.0/24"; + option-data = [ + { name = "domain-name-servers"; + data = "10.141.2.1"; + } + { name = "broadcast-address"; + data = "10.141.2.255"; + } + { name = "routers"; + data = "10.141.2.1"; + } + ]; + ddns-send-updates = false; + pools = [ { pool = "10.141.2.128 - 10.141.2.254"; } ]; + reservations = []; + } + ]; + }; + }; + dhcp6 = { + enable = true; + settings = { + interfaces-config = { + interfaces = [ "lan" ]; + }; + + lease-database = { + name = "/var/lib/kea/dhcp6.leases"; + persist = true; + type = "memfile"; + }; + }; + }; + dhcp-ddns = { + enable = true; + settings = { + forward-ddns = { + ddns-domains = [ + { name = "lan.yggdrasil."; + dns-servers = [ + { ip-address = "127.0.0.1"; + port = 5353; + key-name = "local_key"; + } + ]; + } + { name = "mgmt.yggdrasil."; + dns-servers = [ + { ip-address = "127.0.0.1"; + port = 5353; + key-name = "local_key"; + } + ]; + } + ]; + }; + reverse-ddns = { + ddns-domains = [ + { name = "0.141.10.in-addr.arpa."; + dns-servers = [ + { ip-address = "127.0.0.1"; + port = 5353; + key-name = "local_key"; + } + ]; + } + { name = "1.141.10.in-addr.arpa."; + dns-servers = [ + { ip-address = "127.0.0.1"; + port = 5353; + key-name = "local_key"; + } + ]; + } + ]; + }; + }; + }; + }; + + systemd.services.kea-dhcp-ddns-server = { + preStart = let + configLines = [ + "" + ] ++ lib.mapAttrsToList (k: v: + "\"${k}\": ${builtins.toJSON v}" + ) config.services.kea.dhcp-ddns.settings; + + config-template = pkgs.writeText "dhcp-ddns.conf" '' + {"DhcpDdns": { + ${lib.concatStringsSep ",\n " configLines} + }} + ''; + in '' + ${pkgs.envsubst}/bin/envsubst -i "${config-template}" -o "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf" + ''; + + serviceConfig = { + ExecStart = lib.mkForce '' + ${pkgs.kea}/bin/kea-dhcp-ddns -c "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf" ${lib.escapeShellArgs config.services.kea.dhcp-ddns.extraArgs} + ''; + LoadCredential = [ + "knot-tsig.json.frag:${config.sops.secrets."kea-knot-tsig.json.frag".path}" + ]; + }; + }; + + sops.secrets."kea-knot-tsig.json.frag" = { + format = "binary"; + sopsFile = ./knot-tsig.json.frag; + }; + + systemd.services."installer-atftpd" = { + description = "TFTP Server for PXE Booting NixOS Installer"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig.ExecStart = let + installerBuild = flake.nixosConfigurations.installer-x86_64-linux-netboot.config.system.build; + ipxe = pkgs.ipxe.override { + additionalTargets = { + "bin-i386-efi/ipxe.efi" = "i386-ipxe.efi"; + }; + }; + tftpRoot = pkgs.runCommandLocal "installer-netboot" {} '' + mkdir -p $out + install -m 0444 -t $out \ + ${installerBuild.netbootRamdisk}/initrd \ + ${installerBuild.kernel}/bzImage \ + ${installerBuild.netbootIpxeScript}/netboot.ipxe \ + ${ipxe}/ipxe.efi ${ipxe}/i386-ipxe.efi ${ipxe}/undionly.kpxe + ''; + in "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address=10.141.0.1 ${tftpRoot}"; + }; + }; +} diff --git a/hosts/vidhar/network/dhcp/knot-tsig.json.frag b/hosts/vidhar/network/dhcp/knot-tsig.json.frag new file mode 100644 index 00000000..75deb41c --- /dev/null +++ b/hosts/vidhar/network/dhcp/knot-tsig.json.frag @@ -0,0 +1,26 @@ +{ + "data": "ENC[AES256_GCM,data:cGcoqYZ341xQOFukDm4J5KDfG6+NaNbk2U2k4YGneRsAoPJZe/8KDmVr8TBWFCXXbuzeCGbiuXRVBmtYSEIqbqTN4u00RdQgpeL72cB3ZFd2c7cideEQV5z802pqFfXSlmLBC01OPG3TwAgk6xhQYSn5IcBTIL6fRF235Y9Q8k/X96rhfwPRVq84,iv:UoweWBcVuQIXeWFFl/WNUHLXG8nEri1UuTskC2I26hU=,tag:TJldVr2LDTmKA3ozZoX+cQ==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": null, + "lastmodified": "2022-03-15T13:52:17Z", + "mac": "ENC[AES256_GCM,data:rTelaGx5S2E2oYPNGfctFbgDKdyRX8tpVTqLtpcCAJ8MS5ppFTjnSwYi4yQHvTicfAPNz7hGJYAnTdyC2QDTciJgkS6KC3CCXWCimkTybBdVW4Azwz9iBZCpWu+rB1vcQhSLlLCaKmKskkqDZZ5+mfuaXc+TT2uwTA0SDtZWvnM=,iv:ANCZ1fHy6w/svEE53o7rWsp5qU15qoriqyVMzClH6J0=,tag:H92RM5GuLIl9/kslq4tzkQ==,type:str]", + "pgp": [ + { + "created_at": "2022-03-15T13:50:52Z", + "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DbYDvGI0HDr0SAQdANAtB0un04iI+foGRefRK249LhT6Mz+yzdhkWa0UYoxcw\nUGDSh6la4ijiaqdeVfJ3vckXfAqee7dLseNQ64dafdlk2hVI0ZNv6mjfwgWk698v\n0l4B4EOHfDrmFNhZFcj1/sCRnukgx7PSeybZn3miTLQgMGOydrfYuisA3we/4EUo\nU55PGINdtAu268OUHQjj3yF1S72Yeh1MXEdvajRQdqorQJ4TpsPUtJolM25Df/kK\n=etIn\n-----END PGP MESSAGE-----\n", + "fp": "A1C7C95E6CAF0A965CB47277BCF50A89C1B1F362" + }, + { + "created_at": "2022-03-15T13:50:52Z", + "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdABm/Qf3pX4SxvTzq6sJKWc5o3Fzu/nH3XAH1WE2L/BUMw\nMFFmYmq3399ZcZ6JvaHdbJFUdavo/+wOg3ecWok039wbsr9qwn8YA4cR7VBsUPLa\n0l4BxuaiT3M+mTVvr5WpGFc3Xj7Mp4/z6hBUS+qTFIFZI2U5JsmZgC7VGTm+dlSJ\nexN6yr9mlQXvDIkx8w5/eaiYGViZ90SxN9BPYDqfGGigAw+xdXaafcOx8uBldAL1\n=HLRI\n-----END PGP MESSAGE-----\n", + "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51" + } + ], + "unencrypted_suffix": "_unencrypted", + "version": "3.7.1" + } +} \ No newline at end of file -- cgit v1.2.3