summaryrefslogtreecommitdiff
path: root/hosts
diff options
context:
space:
mode:
Diffstat (limited to 'hosts')
-rw-r--r--hosts/vidhar/default.nix2
-rw-r--r--hosts/vidhar/dns.nix47
-rw-r--r--hosts/vidhar/dns/Gupfile2
-rw-r--r--hosts/vidhar/dns/default.nix127
-rw-r--r--hosts/vidhar/dns/key.gup6
-rw-r--r--hosts/vidhar/dns/keys/local.yaml26
-rw-r--r--hosts/vidhar/dns/zones/arpa.in-addr.10.141.0.soa12
-rw-r--r--hosts/vidhar/dns/zones/arpa.in-addr.10.141.1.soa14
-rw-r--r--hosts/vidhar/dns/zones/arpa.in-addr.10.141.soa11
-rw-r--r--hosts/vidhar/dns/zones/yggdrasil.lan.soa13
-rw-r--r--hosts/vidhar/dns/zones/yggdrasil.mgmt.soa15
-rw-r--r--hosts/vidhar/dns/zones/yggdrasil.soa21
-rw-r--r--hosts/vidhar/network/default.nix152
-rw-r--r--hosts/vidhar/network/dhcp/default.nix264
-rw-r--r--hosts/vidhar/network/dhcp/knot-tsig.json.frag26
15 files changed, 540 insertions, 198 deletions
diff --git a/hosts/vidhar/default.nix b/hosts/vidhar/default.nix
index 3d81b221..f9b021d3 100644
--- a/hosts/vidhar/default.nix
+++ b/hosts/vidhar/default.nix
@@ -1,7 +1,7 @@
1{ hostName, flake, config, pkgs, lib, ... }: 1{ hostName, flake, config, pkgs, lib, ... }:
2{ 2{
3 imports = with flake.nixosModules.systemProfiles; [ 3 imports = with flake.nixosModules.systemProfiles; [
4 ./zfs.nix ./network ./samba.nix ./dns.nix ./prometheus ./borg 4 ./zfs.nix ./network ./samba.nix ./dns ./prometheus ./borg
5 initrd-all-crypto-modules default-locale openssh rebuild-machines 5 initrd-all-crypto-modules default-locale openssh rebuild-machines
6 build-server 6 build-server
7 initrd-ssh 7 initrd-ssh
diff --git a/hosts/vidhar/dns.nix b/hosts/vidhar/dns.nix
deleted file mode 100644
index 72e707e7..00000000
--- a/hosts/vidhar/dns.nix
+++ /dev/null
@@ -1,47 +0,0 @@
1{ config, lib, pkgs, ... }:
2{
3 config = {
4 services.unbound = {
5 enable = true;
6 resolveLocalQueries = false;
7 stateDir = "/var/lib/unbound";
8 localControlSocketPath = "/run/unbound/unbound.ctl";
9 settings = {
10 server = {
11 interface = ["127.0.0.1" "10.141.0.1" "::0"];
12 access-control = ["0.0.0.0/0 allow" "::/0 allow"];
13 root-hints = "${pkgs.dns-root-data}/root.hints";
14
15 num-threads = 12;
16 so-reuseport = true;
17 msg-cache-slabs = 16;
18 rrset-cache-slabs = 16;
19 infra-cache-slabs = 16;
20 key-cache-slabs = 16;
21
22 rrset-cache-size = "100m";
23 msg-cache-size = "50m";
24 outgoing-range = 8192;
25 num-queries-per-thread = 4096;
26
27 so-rcvbuf = "4m";
28 so-sndbuf = "4m";
29
30 # serve-expired = true;
31 # serve-expired-ttl = 86400;
32 # serve-expired-reply-ttl = 0;
33
34 prefetch = true;
35 prefetch-key = true;
36
37 minimal-responses = false;
38
39 extended-statistics = true;
40
41 rrset-roundrobin = true;
42 use-caps-for-id = true;
43 };
44 };
45 };
46 };
47}
diff --git a/hosts/vidhar/dns/Gupfile b/hosts/vidhar/dns/Gupfile
new file mode 100644
index 00000000..ac96f620
--- /dev/null
+++ b/hosts/vidhar/dns/Gupfile
@@ -0,0 +1,2 @@
1key.gup:
2 keys/*.yaml \ No newline at end of file
diff --git a/hosts/vidhar/dns/default.nix b/hosts/vidhar/dns/default.nix
new file mode 100644
index 00000000..19a121f6
--- /dev/null
+++ b/hosts/vidhar/dns/default.nix
@@ -0,0 +1,127 @@
1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 knotKeys = let
7 dir = ./keys;
8 toKeyInfo = name: v:
9 if v == "regular" || v == "symlink"
10 then { path = dir + "/${name}"; inherit name; }
11 else null;
12 in filter (v: v != null) (mapAttrsToList toKeyInfo (builtins.readDir dir));
13in {
14 config = {
15 services.unbound = {
16 enable = true;
17 resolveLocalQueries = false;
18 stateDir = "/var/lib/unbound";
19 localControlSocketPath = "/run/unbound/unbound.ctl";
20 settings = {
21 server = {
22 interface = ["127.0.0.1" "10.141.0.1" "::0"];
23 prefer-ip6 = true;
24 access-control = ["0.0.0.0/0 allow" "::/0 allow"];
25 root-hints = "${pkgs.dns-root-data}/root.hints";
26
27 num-threads = 12;
28 so-reuseport = true;
29 msg-cache-slabs = 16;
30 rrset-cache-slabs = 16;
31 infra-cache-slabs = 16;
32 key-cache-slabs = 16;
33
34 rrset-cache-size = "100m";
35 msg-cache-size = "50m";
36 outgoing-range = 8192;
37 num-queries-per-thread = 4096;
38
39 so-rcvbuf = "4m";
40 so-sndbuf = "4m";
41
42 # serve-expired = true;
43 # serve-expired-ttl = 86400;
44 # serve-expired-reply-ttl = 0;
45
46 prefetch = true;
47 prefetch-key = true;
48
49 minimal-responses = false;
50
51 extended-statistics = true;
52
53 rrset-roundrobin = true;
54 use-caps-for-id = true;
55
56 local-zone = [
57 "141.10.in-addr.arpa transparent"
58 "yggdrasil transparent"
59 ];
60 domain-insecure = [
61 "141.10.in-addr.arpa"
62 "yggdrasil"
63 ];
64 };
65
66 stub-zone = map (name: {
67 inherit name;
68 stub-addr = "127.0.0.1@5353";
69 stub-first = true;
70 stub-no-cache = true;
71 stub-prime = false;
72 }) ["yggdrasil" "lan.yggdrasil" "mgmt.yggdrasil" "arpa.in-addr.10.141" "arpa.in-addr.10.141.0" "arpa.in-addr.10.141.1"];
73 };
74 };
75
76 services.knot = {
77 enable = true;
78 keyFiles = map ({name, ...}: config.sops.secrets.${name}.path) knotKeys;
79 extraConfig = ''
80 server:
81 listen: 127.0.0.1@5353
82 listen: ::1@5353
83
84 acl:
85 - id: local_acl
86 key: local_key
87 action: update
88
89 template:
90 - id: local_zone
91 storage: /var/lib/knot
92 zonefile-sync: -1
93 zonefile-load: difference-no-serial
94 serial-policy: dateserial
95 journal-content: all
96 semantic-checks: on
97 acl: [local_acl]
98
99 zone:
100 - domain: yggdrasil
101 template: local_zone
102 file: ${./zones/yggdrasil.soa}
103 - domain: lan.yggdrasil
104 template: local_zone
105 file: ${./zones/yggdrasil.lan.soa}
106 - domain: mgmt.yggdrasil
107 template: local_zone
108 file: ${./zones/yggdrasil.mgmt.soa}
109 - domain: 141.10.in-addr.arpa
110 template: local_zone
111 file: ${./zones/arpa.in-addr.10.141.soa}
112 - domain: 0.141.10.in-addr.arpa
113 template: local_zone
114 file: ${./zones/arpa.in-addr.10.141.0.soa}
115 - domain: 1.141.10.in-addr.arpa
116 template: local_zone
117 file: ${./zones/arpa.in-addr.10.141.1.soa}
118 '';
119 };
120
121 sops.secrets = listToAttrs (map ({name, path}: nameValuePair name {
122 format = "binary";
123 owner = "knot";
124 sopsFile = path;
125 }) knotKeys);
126 };
127}
diff --git a/hosts/vidhar/dns/key.gup b/hosts/vidhar/dns/key.gup
new file mode 100644
index 00000000..83c36b0e
--- /dev/null
+++ b/hosts/vidhar/dns/key.gup
@@ -0,0 +1,6 @@
1#!/usr/bin/env zsh
2
3keyName=${${2:t}%.yaml}_key
4
5keymgr -t ${keyName} > $1
6sops -p 'A1C7C95E6CAF0A965CB47277BCF50A89C1B1F362,30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51' --input-type=binary --output-type=binary -e -i $1
diff --git a/hosts/vidhar/dns/keys/local.yaml b/hosts/vidhar/dns/keys/local.yaml
new file mode 100644
index 00000000..e66f4b61
--- /dev/null
+++ b/hosts/vidhar/dns/keys/local.yaml
@@ -0,0 +1,26 @@
1{
2 "data": "ENC[AES256_GCM,data:hpWdnmsmBmO01PkTlmRLHdmXrPX6POuU/PWrOUMgH6glThzsFdk84tskUExnsl3N39ryCmgZwotIZ8zCWduPBn+nN3VTEP5Z4xltC8I82C6F283gWC3gxpTXFSwF7JetRM5uBQV0FFd9iXHUySEHdzoRqsGuZTMYdT44Bm6gGQHyt7N3/EeLHyJKa7MH+SLLznjlaTnmrAxEyGP8Talda0s/mkh4nRqQnbxX6aOTQpQ=,iv:eRQuxRNQGU2Zwudaqjr+QvLLpJ5QqrjvAN/uL6x8hUs=,tag:CYEt1K+gOGiOX9qQR/Q9jw==,type:str]",
3 "sops": {
4 "kms": null,
5 "gcp_kms": null,
6 "azure_kv": null,
7 "hc_vault": null,
8 "age": null,
9 "lastmodified": "2022-03-15T13:30:32Z",
10 "mac": "ENC[AES256_GCM,data:PG4ywF/U6ITmdRB4OU5uXu54YabYt9Yyy2oYEMx0XpMlpKWH5bmg2qQNFakxBD6wCy2H6e3LmwcUl2N692crm3n/qQRNPQ0ETHVlaPlRFG85tiz/Ngi6tasoKG+ciLAXMy05c+yY6oENN7grm1TTMZRGSIyxo27ZU+k4kmz4eVM=,iv:fluwCnXHAJ/z2oGWCLXbjooymXbViPrZdVJOnoSrn1g=,tag:QtNGIKMBDtKnb3JPuRqmiA==,type:str]",
11 "pgp": [
12 {
13 "created_at": "2022-03-15T13:30:31Z",
14 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DbYDvGI0HDr0SAQdAQAK54tXtgsLn6MmWQC/4irGRJd160lpAxCIT+nt/MBUw\nznjpLnbZXSft1RQI6/B95udkm0U/MBKt7wSMe9I/Po44qJrqHqb4jofz6NCeqxD3\n0l4Bl/DpnWfam9knZFQ9NIEaKYWXSmVuxVduhpYYGopXUrKol8BVTdXU6qHaPKgV\nQc72FvezgyHngZwXNEggvS1IWPq4m6pamLi77e8hNGiQx5CiaFXWwCP4gY6A80pS\n=FNi5\n-----END PGP MESSAGE-----\n",
15 "fp": "A1C7C95E6CAF0A965CB47277BCF50A89C1B1F362"
16 },
17 {
18 "created_at": "2022-03-15T13:30:31Z",
19 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdA+/lLWPxgadpnWQlbAVbdzpbevoVKuaGrQmp79m4wKycw\nBeErMZugDNzHWXkTHXez5SpS94RYlGzhLcVLGfMg7C0h3wN192QaMrcH01udnjhK\n0l4BRYt9+9CCZL+Nb/ss+BIyOAFCZi2RkwzvXl9wVk+mb1As9/UYml9zqh/juU5F\nBZXqwNPA5RSNCoB0wy3A5yIB3uniMuYczTs67VHJ5cw2VVSQvXF5zue90i2F4mC4\n=IsU1\n-----END PGP MESSAGE-----\n",
20 "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51"
21 }
22 ],
23 "unencrypted_suffix": "_unencrypted",
24 "version": "3.7.1"
25 }
26} \ No newline at end of file
diff --git a/hosts/vidhar/dns/zones/arpa.in-addr.10.141.0.soa b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.0.soa
new file mode 100644
index 00000000..75e6b3a8
--- /dev/null
+++ b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.0.soa
@@ -0,0 +1,12 @@
1$ORIGIN 0.141.10.in-addr.arpa.
2$TTL 300
3@ IN SOA vidhar.lan.yggdrasil. root.yggdrasil.li. (
4 2022031504 ; serial
5 300 ; refresh
6 300 ; retry
7 300 ; expire
8 300 ; min TTL
9)
10
11 IN NS vidhar.lan.yggdrasil.
121 IN PTR vidhar.lan.yggdrasil.
diff --git a/hosts/vidhar/dns/zones/arpa.in-addr.10.141.1.soa b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.1.soa
new file mode 100644
index 00000000..2d535d56
--- /dev/null
+++ b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.1.soa
@@ -0,0 +1,14 @@
1$ORIGIN 1.141.10.in-addr.arpa.
2$TTL 300
3@ IN SOA vidhar.mgmt.yggdrasil. root.yggdrasil.li. (
4 2022031505 ; serial
5 300 ; refresh
6 300 ; retry
7 300 ; expire
8 300 ; min TTL
9)
10
11 IN NS vidhar.mgmt.yggdrasil.
121 IN PTR vidhar.mgmt.yggdrasil.
132 IN PTR switch01.mgmt.yggdrasil.
144 IN PTR ap01.mgmt.yggdrasil.
diff --git a/hosts/vidhar/dns/zones/arpa.in-addr.10.141.soa b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.soa
new file mode 100644
index 00000000..ea5a35f3
--- /dev/null
+++ b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.soa
@@ -0,0 +1,11 @@
1$ORIGIN 141.10.in-addr.arpa.
2$TTL 300
3@ IN SOA vidhar.lan.yggdrasil. root.yggdrasil.li. (
4 2022031505 ; serial
5 300 ; refresh
6 300 ; retry
7 300 ; expire
8 300 ; min TTL
9)
10
11 IN NS vidhar.lan.yggdrasil.
diff --git a/hosts/vidhar/dns/zones/yggdrasil.lan.soa b/hosts/vidhar/dns/zones/yggdrasil.lan.soa
new file mode 100644
index 00000000..c58b9a13
--- /dev/null
+++ b/hosts/vidhar/dns/zones/yggdrasil.lan.soa
@@ -0,0 +1,13 @@
1$ORIGIN lan.yggdrasil.
2$TTL 300
3@ IN SOA vidhar.lan.yggdrasil. root.yggdrasil.li. (
4 2022031504 ; serial
5 300 ; refresh
6 300 ; retry
7 300 ; expire
8 300 ; min TTL
9)
10
11 IN NS vidhar.lan.yggdrasil.
12
13vidhar IN A 10.141.0.1
diff --git a/hosts/vidhar/dns/zones/yggdrasil.mgmt.soa b/hosts/vidhar/dns/zones/yggdrasil.mgmt.soa
new file mode 100644
index 00000000..8a630a9a
--- /dev/null
+++ b/hosts/vidhar/dns/zones/yggdrasil.mgmt.soa
@@ -0,0 +1,15 @@
1$ORIGIN mgmt.yggdrasil.
2$TTL 300
3@ IN SOA vidhar.mgmt.yggdrasil. root.yggdrasil.li. (
4 2022031505 ; serial
5 300 ; refresh
6 300 ; retry
7 300 ; expire
8 300 ; min TTL
9)
10
11 IN NS vidhar.mgmt.yggdrasil.
12
13vidhar IN A 10.141.1.1
14switch01 IN A 10.141.1.2
15ap01 IN A 10.141.1.4
diff --git a/hosts/vidhar/dns/zones/yggdrasil.soa b/hosts/vidhar/dns/zones/yggdrasil.soa
new file mode 100644
index 00000000..6e66a063
--- /dev/null
+++ b/hosts/vidhar/dns/zones/yggdrasil.soa
@@ -0,0 +1,21 @@
1$ORIGIN yggdrasil.
2$TTL 300
3@ IN SOA vidhar.yggdrasil. root.yggdrasil.li. (
4 2022031504 ; serial
5 300 ; refresh
6 300 ; retry
7 300 ; expire
8 300 ; min TTL
9)
10
11 IN NS vidhar.yggdrasil.
12
13surtr IN AAAA 2a03:4000:52:ada:1::
14vidhar IN AAAA 2a03:4000:52:ada:1:1::
15sif IN AAAA 2a03:4000:52:ada:1:2::
16
17grafana.vidhar IN CNAME vidhar.yggdrasil.
18
19
20vidhar.lan IN A 10.141.0.1
21vidhar.mgmt IN A 10.141.1.1
diff --git a/hosts/vidhar/network/default.nix b/hosts/vidhar/network/default.nix
index 2d9a7b8f..85ddd4ef 100644
--- a/hosts/vidhar/network/default.nix
+++ b/hosts/vidhar/network/default.nix
@@ -1,6 +1,6 @@
1{ flake, config, lib, pkgs, ... }: 1{ ... }:
2{ 2{
3 imports = [ ./dsl.nix ./bifrost ]; 3 imports = [ ./dsl.nix ./bifrost ./dhcp ];
4 4
5 config = { 5 config = {
6 networking = { 6 networking = {
@@ -53,132 +53,6 @@
53 llmnr = "false"; 53 llmnr = "false";
54 }; 54 };
55 55
56 services.kea = {
57 dhcp4 = {
58 enable = true;
59 settings = {
60 valid-lifetime = 4000;
61 rebind-timer = 2000;
62 renew-timer = 1000;
63
64 interfaces-config = {
65 interfaces = [ "lan" "mgmt" ];
66 };
67
68 lease-database = {
69 name = "/var/lib/kea/dhcp4.leases";
70 persist = true;
71 type = "memfile";
72 };
73
74 client-classes = [
75 { name = "ipxe";
76 test = "option[77].hex == 'iPXE'";
77 next-server = "10.141.0.1";
78 boot-file-name = "netboot.ipxe";
79 only-if-required = true;
80 }
81 { name = "uefi-64";
82 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'";
83 only-if-required = true;
84 option-data = [
85 { name = "tftp-server-name"; data = "10.141.0.1"; }
86 ];
87 boot-file-name = "ipxe.efi";
88 }
89 { name = "uefi-32";
90 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00002' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00006'";
91 only-if-required = true;
92 option-data = [
93 { name = "tftp-server-name"; data = "10.141.0.1"; }
94 ];
95 boot-file-name = "i386-ipxe.efi";
96 }
97 { name = "legacy";
98 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'";
99 only-if-required = true;
100 option-data = [
101 { name = "tftp-server-name"; data = "10.141.0.1"; }
102 ];
103 boot-file-name = "undionly.kpxe";
104 }
105 ];
106
107 subnet4 = [
108 { subnet = "10.141.0.0/24";
109 option-data = [
110 { name = "domain-name-servers";
111 data = "10.141.0.1";
112 }
113 { name = "broadcast-address";
114 data = "10.141.0.255";
115 }
116 { name = "routers";
117 data = "10.141.0.1";
118 }
119 { name = "domain-name";
120 data = "yggdrasil";
121 }
122 ];
123 pools = [ { pool = "10.141.0.128 - 10.141.0.254"; } ];
124 reservations = [];
125 require-client-classes = ["ipxe" "uefi-64" "uefi-32" "legacy"];
126 }
127 { subnet = "10.141.1.0/24";
128 option-data = [
129 { name = "domain-name-servers";
130 data = "10.141.1.1";
131 }
132 { name = "broadcast-address";
133 data = "10.141.1.255";
134 }
135 ];
136 pools = [ { pool = "10.141.1.128 - 10.141.1.254"; } ];
137 reservations = [
138 { hostname = "switch01";
139 hw-address = "60:a4:b7:53:94:b5";
140 ip-address = "10.141.1.2";
141 }
142 { hostname = "ap01";
143 hw-address = "74:ac:b9:29:ad:9a";
144 ip-address = "10.141.1.4";
145 }
146 ];
147 }
148 { subnet = "10.141.2.0/24";
149 option-data = [
150 { name = "domain-name-servers";
151 data = "10.141.2.1";
152 }
153 { name = "broadcast-address";
154 data = "10.141.2.255";
155 }
156 { name = "routers";
157 data = "10.141.2.1";
158 }
159 ];
160 pools = [ { pool = "10.141.2.128 - 10.141.2.254"; } ];
161 reservations = [];
162 }
163 ];
164 };
165 };
166 dhcp6 = {
167 enable = true;
168 settings = {
169 interfaces-config = {
170 interfaces = [ "lan" ];
171 };
172
173 lease-database = {
174 name = "/var/lib/kea/dhcp6.leases";
175 persist = true;
176 type = "memfile";
177 };
178 };
179 };
180 };
181
182 systemd.network.networks = { 56 systemd.network.networks = {
183 "eno1" = { 57 "eno1" = {
184 matchConfig.Name = "eno1"; 58 matchConfig.Name = "eno1";
@@ -191,27 +65,5 @@
191 networkConfig.LinkLocalAddressing = "no"; 65 networkConfig.LinkLocalAddressing = "no";
192 }; 66 };
193 }; 67 };
194
195 systemd.services."installer-atftpd" = {
196 description = "TFTP Server for PXE Booting NixOS Installer";
197 after = [ "network.target" ];
198 wantedBy = [ "multi-user.target" ];
199 serviceConfig.ExecStart = let
200 installerBuild = flake.nixosConfigurations.installer-x86_64-linux-netboot.config.system.build;
201 ipxe = pkgs.ipxe.override {
202 additionalTargets = {
203 "bin-i386-efi/ipxe.efi" = "i386-ipxe.efi";
204 };
205 };
206 tftpRoot = pkgs.runCommandLocal "installer-netboot" {} ''
207 mkdir -p $out
208 install -m 0444 -t $out \
209 ${installerBuild.netbootRamdisk}/initrd \
210 ${installerBuild.kernel}/bzImage \
211 ${installerBuild.netbootIpxeScript}/netboot.ipxe \
212 ${ipxe}/ipxe.efi ${ipxe}/i386-ipxe.efi ${ipxe}/undionly.kpxe
213 '';
214 in "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address=10.141.0.1 ${tftpRoot}";
215 };
216 }; 68 };
217} 69}
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 @@
1{ flake, config, pkgs, lib, ... }:
2{
3 config = {
4 services.kea = {
5 dhcp4 = {
6 enable = true;
7 settings = {
8 valid-lifetime = 4000;
9 rebind-timer = 2000;
10 renew-timer = 1000;
11
12 interfaces-config = {
13 interfaces = [ "lan" "mgmt" ];
14 };
15
16 lease-database = {
17 name = "/var/lib/kea/dhcp4.leases";
18 persist = true;
19 type = "memfile";
20 };
21
22 client-classes = [
23 { name = "ipxe";
24 test = "option[77].hex == 'iPXE'";
25 next-server = "10.141.0.1";
26 boot-file-name = "netboot.ipxe";
27 only-if-required = true;
28 }
29 { name = "uefi-64";
30 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'";
31 only-if-required = true;
32 option-data = [
33 { name = "tftp-server-name"; data = "10.141.0.1"; }
34 ];
35 boot-file-name = "ipxe.efi";
36 }
37 { name = "uefi-32";
38 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00002' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00006'";
39 only-if-required = true;
40 option-data = [
41 { name = "tftp-server-name"; data = "10.141.0.1"; }
42 ];
43 boot-file-name = "i386-ipxe.efi";
44 }
45 { name = "legacy";
46 test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'";
47 only-if-required = true;
48 option-data = [
49 { name = "tftp-server-name"; data = "10.141.0.1"; }
50 ];
51 boot-file-name = "undionly.kpxe";
52 }
53 ];
54
55 dhcp-ddns.enable-updates = true;
56 ddns-send-updates = false;
57 ddns-override-client-update = true;
58 ddns-override-no-update = true;
59 ddns-replace-client-name = "when-not-present";
60 ddns-generated-prefix = "noname";
61 ddns-update-on-renew = true;
62
63 subnet4 = [
64 { subnet = "10.141.0.0/24";
65 option-data = [
66 { name = "domain-name-servers";
67 data = "10.141.0.1";
68 }
69 { name = "broadcast-address";
70 data = "10.141.0.255";
71 }
72 { name = "routers";
73 data = "10.141.0.1";
74 }
75 { name = "domain-name";
76 data = "yggdrasil";
77 }
78 { name = "domain-search";
79 data = "lan.yggdrasil, yggdrasil";
80 }
81 ];
82 ddns-send-updates = true;
83 ddns-qualifying-suffix = "lan.yggdrasil";
84 pools = [ { pool = "10.141.0.128 - 10.141.0.254"; } ];
85 require-client-classes = ["ipxe" "uefi-64" "uefi-32" "legacy"];
86 reservations = [
87 { hostname = "sif";
88 hw-address = "3c:e1:a1:52:24:35";
89 }
90 { hostname = "sif";
91 hw-address = "ee:32:68:76:83:ac";
92 }
93 { hostname = "sif";
94 hw-address = "48:2a:e3:64:62:97";
95 }
96 { hostname = "eos";
97 hw-address = "00:d8:61:79:c5:40";
98 }
99 ];
100 }
101 { subnet = "10.141.1.0/24";
102 option-data = [
103 { name = "domain-name-servers";
104 data = "10.141.1.1";
105 }
106 { name = "broadcast-address";
107 data = "10.141.1.255";
108 }
109 { name = "domain-name";
110 data = "yggdrasil";
111 }
112 { name = "domain-search";
113 data = "mgmt.yggdrasil, yggdrasil";
114 }
115 ];
116 ddns-send-updates = true;
117 ddns-qualifying-suffix = "mgmt.yggdrasil";
118 pools = [ { pool = "10.141.1.128 - 10.141.1.254"; } ];
119 reservations = [
120 { hostname = "switch01";
121 hw-address = "60:a4:b7:53:94:b5";
122 ip-address = "10.141.1.2";
123 }
124 { hostname = "ap01";
125 hw-address = "74:ac:b9:29:ad:9a";
126 ip-address = "10.141.1.4";
127 }
128 ];
129 }
130 { subnet = "10.141.2.0/24";
131 option-data = [
132 { name = "domain-name-servers";
133 data = "10.141.2.1";
134 }
135 { name = "broadcast-address";
136 data = "10.141.2.255";
137 }
138 { name = "routers";
139 data = "10.141.2.1";
140 }
141 ];
142 ddns-send-updates = false;
143 pools = [ { pool = "10.141.2.128 - 10.141.2.254"; } ];
144 reservations = [];
145 }
146 ];
147 };
148 };
149 dhcp6 = {
150 enable = true;
151 settings = {
152 interfaces-config = {
153 interfaces = [ "lan" ];
154 };
155
156 lease-database = {
157 name = "/var/lib/kea/dhcp6.leases";
158 persist = true;
159 type = "memfile";
160 };
161 };
162 };
163 dhcp-ddns = {
164 enable = true;
165 settings = {
166 forward-ddns = {
167 ddns-domains = [
168 { name = "lan.yggdrasil.";
169 dns-servers = [
170 { ip-address = "127.0.0.1";
171 port = 5353;
172 key-name = "local_key";
173 }
174 ];
175 }
176 { name = "mgmt.yggdrasil.";
177 dns-servers = [
178 { ip-address = "127.0.0.1";
179 port = 5353;
180 key-name = "local_key";
181 }
182 ];
183 }
184 ];
185 };
186 reverse-ddns = {
187 ddns-domains = [
188 { name = "0.141.10.in-addr.arpa.";
189 dns-servers = [
190 { ip-address = "127.0.0.1";
191 port = 5353;
192 key-name = "local_key";
193 }
194 ];
195 }
196 { name = "1.141.10.in-addr.arpa.";
197 dns-servers = [
198 { ip-address = "127.0.0.1";
199 port = 5353;
200 key-name = "local_key";
201 }
202 ];
203 }
204 ];
205 };
206 };
207 };
208 };
209
210 systemd.services.kea-dhcp-ddns-server = {
211 preStart = let
212 configLines = [
213 "<?include \"\${CREDENTIALS_DIRECTORY}/knot-tsig.json.frag\"?>"
214 ] ++ lib.mapAttrsToList (k: v:
215 "\"${k}\": ${builtins.toJSON v}"
216 ) config.services.kea.dhcp-ddns.settings;
217
218 config-template = pkgs.writeText "dhcp-ddns.conf" ''
219 {"DhcpDdns": {
220 ${lib.concatStringsSep ",\n " configLines}
221 }}
222 '';
223 in ''
224 ${pkgs.envsubst}/bin/envsubst -i "${config-template}" -o "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf"
225 '';
226
227 serviceConfig = {
228 ExecStart = lib.mkForce ''
229 ${pkgs.kea}/bin/kea-dhcp-ddns -c "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf" ${lib.escapeShellArgs config.services.kea.dhcp-ddns.extraArgs}
230 '';
231 LoadCredential = [
232 "knot-tsig.json.frag:${config.sops.secrets."kea-knot-tsig.json.frag".path}"
233 ];
234 };
235 };
236
237 sops.secrets."kea-knot-tsig.json.frag" = {
238 format = "binary";
239 sopsFile = ./knot-tsig.json.frag;
240 };
241
242 systemd.services."installer-atftpd" = {
243 description = "TFTP Server for PXE Booting NixOS Installer";
244 after = [ "network.target" ];
245 wantedBy = [ "multi-user.target" ];
246 serviceConfig.ExecStart = let
247 installerBuild = flake.nixosConfigurations.installer-x86_64-linux-netboot.config.system.build;
248 ipxe = pkgs.ipxe.override {
249 additionalTargets = {
250 "bin-i386-efi/ipxe.efi" = "i386-ipxe.efi";
251 };
252 };
253 tftpRoot = pkgs.runCommandLocal "installer-netboot" {} ''
254 mkdir -p $out
255 install -m 0444 -t $out \
256 ${installerBuild.netbootRamdisk}/initrd \
257 ${installerBuild.kernel}/bzImage \
258 ${installerBuild.netbootIpxeScript}/netboot.ipxe \
259 ${ipxe}/ipxe.efi ${ipxe}/i386-ipxe.efi ${ipxe}/undionly.kpxe
260 '';
261 in "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address=10.141.0.1 ${tftpRoot}";
262 };
263 };
264}
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 @@
1{
2 "data": "ENC[AES256_GCM,data:cGcoqYZ341xQOFukDm4J5KDfG6+NaNbk2U2k4YGneRsAoPJZe/8KDmVr8TBWFCXXbuzeCGbiuXRVBmtYSEIqbqTN4u00RdQgpeL72cB3ZFd2c7cideEQV5z802pqFfXSlmLBC01OPG3TwAgk6xhQYSn5IcBTIL6fRF235Y9Q8k/X96rhfwPRVq84,iv:UoweWBcVuQIXeWFFl/WNUHLXG8nEri1UuTskC2I26hU=,tag:TJldVr2LDTmKA3ozZoX+cQ==,type:str]",
3 "sops": {
4 "kms": null,
5 "gcp_kms": null,
6 "azure_kv": null,
7 "hc_vault": null,
8 "age": null,
9 "lastmodified": "2022-03-15T13:52:17Z",
10 "mac": "ENC[AES256_GCM,data:rTelaGx5S2E2oYPNGfctFbgDKdyRX8tpVTqLtpcCAJ8MS5ppFTjnSwYi4yQHvTicfAPNz7hGJYAnTdyC2QDTciJgkS6KC3CCXWCimkTybBdVW4Azwz9iBZCpWu+rB1vcQhSLlLCaKmKskkqDZZ5+mfuaXc+TT2uwTA0SDtZWvnM=,iv:ANCZ1fHy6w/svEE53o7rWsp5qU15qoriqyVMzClH6J0=,tag:H92RM5GuLIl9/kslq4tzkQ==,type:str]",
11 "pgp": [
12 {
13 "created_at": "2022-03-15T13:50:52Z",
14 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DbYDvGI0HDr0SAQdANAtB0un04iI+foGRefRK249LhT6Mz+yzdhkWa0UYoxcw\nUGDSh6la4ijiaqdeVfJ3vckXfAqee7dLseNQ64dafdlk2hVI0ZNv6mjfwgWk698v\n0l4B4EOHfDrmFNhZFcj1/sCRnukgx7PSeybZn3miTLQgMGOydrfYuisA3we/4EUo\nU55PGINdtAu268OUHQjj3yF1S72Yeh1MXEdvajRQdqorQJ4TpsPUtJolM25Df/kK\n=etIn\n-----END PGP MESSAGE-----\n",
15 "fp": "A1C7C95E6CAF0A965CB47277BCF50A89C1B1F362"
16 },
17 {
18 "created_at": "2022-03-15T13:50:52Z",
19 "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",
20 "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51"
21 }
22 ],
23 "unencrypted_suffix": "_unencrypted",
24 "version": "3.7.1"
25 }
26} \ No newline at end of file