summaryrefslogtreecommitdiff
path: root/hosts/vidhar/network
diff options
context:
space:
mode:
Diffstat (limited to 'hosts/vidhar/network')
-rw-r--r--hosts/vidhar/network/default.nix49
-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
-rw-r--r--hosts/vidhar/network/gpon.nix271
-rw-r--r--hosts/vidhar/network/pap-secrets26
-rw-r--r--hosts/vidhar/network/pppoe/default.nix184
-rw-r--r--hosts/vidhar/network/pppoe/no-double-timeout.patch13
-rw-r--r--hosts/vidhar/network/pppoe/o2-password18
-rw-r--r--hosts/vidhar/network/ruleset.nft105
9 files changed, 517 insertions, 441 deletions
diff --git a/hosts/vidhar/network/default.nix b/hosts/vidhar/network/default.nix
index 0643f0bb..3b48a7fc 100644
--- a/hosts/vidhar/network/default.nix
+++ b/hosts/vidhar/network/default.nix
@@ -1,9 +1,9 @@
1{ pkgs, lib, ... }: 1{ pkgs, lib, config, ... }:
2 2
3with lib; 3with lib;
4 4
5{ 5{
6 imports = [ ./gpon.nix ./bifrost ./dhcp ]; 6 imports = [ ./pppoe ./bifrost ./dhcp ];
7 7
8 config = { 8 config = {
9 networking = { 9 networking = {
@@ -61,7 +61,9 @@ with lib;
61 firewall.enable = false; 61 firewall.enable = false;
62 nftables = { 62 nftables = {
63 enable = true; 63 enable = true;
64 rulesetFile = ./ruleset.nft; 64 rulesetFile = pkgs.replaceVars ./ruleset.nft {
65 inherit (config.networking) pppInterface;
66 };
65 }; 67 };
66 68
67 resolvconf = { 69 resolvconf = {
@@ -76,16 +78,29 @@ with lib;
76 78
77 environment.etc."dnssec-trust-anchors.d/root.positive".source = "${pkgs.dns-root-data}/root.ds"; 79 environment.etc."dnssec-trust-anchors.d/root.positive".source = "${pkgs.dns-root-data}/root.ds";
78 80
79 systemd.network.networks = { 81 systemd.network = {
80 "eno1" = { 82 networks = {
81 matchConfig.Name = "eno1"; 83 "eno1" = {
82 linkConfig = { 84 matchConfig.Name = "eno1";
83 ActivationPolicy = "down"; 85 linkConfig = {
86 ActivationPolicy = "down";
87 };
88 };
89 "eno2" = {
90 matchConfig.Name = "eno2";
91 networkConfig.LinkLocalAddressing = "no";
92 };
93 "40-lan" = {
94 matchConfig.Name = "lan";
95 networkConfig = {
96 IPv6SendRA = true;
97 DHCPPrefixDelegation = true;
98 };
99 ipv6SendRAConfig = {
100 DNS = "_link_local";
101 Domains = ["lan.yggdrasil" "yggdrasil"];
102 };
84 }; 103 };
85 };
86 "eno2" = {
87 matchConfig.Name = "eno2";
88 networkConfig.LinkLocalAddressing = "no";
89 }; 104 };
90 }; 105 };
91 106
@@ -103,13 +118,21 @@ with lib;
103 /srv/nfs/nix-store 10.141.0.0/24(ro,async,root_squash) 2a03:4000:52:ada:1::/80(ro,async,root_squash) 118 /srv/nfs/nix-store 10.141.0.0/24(ro,async,root_squash) 2a03:4000:52:ada:1::/80(ro,async,root_squash)
104 ''; 119 '';
105 }; 120 };
106 settings.nfsd.vers3 = false; 121 settings.nfsd = {
122 rdma = true;
123 vers3 = false;
124 vers4 = true;
125 "vers4.0" = false;
126 "vers4.1" = false;
127 "vers4.2" = true;
128 };
107 }; 129 };
108 130
109 fileSystems = { 131 fileSystems = {
110 "/srv/nfs/nix-store" = { 132 "/srv/nfs/nix-store" = {
111 device = "/nix/store"; 133 device = "/nix/store";
112 options = [ "bind" ]; 134 options = [ "bind" ];
135 fsType = "none";
113 }; 136 };
114 }; 137 };
115 }; 138 };
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}
diff --git a/hosts/vidhar/network/gpon.nix b/hosts/vidhar/network/gpon.nix
deleted file mode 100644
index 1628159c..00000000
--- a/hosts/vidhar/network/gpon.nix
+++ /dev/null
@@ -1,271 +0,0 @@
1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 pppInterface = config.networking.pppInterface;
7in {
8 options = {
9 networking.pppInterface = mkOption {
10 type = types.str;
11 default = "gpon";
12 };
13 };
14
15 config = {
16 networking.vlans = {
17 telekom = {
18 id = 7;
19 interface = "eno2";
20 };
21 };
22
23 services.pppd = {
24 enable = true;
25 peers.telekom.config = ''
26 nodefaultroute
27 ifname ${pppInterface}
28 lcp-echo-adaptive
29 lcp-echo-failure 5
30 lcp-echo-interval 1
31 maxfail 0
32 mtu 1492
33 mru 1492
34 plugin pppoe.so
35 name telekom
36 user 002576900250551137425220#0001@t-online.de
37 nic-telekom
38 debug
39 +ipv6
40 '';
41 };
42 systemd.services."pppd-telekom" = {
43 stopIfChanged = true;
44
45 serviceConfig = {
46 PIDFile = "/run/pppd/${pppInterface}.pid";
47 };
48 restartTriggers = with config; [
49 environment.etc."ppp/ip-pre-up".source
50 environment.etc."ppp/ip-up".source
51 environment.etc."ppp/ip-down".source
52 # sops.secrets."pap-secrets".sopsFile
53 ];
54 };
55 sops.secrets."pap-secrets" = {
56 format = "binary";
57 sopsFile = ./pap-secrets;
58 path = "/etc/ppp/pap-secrets";
59 };
60
61 environment.etc = {
62 "ppp/ip-pre-up".source = let
63 app = pkgs.writeShellApplication {
64 name = "ip-pre-up";
65 runtimeInputs = with pkgs; [ iproute2 ethtool ];
66 text = ''
67 ethtool -K telekom tso off gso off gro off
68
69 ip link del "ifb4${pppInterface}" || true
70 ip link add name "ifb4${pppInterface}" type ifb
71 ip link set "ifb4${pppInterface}" up
72
73 tc qdisc del dev "ifb4${pppInterface}" root || true
74 tc qdisc del dev "${pppInterface}" ingress || true
75 tc qdisc del dev "${pppInterface}" root || true
76
77 tc qdisc add dev "${pppInterface}" handle ffff: ingress
78 tc filter add dev "${pppInterface}" parent ffff: basic action ctinfo dscp 0x0000003f 0x00000040 action mirred egress redirect dev "ifb4${pppInterface}"
79 tc qdisc replace dev "ifb4${pppInterface}" root cake memlimit 128Mb overhead 35 mpu 74 regional diffserv4 bandwidth 285mbit
80 tc qdisc replace dev "${pppInterface}" root cake memlimit 128Mb overhead 35 mpu 74 regional nat diffserv4 wash bandwidth 143mbit
81 '';
82 };
83 in "${app}/bin/${app.meta.mainProgram}";
84 "ppp/ip-up".source = let
85 app = pkgs.writeShellApplication {
86 name = "ip-up";
87 runtimeInputs = with pkgs; [ iproute2 ];
88 text = ''
89 ip route add default via "$5" dev "${pppInterface}" metric 512
90 '';
91 };
92 in "${app}/bin/${app.meta.mainProgram}";
93 "ppp/ip-down".source = let
94 app = pkgs.writeShellApplication {
95 name = "ip-down";
96 runtimeInputs = with pkgs; [ iproute2 ];
97 text = ''
98 ip link del "ifb4${pppInterface}"
99 '';
100 };
101 in "${app}/bin/${app.meta.mainProgram}";
102 };
103
104 systemd.network.networks.${pppInterface} = {
105 matchConfig = {
106 Name = pppInterface;
107 };
108 dns = [ "::1" "127.0.0.1" ];
109 domains = [ "~." ];
110 networkConfig = {
111 LinkLocalAddressing = "no";
112 DNSSEC = true;
113 };
114 };
115
116 services.corerad = {
117 enable = true;
118 settings = {
119 interfaces = [
120 { name = pppInterface;
121 monitor = true;
122 verbose = true;
123 }
124 { name = "lan";
125 advertise = true;
126 verbose = true;
127 prefix = [{ prefix = "::/64"; }];
128 route = [{ prefix = "::/0"; }];
129 rdnss = [{ servers = ["::"]; }];
130 dnssl = [{ domain_names = ["yggdrasil"]; }];
131 # other_config = true;
132 }
133 ];
134
135 debug = {
136 address = "localhost:9430";
137 prometheus = true;
138 };
139 };
140 };
141 services.ndppd = {
142 enable = true;
143 proxies = {
144 ${pppInterface} = {
145 router = true;
146 rules = {
147 lan = {
148 method = "iface";
149 interface = "lan";
150 network = "::/0";
151 };
152 };
153 };
154 };
155 };
156 boot.kernelModules = [ "ifb" ];
157 boot.kernel.sysctl = {
158 "net.ipv6.conf.all.forwarding" = true;
159 "net.ipv6.conf.default.forwarding" = true;
160 "net.ipv4.conf.all.forwarding" = true;
161 "net.ipv4.conf.default.forwarding" = true;
162
163 "net.core.rmem_max" = 4194304;
164 "net.core.wmem_max" = 4194304;
165 };
166 systemd.services."pppd-telekom" = {
167 bindsTo = [ "sys-subsystem-net-devices-telekom.device" ];
168 after = [ "sys-subsystem-net-devices-telekom.device" ];
169 };
170 systemd.services."dhcpcd-${pppInterface}" = {
171 wantedBy = [ "multi-user.target" "network-online.target" "pppd-telekom.service" ];
172 bindsTo = [ "pppd-telekom.service" ];
173 after = [ "pppd-telekom.service" ];
174 wants = [ "network.target" ];
175 before = [ "network-online.target" ];
176
177 path = with pkgs; [ dhcpcd nettools openresolv ];
178 unitConfig.ConditionCapability = "CAP_NET_ADMIN";
179
180 stopIfChanged = true;
181
182 preStart = ''
183 i=0
184
185 while [[ -z "$(${pkgs.iproute2}/bin/ip -6 addr show dev ${pppInterface} scope link)" ]]; do
186 ${pkgs.coreutils}/bin/sleep 0.1
187 i=$((i + 1))
188 if [[ "$i" -ge 10 ]]; then
189 exit 1
190 fi
191 done
192 '';
193
194 postStop = ''
195 for dev in lan; do
196 ${pkgs.iproute2}/bin/ip -6 a show dev "''${dev}" scope global | ${pkgs.gnugrep}/bin/grep inet6 | ${pkgs.gawk}/bin/awk '{ print $2; }' | ${pkgs.findutils}/bin/xargs -I '{}' -- ${pkgs.iproute2}/bin/ip addr del '{}' dev "''${dev}"
197 done
198 '';
199
200 serviceConfig = let
201 dhcpcdConf = pkgs.writeText "dhcpcd.conf" ''
202 duid
203 vendorclassid
204 ipv6only
205
206 nooption domain_name_servers, domain_name, domain_search
207 option classless_static_routes
208 option interface_mtu
209
210 option host_name
211 option rapid_commit
212 require dhcp_server_identifier
213 slaac private
214
215 nohook resolv.conf
216 ipv6ra_autoconf
217 iaid 1195061668
218 ipv6rs # enable routing solicitation for WAN adapter
219 ia_pd 1 lan/0/64/0 # request a PD and assign it to the LAN
220
221 reboot 0
222
223 waitip 6
224 '';
225 in {
226 Type = "forking";
227 PIDFile = "/var/run/dhcpcd/${pppInterface}.pid";
228 RuntimeDirectory = "dhcpcd";
229 ExecStart = "@${pkgs.dhcpcd}/sbin/dhcpcd dhcpcd -q --config ${dhcpcdConf} ${pppInterface}";
230 ExecReload = "${pkgs.dhcpcd}/sbin/dhcpcd --rebind ${pppInterface}";
231 Restart = "always";
232 RestartSec = "5";
233 };
234 };
235 systemd.services.ndppd = {
236 wantedBy = [ "dhcpcd-${pppInterface}.service" ];
237 bindsTo = [ "dhcpcd-${pppInterface}.service" ];
238 after = [ "dhcpcd-${pppInterface}.service" ];
239
240 serviceConfig = {
241 Restart = "always";
242 RestartSec = "5";
243 };
244 };
245 systemd.services.corerad = {
246 wantedBy = [ "dhcpcd-${pppInterface}.service" ];
247 bindsTo = [ "dhcpcd-${pppInterface}.service" ];
248 after = [ "dhcpcd-${pppInterface}.service" ];
249
250 serviceConfig = {
251 Restart = lib.mkForce "always";
252 RestartSec = "5";
253 };
254 };
255 users.users.dhcpcd = {
256 isSystemUser = true;
257 group = "dhcpcd";
258 };
259 users.groups.dhcpcd = {};
260
261 systemd.services.unbound = {
262 wantedBy = [ "dhcpcd-${pppInterface}.service" ];
263 bindsTo = [ "dhcpcd-${pppInterface}.service" ];
264 after = [ "dhcpcd-${pppInterface}.service" ];
265
266 serviceConfig = {
267 Restart = lib.mkForce "always";
268 };
269 };
270 };
271}
diff --git a/hosts/vidhar/network/pap-secrets b/hosts/vidhar/network/pap-secrets
deleted file mode 100644
index 3516de6c..00000000
--- a/hosts/vidhar/network/pap-secrets
+++ /dev/null
@@ -1,26 +0,0 @@
1{
2 "data": "ENC[AES256_GCM,data:BOyWdys7Oja54Ijv5j+kqufdokQe0onnqw/gVxpNOMf+YI/LlzJscaEtGqPh3ehVtYoSWGumCBPrjdq/zhYq4VV/PCtdeu3MnX1CH2B5bH0mFs0eXcqeGK6NErz/b5nEglv4Z19ig2CUDlbvi8h1zZAEjxTNKhT16ItCtJnBCsIoiMl2QcTTWMyh4a02v3wA1UrOQZvFuCgCHmRoBE6vpREyB23gQdrdKLk7D1LLw5C1aZnzQOhFsgs7bVjOcBnmwTao8ntXxw==,iv:X5FgYkl3DGA/lkRsoc+5XrK3Nlp/ldnFigpXpYNfSJE=,tag:qUH7m9NzuVNnOfr3rRgaOg==,type:str]",
3 "sops": {
4 "kms": null,
5 "gcp_kms": null,
6 "azure_kv": null,
7 "hc_vault": null,
8 "age": [
9 {
10 "recipient": "age1qffdqvy9arld9zd5a5cylt0n98xhcns5shxhrhwjq5g4qa844ejselaa4l",
11 "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwYTFaTDZRbDd6cFBRSTNN\nVk1kcFJXRG9TT21IMDZsVmtoZjBTNDNjeDFzCkhxNEI2Ujd6SW1STG43eE5EdzZa\nS3phenJZN0RxajBXQ1BnbUhTa3htdFEKLS0tIGVlT3lReHJSQ2UvQ1FST0M0RzVP\nNmxWNzJmNlFPclJTeDUycDJiUzA4Yk0K4JHtkEPY49TGnKPZzEoEZ131RxeQEWkR\nK1ftH2ilr2tUhiErhpqxoTqfAm33xvruqTsePxh1uC7svzKtKBlS2g==\n-----END AGE ENCRYPTED FILE-----\n"
12 }
13 ],
14 "lastmodified": "2021-11-15T08:30:09Z",
15 "mac": "ENC[AES256_GCM,data:TAgZ4ktdN9sZPMo1UtwjKdTM2QBjLorcm84HYXTGYNNEorPoqrXAWOvyWRLjx+zxzpRuDLBPQHCkjwkVO2CctxnTaWPMwITbYtQqj/5ZxACuAeX8MaSximB8s5MJK2faCuVXEnFehbnnPr5Fs8ZsgHwu2iH6DU8ScLEkgckzGV0=,iv:keUbKwWfoIIBsp5Rsm2lEba1ZHAozQY2YpA6p5qDBiU=,tag:1llGytMGvOjSVYKJXGUmXg==,type:str]",
16 "pgp": [
17 {
18 "created_at": "2023-01-30T10:58:50Z",
19 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdA+cwEt6Gv5oKvym4ceJek+J/5guNpmsLLXWIY5CCCSXUw\npXyQpqxm7LQnasIqYNNsNCVbB1mAu6WU6MKn0BG03YWjr8buLB+7PpwZcxeZzRfD\n0l4BAsl+vKwa2YSMCR+EWYSfeEzEVHqoGBJ60dYXuiFiNZInCik+g69PdhsGygNH\nRtIcRiCB8t94GkvdWySTq5ohi1wKOe224l9evbt4zXntVngCHxixuufLrr3Cj+EE\n=3lw4\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/network/pppoe/default.nix b/hosts/vidhar/network/pppoe/default.nix
new file mode 100644
index 00000000..ffb97f10
--- /dev/null
+++ b/hosts/vidhar/network/pppoe/default.nix
@@ -0,0 +1,184 @@
1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 inherit (config.networking) pppInterface;
7in {
8 options = {
9 networking.pppInterface = mkOption {
10 type = types.str;
11 default = "ppp";
12 };
13 };
14
15 config = {
16 networking.vlans = {
17 pppoe = {
18 id = 7;
19 interface = "eno2";
20 };
21 };
22
23 services.pppd = {
24 enable = true;
25 package = pkgs.ppp.overrideAttrs (oldAttrs: {
26 patches = [
27 ./no-double-timeout.patch
28 ] ++ (oldAttrs.patches or []);
29 });
30 peers = {
31 o2.config = ''
32 user DSL0004874856014@s93.bbi-o2.de
33 '';
34 };
35 };
36 systemd.services."pppd-o2" = {
37 stopIfChanged = true;
38
39 restartTriggers = with config; [
40 environment.etc."ppp/pap-secrets".source
41 environment.etc."ppp/options".source
42 environment.etc."ppp/ip-pre-up".source
43 environment.etc."ppp/ip-up".source
44 environment.etc."ppp/ip-down".source
45 ];
46
47 serviceConfig = {
48 LoadCredential = [
49 "password:${config.sops.secrets."o2-password".path}"
50 ];
51
52 RestartSec = lib.mkForce "50ms";
53 RestartMaxDelaySec = "5s";
54 RestartSteps = 4;
55 StartLimitBurst = 10;
56
57 ProtectHome = lib.mkForce "tmpfs";
58 };
59
60 bindsTo = [ "sys-subsystem-net-devices-pppoe.device" ];
61 after = [ "sys-subsystem-net-devices-pppoe.device" ];
62 };
63 systemd.services."reset-failed-pppd-o2" = {
64 serviceConfig = {
65 Type = "oneshot";
66 ExecStart = "${lib.getExe' config.systemd.package "systemctl"} reset-failed pppd-o2.service";
67 };
68 };
69 systemd.timers."reset-failed-pppd-o2" = {
70 wantedBy = ["pppd-o2.service"];
71 after = ["pppd-o2.service"];
72 bindsTo = ["pppd-o2.service"];
73 timerConfig = {
74 OnActiveSec = "30s";
75 RemainAfterElapse = false;
76 };
77 };
78 sops.secrets."o2-password" = {
79 format = "binary";
80 sopsFile = ./o2-password;
81 };
82
83 environment.etc = {
84 "ppp/options".text = ''
85 nodefaultroute
86 ifname ${pppInterface}
87 lcp-echo-adaptive
88 lcp-echo-failure 10
89 lcp-echo-interval 1
90 maxfail 0
91 mtu 1492
92 mru 1492
93 plugin pppoe.so
94 pppoe-padi-timeout 1
95 pppoe-padi-attempts 10
96 nic-pppoe
97 debug
98 +ipv6
99 '';
100 "ppp/pap-secrets" = {
101 mode = "0400";
102 text = ''
103 DSL0004874856014@s93.bbi-o2.de * @/run/credentials/pppd-o2.service/password *
104 '';
105 };
106 "ppp/ip-pre-up".source = pkgs.resholve.writeScript "ip-pre-up" {
107 interpreter = pkgs.runtimeShell;
108 inputs = [ pkgs.iproute2 pkgs.ethtool ];
109 execer = [
110 "cannot:${lib.getExe' pkgs.iproute2 "ip"}"
111 "cannot:${lib.getExe' pkgs.iproute2 "tc"}"
112 ];
113 } ''
114 ethtool -K pppoe tso off gso off gro off
115
116 ip link del "ifb4$1" || true
117 ip link add name "ifb4$1" type ifb
118 ip link set "ifb4$1" up
119
120 tc qdisc del dev "ifb4$1" root || true
121 tc qdisc del dev "$1" ingress || true
122 tc qdisc del dev "$1" root || true
123
124 tc qdisc add dev "$1" handle ffff: ingress
125 tc filter add dev "$1" parent ffff: basic action ctinfo dscp 0x0000003f 0x00000040 action mirred egress redirect dev "ifb4$1"
126 tc qdisc replace dev "ifb4$1" root cake memlimit 128Mb pppoe-ptm nat diffserv4 ingress rtt 15ms bandwidth 110mbit
127 tc qdisc replace dev "$1" root cake memlimit 128Mb pppoe-ptm nat diffserv4 wash rtt 15ms bandwidth 28mbit
128 '';
129 "ppp/ip-up".source = pkgs.resholve.writeScript "ip-up" {
130 interpreter = pkgs.runtimeShell;
131 inputs = [ pkgs.iproute2 ];
132 execer = [ "cannot:${lib.getExe' pkgs.iproute2 "ip"}" ];
133 } ''
134 ip addr add "$4" peer "$5"/32 dev "$1"
135 ip route add default dev "$1" metric 512
136 '';
137 "ppp/ip-down".source = pkgs.resholve.writeScript "ip-down" {
138 interpreter = pkgs.runtimeShell;
139 inputs = [ pkgs.iproute2 ];
140 execer = [ "cannot:${lib.getExe' pkgs.iproute2 "ip"}" ];
141 } ''
142 ip link del "ifb4$1"
143 '';
144 };
145
146 systemd.package = pkgs.systemd.overrideAttrs (oldAttrs: {
147 patches = (oldAttrs.patches or []) ++ [
148 (pkgs.fetchpatch {
149 url = "https://github.com/sysedwinistrator/systemd/commit/b9691a43551739ddacdb8d53a4312964c3ddfa08.patch";
150 hash = "sha256-TLfOTFodLzCVywnF4Xp4BR2Pja0Qq4ItE/yaKkzI414=";
151 })
152 ];
153 });
154
155 systemd.network.networks = {
156 "40-${pppInterface}" = {
157 matchConfig.Name = pppInterface;
158 dns = [ "::1" "127.0.0.1" ];
159 domains = [ "~." ];
160 networkConfig = {
161 DHCP = true;
162 DNSSEC = true;
163 };
164 dhcpV6Config = {
165 PrefixDelegationHint = "::/64";
166 WithoutRA = "solicit";
167 };
168 };
169 };
170
171 boot.kernelModules = [ "ifb" ];
172 boot.kernel.sysctl = {
173 "net.ipv6.conf.all.forwarding" = true;
174 "net.ipv6.conf.default.forwarding" = true;
175 "net.ipv4.conf.all.forwarding" = true;
176 "net.ipv4.conf.default.forwarding" = true;
177
178 "net.ipv4.tcp_ecn" = 1;
179
180 "net.core.rmem_max" = 4194304;
181 "net.core.wmem_max" = 4194304;
182 };
183 };
184}
diff --git a/hosts/vidhar/network/pppoe/no-double-timeout.patch b/hosts/vidhar/network/pppoe/no-double-timeout.patch
new file mode 100644
index 00000000..53f41ae1
--- /dev/null
+++ b/hosts/vidhar/network/pppoe/no-double-timeout.patch
@@ -0,0 +1,13 @@
1diff --git i/pppd/plugins/pppoe/discovery.c w/pppd/plugins/pppoe/discovery.c
2index 86bda61..8060558 100644
3--- i/pppd/plugins/pppoe/discovery.c
4+++ w/pppd/plugins/pppoe/discovery.c
5@@ -686,7 +686,7 @@ discovery1(PPPoEConnection *conn, int waitWholeTimeoutForPADO)
6 conn->discoveryState = STATE_SENT_PADI;
7 waitForPADO(conn, timeout, waitWholeTimeoutForPADO);
8
9- timeout *= 2;
10+ // timeout *= 2;
11 } while (conn->discoveryState == STATE_SENT_PADI);
12 }
13
diff --git a/hosts/vidhar/network/pppoe/o2-password b/hosts/vidhar/network/pppoe/o2-password
new file mode 100644
index 00000000..cd3aed78
--- /dev/null
+++ b/hosts/vidhar/network/pppoe/o2-password
@@ -0,0 +1,18 @@
1{
2 "data": "ENC[AES256_GCM,data:mxHA3rrs5Sc50jAP,iv:iW1ua7wjZR8rPwXw21TdFK+fbfosc1CmnrTG34OJ2zM=,tag:pZ/FAHupnKy0wHtF6RN7yA==,type:str]",
3 "sops": {
4 "age": [
5 {
6 "recipient": "age1rmmhetcmllq0ahl5qznlr0eya2zdxwl9h6y5wnl97d2wtyx5t99sm2u866",
7 "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpUzAvSlJkSFhhRTFLY0VO\nU1VYbFhpMEpxaFhlb2NyS0xDNU5oMm9EZzJnCm5vbTM4c3lFMU5EajhwTGd6MTVx\nZTFmNVlyaVZuRy9hL2VnWFR0TTNEemsKLS0tIDdTemNMTTllQ1pmb0JNTlVGcTlU\nWjQ2MW4yVmtvRng3TlRDbmpHdmRkbUEKtIVAq4aZD6rhtX7+67EE5eOKAtGsVpBg\nPkfjkyV8ifBEx/lwDaJSHpLPfkbI9oArTL8BloodJEEGql5PXZxtvg==\n-----END AGE ENCRYPTED FILE-----\n"
8 },
9 {
10 "recipient": "age1qffdqvy9arld9zd5a5cylt0n98xhcns5shxhrhwjq5g4qa844ejselaa4l",
11 "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmUk1oZGdjL25YbGRzdFFh\nRllkcU1IM0x6a2M2S0JicDBFYnBxMWluaEFzCjJ3WHozNkw0RThCMG5BNE5uUkZa\nTnV1OHpaSkMrTk9XM1NRWmxlTmRuUFkKLS0tIE9qdXVWOG9CL0MyS1JXbzhmbVdC\nZlRBWm1SSTZWYzBDc1U4ci94a0hMcHcKLgbJSAMUJ9VaXVmYQe+Uj13KrWFe4QvJ\nRcibCyOJH/VO3rmxU8RAkx0jaH448h9klWhs583Od5yNg7GleC+/qg==\n-----END AGE ENCRYPTED FILE-----\n"
12 }
13 ],
14 "lastmodified": "2026-04-14T15:24:19Z",
15 "mac": "ENC[AES256_GCM,data:/dr0bXAf0v5K9LdKw7RzTTL8Qw/WqiHqLk0EbahDnFg3cVplV0s+ImCnxmhutv3hxdtMZ2dmLBfb8CYb/ZLc4HtNT/K2iKGQM7pF4+XxIjS35Q1JUcXxLrsGZcpARuCZ0AJnKo8yFgtM64dYcbxHlRwGG4u4Ds9fEHHLUMigNM0=,iv:jfFlfscUB7S1JjL/uBeW3uD4bugCT9Cj/vigGvGXrlA=,tag:suol02QD4jRH/QulWoV21A==,type:str]",
16 "version": "3.12.2"
17 }
18}
diff --git a/hosts/vidhar/network/ruleset.nft b/hosts/vidhar/network/ruleset.nft
index 10fd4c51..f7182c87 100644
--- a/hosts/vidhar/network/ruleset.nft
+++ b/hosts/vidhar/network/ruleset.nft
@@ -5,15 +5,15 @@ table arp filter {
5 limit lim_arp_local { 5 limit lim_arp_local {
6 rate over 50 mbytes/second burst 50 mbytes 6 rate over 50 mbytes/second burst 50 mbytes
7 } 7 }
8 limit lim_arp_gpon { 8 limit lim_arp_ppp {
9 rate over 7500 kbytes/second burst 7500 kbytes 9 rate over 7500 kbytes/second burst 7500 kbytes
10 } 10 }
11 11
12 counter arp-rx {} 12 counter arp-rx {}
13 counter arp-tx {} 13 counter arp-tx {}
14 14
15 counter arp-ratelimit-gpon-rx {} 15 counter arp-ratelimit-ppp-rx {}
16 counter arp-ratelimit-gpon-tx {} 16 counter arp-ratelimit-ppp-tx {}
17 17
18 counter arp-ratelimit-local-rx {} 18 counter arp-ratelimit-local-rx {}
19 counter arp-ratelimit-local-tx {} 19 counter arp-ratelimit-local-tx {}
@@ -22,8 +22,8 @@ table arp filter {
22 type filter hook input priority filter 22 type filter hook input priority filter
23 policy accept 23 policy accept
24 24
25 iifname != gpon limit name lim_arp_local counter name arp-ratelimit-local-rx drop 25 iifname != @pppInterface@ limit name lim_arp_local counter name arp-ratelimit-local-rx drop
26 iifname gpon limit name lim_arp_gpon counter name arp-ratelimit-gpon-rx drop 26 iifname @pppInterface@ limit name lim_arp_ppp counter name arp-ratelimit-ppp-rx drop
27 27
28 counter name arp-rx 28 counter name arp-rx
29 } 29 }
@@ -32,8 +32,8 @@ table arp filter {
32 type filter hook output priority filter 32 type filter hook output priority filter
33 policy accept 33 policy accept
34 34
35 oifname != gpon limit name lim_arp_local counter name arp-ratelimit-local-tx drop 35 oifname != @pppInterface@ limit name lim_arp_local counter name arp-ratelimit-local-tx drop
36 oifname gpon limit name lim_arp_gpon counter name arp-ratelimit-gpon-tx drop 36 oifname @pppInterface@ limit name lim_arp_ppp counter name arp-ratelimit-ppp-tx drop
37 37
38 counter name arp-tx 38 counter name arp-tx
39 } 39 }
@@ -47,11 +47,11 @@ table inet filter {
47 limit lim_icmp_local { 47 limit lim_icmp_local {
48 rate over 50 mbytes/second burst 50 mbytes 48 rate over 50 mbytes/second burst 50 mbytes
49 } 49 }
50 limit lim_icmp_gpon { 50 limit lim_icmp_ppp {
51 rate over 7500 kbytes/second burst 7500 kbytes 51 rate over 7500 kbytes/second burst 7500 kbytes
52 } 52 }
53 53
54 counter icmp-ratelimit-gpon-fw {} 54 counter icmp-ratelimit-ppp-fw {}
55 counter icmp-ratelimit-local-fw {} 55 counter icmp-ratelimit-local-fw {}
56 56
57 counter icmp-fw {} 57 counter icmp-fw {}
@@ -59,7 +59,9 @@ table inet filter {
59 counter invalid-fw {} 59 counter invalid-fw {}
60 counter fw-lo {} 60 counter fw-lo {}
61 counter fw-lan {} 61 counter fw-lan {}
62 counter fw-gpon {} 62 counter fw-ppp {}
63 counter fw-kimai {}
64 counter fw-podman {}
63 65
64 counter fw-cups {} 66 counter fw-cups {}
65 67
@@ -74,7 +76,7 @@ table inet filter {
74 counter invalid-local4-rx {} 76 counter invalid-local4-rx {}
75 counter invalid-local6-rx {} 77 counter invalid-local6-rx {}
76 78
77 counter icmp-ratelimit-gpon-rx {} 79 counter icmp-ratelimit-ppp-rx {}
78 counter icmp-ratelimit-local-rx {} 80 counter icmp-ratelimit-local-rx {}
79 counter icmp-rx {} 81 counter icmp-rx {}
80 82
@@ -92,6 +94,12 @@ table inet filter {
92 counter tftp-rx {} 94 counter tftp-rx {}
93 counter pgbackrest-rx {} 95 counter pgbackrest-rx {}
94 counter immich-rx {} 96 counter immich-rx {}
97 counter paperless-rx {}
98 counter hledger-rx {}
99 counter audiobookshelf-rx {}
100 counter kimai-rx {}
101 counter changedetection-rx {}
102 counter vikunja-rx {}
95 103
96 counter established-rx {} 104 counter established-rx {}
97 105
@@ -103,7 +111,7 @@ table inet filter {
103 111
104 counter tx-lo {} 112 counter tx-lo {}
105 113
106 counter icmp-ratelimit-gpon-tx {} 114 counter icmp-ratelimit-ppp-tx {}
107 counter icmp-ratelimit-local-tx {} 115 counter icmp-ratelimit-local-tx {}
108 counter icmp-tx {} 116 counter icmp-tx {}
109 117
@@ -121,15 +129,21 @@ table inet filter {
121 counter tftp-tx {} 129 counter tftp-tx {}
122 counter pgbackrest-tx {} 130 counter pgbackrest-tx {}
123 counter immich-tx {} 131 counter immich-tx {}
132 counter paperless-tx {}
133 counter hledger-tx {}
134 counter audiobookshelf-tx {}
135 counter kimai-tx {}
136 counter changedetection-tx {}
137 counter vikunja-tx {}
124 138
125 counter tx {} 139 counter tx {}
126 140
127 141
128 chain forward_icmp_accept { 142 chain forward_icmp_accept {
129 oifname { gpon, bifrost } limit name lim_icmp_gpon counter name icmp-ratelimit-gpon-fw drop 143 oifname { @pppInterface@, bifrost } limit name lim_icmp_ppp counter name icmp-ratelimit-ppp-fw drop
130 iifname { gpon, bifrost } limit name lim_icmp_gpon counter name icmp-ratelimit-gpon-fw drop 144 iifname { @pppInterface@, bifrost } limit name lim_icmp_ppp counter name icmp-ratelimit-ppp-fw drop
131 oifname != { gpon, bifrost } limit name lim_icmp_local counter name icmp-ratelimit-local-fw drop 145 oifname != { @pppInterface@, bifrost } limit name lim_icmp_local counter name icmp-ratelimit-local-fw drop
132 iifname != { gpon, bifrost } limit name lim_icmp_local counter name icmp-ratelimit-local-fw drop 146 iifname != { @pppInterface@, bifrost } limit name lim_icmp_local counter name icmp-ratelimit-local-fw drop
133 counter name icmp-fw accept 147 counter name icmp-fw accept
134 } 148 }
135 chain forward { 149 chain forward {
@@ -142,10 +156,19 @@ table inet filter {
142 156
143 iifname lo counter name fw-lo accept 157 iifname lo counter name fw-lo accept
144 158
145 oifname { lan, gpon, bifrost } meta l4proto $icmp_protos jump forward_icmp_accept 159 iifname lan oifname { @pppInterface@, bifrost } meta l4proto $icmp_protos jump forward_icmp_accept
146 iifname lan oifname { gpon, bifrost } counter name fw-lan accept 160 iifname bifrost oifname ve-kimai meta l4proto $icmp_protos jump forward_icmp_accept
161 iifname ve-kimai oifname bifrost meta l4proto $icmp_protos jump forward_icmp_accept
162 iifname lan oifname { @pppInterface@, bifrost } counter name fw-lan accept
163 iifname ve-kimai oifname @pppInterface@ counter name fw-kimai accept
164 iifname podman0 ip saddr 10.88.0.5 oifname @pppInterface@ counter name fw-podman accept
147 165
148 iifname gpon oifname lan ct state { established, related } counter name fw-gpon accept 166 iifname @pppInterface@ oifname lan ct state { established, related } counter name fw-ppp accept
167 iifname @pppInterface@ oifname ve-kimai ct state { established, related } counter name fw-kimai accept
168 iifname @pppInterface@ oifname podman0 ip daddr 10.88.0.5 ct state { established, related } counter name fw-podman accept
169
170 iifname bifrost oifname ve-kimai tcp dport 80 ip6 saddr $bifrost_surtr ip6 daddr 2a03:4000:52:ada:6::2 counter name kimai-rx accept
171 iifname ve-kimai oifname bifrost tcp sport 80 ip6 saddr 2a03:4000:52:ada:6::2 ip6 daddr $bifrost_surtr counter name kimai-tx accept
149 172
150 173
151 limit name lim_reject log level debug prefix "drop forward: " counter name reject-ratelimit-fw drop 174 limit name lim_reject log level debug prefix "drop forward: " counter name reject-ratelimit-fw drop
@@ -166,22 +189,22 @@ table inet filter {
166 iif != lo ip daddr 127.0.0.1/8 counter name invalid-local4-rx reject 189 iif != lo ip daddr 127.0.0.1/8 counter name invalid-local4-rx reject
167 iif != lo ip6 daddr ::1/128 counter name invalid-local6-rx reject 190 iif != lo ip6 daddr ::1/128 counter name invalid-local6-rx reject
168 191
169 iifname { bifrost, gpon } meta l4proto $icmp_protos limit name lim_icmp_gpon counter name icmp-ratelimit-gpon-rx drop 192 iifname { bifrost, @pppInterface@ } meta l4proto $icmp_protos limit name lim_icmp_ppp counter name icmp-ratelimit-ppp-rx drop
170 iifname != { bifrost, gpon } meta l4proto $icmp_protos limit name lim_icmp_local counter name icmp-ratelimit-local-rx drop 193 iifname != { bifrost, @pppInterface@ } meta l4proto $icmp_protos limit name lim_icmp_local counter name icmp-ratelimit-local-rx drop
171 meta l4proto $icmp_protos counter name icmp-rx accept 194 meta l4proto $icmp_protos counter name icmp-rx accept
172 195
173 iifname { lan, mgmt, gpon, yggdrasil, bifrost } tcp dport 22 counter name ssh-rx accept 196 iifname { lan, mgmt, @pppInterface@, yggdrasil, bifrost } tcp dport 22 counter name ssh-rx accept
174 iifname { lan, mgmt, gpon, yggdrasil, bifrost } udp dport 60000-61000 counter name mosh-rx accept 197 iifname { lan, mgmt, @pppInterface@, yggdrasil, bifrost } udp dport 60000-61000 counter name mosh-rx accept
175 198
176 iifname { lan, mgmt, wifibh, yggdrasil } meta l4proto { tcp, udp } th dport 53 counter name dns-rx accept 199 iifname { lan, mgmt, wifibh, yggdrasil, podman0 } meta l4proto { tcp, udp } th dport 53 counter name dns-rx accept
177 200
178 iifname { lan, yggdrasil } tcp dport 2049 counter name nfs-rx accept 201 iifname { lan, yggdrasil } tcp dport 2049 counter name nfs-rx accept
179 202
180 iifname { lan, mgmt, gpon } meta protocol ip udp dport 51820 counter name wg-rx accept 203 iifname { lan, mgmt, @pppInterface@ } meta protocol ip udp dport 51820 counter name wg-rx accept
181 iifname { lan, mgmt, gpon } meta protocol ip6 udp dport 51821 counter name wg-rx accept 204 iifname { lan, mgmt, @pppInterface@ } meta protocol ip6 udp dport 51821 counter name wg-rx accept
182 iifname "yggdrasil-wg-*" meta l4proto gre counter name yggdrasil-gre-rx accept 205 iifname "yggdrasil-wg-*" meta l4proto gre counter name yggdrasil-gre-rx accept
183 206
184 iifname gpon meta protocol ip6 udp dport 546 udp sport 547 counter name ipv6-pd-rx accept 207 iifname @pppInterface@ meta protocol ip6 udp dport 546 udp sport 547 counter name ipv6-pd-rx accept
185 208
186 iifname mgmt udp dport 123 counter name ntp-rx accept 209 iifname mgmt udp dport 123 counter name ntp-rx accept
187 210
@@ -197,6 +220,11 @@ table inet filter {
197 tcp dport 8432 counter name pgbackrest-rx accept 220 tcp dport 8432 counter name pgbackrest-rx accept
198 221
199 iifname bifrost tcp dport 2283 ip6 saddr $bifrost_surtr counter name immich-rx accept 222 iifname bifrost tcp dport 2283 ip6 saddr $bifrost_surtr counter name immich-rx accept
223 iifname bifrost tcp dport 28981 ip6 saddr $bifrost_surtr counter name paperless-rx accept
224 iifname bifrost tcp dport 5000 ip6 saddr $bifrost_surtr counter name hledger-rx accept
225 iifname bifrost tcp dport 28982 ip6 saddr $bifrost_surtr counter name audiobookshelf-rx accept
226 iifname bifrost tcp dport 5001 ip6 saddr $bifrost_surtr counter name changedetection-rx accept
227 iifname bifrost tcp dport 3456 ip6 saddr $bifrost_surtr counter name vikunja-rx accept
200 228
201 ct state { established, related } counter name established-rx accept 229 ct state { established, related } counter name established-rx accept
202 230
@@ -214,8 +242,8 @@ table inet filter {
214 242
215 oifname lo counter name tx-lo accept 243 oifname lo counter name tx-lo accept
216 244
217 oifname { bifrost, gpon } meta l4proto $icmp_protos limit name lim_icmp_gpon counter name icmp-ratelimit-gpon-tx drop 245 oifname { bifrost, @pppInterface@ } meta l4proto $icmp_protos limit name lim_icmp_ppp counter name icmp-ratelimit-ppp-tx drop
218 oifname != { bifrost, gpon } meta l4proto $icmp_protos limit name lim_icmp_local counter name icmp-ratelimit-local-tx drop 246 oifname != { bifrost, @pppInterface@ } meta l4proto $icmp_protos limit name lim_icmp_local counter name icmp-ratelimit-local-tx drop
219 meta l4proto $icmp_protos counter name icmp-tx accept 247 meta l4proto $icmp_protos counter name icmp-tx accept
220 248
221 249
@@ -246,6 +274,11 @@ table inet filter {
246 tcp sport 8432 counter name pgbackrest-tx accept 274 tcp sport 8432 counter name pgbackrest-tx accept
247 275
248 iifname bifrost tcp sport 2283 ip6 daddr $bifrost_surtr counter name immich-tx accept 276 iifname bifrost tcp sport 2283 ip6 daddr $bifrost_surtr counter name immich-tx accept
277 iifname bifrost tcp sport 28981 ip6 daddr $bifrost_surtr counter name paperless-tx accept
278 iifname bifrost tcp sport 5000 ip6 daddr $bifrost_surtr counter name hledger-tx accept
279 iifname bifrost tcp sport 28982 ip6 daddr $bifrost_surtr counter name audiobookshelf-tx accept
280 iifname bifrost tcp sport 5001 ip6 daddr $bifrost_surtr counter name changedetection-tx accept
281 iifname bifrost tcp sport 3456 ip6 daddr $bifrost_surtr counter name vikunja-tx accept
249 282
250 283
251 counter name tx 284 counter name tx
@@ -253,28 +286,28 @@ table inet filter {
253} 286}
254 287
255table inet nat { 288table inet nat {
256 counter gpon-nat {} 289 counter ppp-nat {}
257 # counter container-nat {} 290 counter kimai-nat {}
258 291
259 chain postrouting { 292 chain postrouting {
260 type nat hook postrouting priority srcnat 293 type nat hook postrouting priority srcnat
261 policy accept 294 policy accept
262 295
263 296
264 meta nfproto ipv4 oifname gpon counter name gpon-nat masquerade 297 meta nfproto ipv4 oifname @pppInterface@ counter name ppp-nat masquerade
265 # iifname ve-* oifname gpon counter name container-nat masquerade 298 iifname ve-kimai oifname @pppInterface@ counter name kimai-nat masquerade
266 } 299 }
267} 300}
268 301
269table inet mss_clamp { 302table inet mss_clamp {
270 counter gpon-mss-clamp {} 303 counter ppp-mss-clamp {}
271 304
272 chain postrouting { 305 chain postrouting {
273 type filter hook postrouting priority mangle 306 type filter hook postrouting priority mangle
274 policy accept 307 policy accept
275 308
276 309
277 oifname gpon tcp flags & (syn|rst) == syn counter name gpon-mss-clamp tcp option maxseg size set rt mtu 310 oifname @pppInterface@ tcp flags & (syn|rst) == syn counter name ppp-mss-clamp tcp option maxseg size set rt mtu
278 } 311 }
279} 312}
280 313
@@ -409,7 +442,7 @@ table inet dscpclassify {
409 chain postrouting { 442 chain postrouting {
410 type filter hook postrouting priority filter + 1; policy accept 443 type filter hook postrouting priority filter + 1; policy accept
411 444
412 oifname != gpon return 445 oifname != @pppInterface@ return
413 446
414 ip dscp cs0 goto ct_set_cs0 447 ip dscp cs0 goto ct_set_cs0
415 ip dscp lephb goto ct_set_lephb 448 ip dscp lephb goto ct_set_lephb