zaphyra's git: nixfiles

zaphyra and void's nixfiles

commit 159db097be3a1375b72c2d23247251e3d22fab77
parent af1d8ed39711acc5b759f540805ab898d7eff857
Author: Katja (zaphyra) <git@ctu.cx>
Date: Thu, 29 May 2025 18:16:08 +0200

config/nixos/modules/presets/katja: add `router`
4 files changed, 492 insertions(+), 0 deletions(-)
A
config/nixos/modules/presets/katja/router/enable.nix
|
93
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
config/nixos/modules/presets/katja/router/pppd.nix
|
89
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
config/nixos/modules/presets/katja/router/systemd-networkd.nix
|
227
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
resources/katja/routerRuleset.nft
|
83
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/config/nixos/modules/presets/katja/router/enable.nix b/config/nixos/modules/presets/katja/router/enable.nix
@@ -0,0 +1,93 @@
+{
+  inputs,
+  pov,
+  pkgs,
+  lib,
+  config,
+  hostConfig,
+  ...
+}:
+let
+  inherit (lib) types;
+  cfg = lib.getAttrFromPath pov config;
+
+in
+{
+
+  option = {
+    type = types.bool;
+    default = false;
+  };
+
+  config = lib.mkIf cfg.enable {
+
+    environment.systemPackages = [ pkgs.wireguard-tools ];
+
+    boot.initrd.kernelModules = [ "jool" ];
+
+    hardware.firmware = [
+      (pkgs.runCommandNoCC "rtl8168h-firmware" { } ''
+        mkdir -p $out/lib/firmware/rtl_nic
+        cp ${pkgs.linux-firmware}/lib/firmware/rtl_nic/rtl8168h-2.fw $out/lib/firmware/rtl_nic/rtl8168h-2.fw
+      '')
+    ];
+
+    modules.presets.katja.router = {
+      systemd-networkd = true;
+      pppd = true;
+    };
+
+    networking = {
+      useNetworkd = true;
+      useDHCP = false;
+      firewall.enable = false;
+
+      nftables.enable = true;
+      nftables.rulesetFile = inputs.self.resources.katja.routerRuleset;
+
+      jool.enable = true;
+      jool.nat64.default = { };
+    };
+
+    services = {
+      resolved.enable = false;
+
+      avahi.enable = true;
+      avahi.reflector = true;
+      avahi.allowInterfaces = [ "brlan" ];
+
+      kresd.enable = true;
+      kresd.listenPlain = [ "53" ];
+      kresd.extraConfig = ''
+        require 'math'
+        math.randomseed(os.time())
+
+        modules.load('dns64')
+        modules.load('view')
+
+        dns64.config('64:ff9b::')
+
+        -- disable dns64 for all IPv4 source addresses
+        view:addr('0.0.0.0/0', policy.all(policy.FLAGS('DNS64_DISABLE')))
+
+        dns_providers = {
+          { -- Quad9
+            '9.9.9.9', '149.112.112.112'
+          },
+          { -- Cloudflare
+            '1.1.1.1', '1.0.0.1'
+          },
+          { -- Google
+            '8.8.8.8', '8.8.4.4'
+          }
+        }
+
+        policy.add(function (request, query)
+          return policy.FORWARD(dns_providers[math.random(1, #dns_providers)])
+        end)
+      '';
+    };
+
+  };
+
+}
diff --git a/config/nixos/modules/presets/katja/router/pppd.nix b/config/nixos/modules/presets/katja/router/pppd.nix
@@ -0,0 +1,89 @@
+{
+  povSelf,
+  pkgs,
+  lib,
+  config,
+  hostConfig,
+  utils,
+  ...
+}:
+let
+  inherit (lib) types;
+  cfg = lib.getAttrFromPath povSelf config;
+
+in
+{
+
+  option = {
+    type = types.bool;
+    default = false;
+  };
+
+  config = lib.mkIf cfg {
+    sops.secrets."environments/pppd" = {};
+
+    services.pppd = {
+      enable = true;
+      peers.dtagdsl.config = ''
+        plugin pppoe.so dtagdsl
+        user "''${DTAG_PPP_USER}"
+        password "''${DTAG_PPP_PASS}"
+        hide-password
+        ifname ppp-dtagdsl
+        persist
+
+        maxfail 0
+        holdoff 5
+
+        noipdefault
+
+        lcp-echo-interval 20
+        lcp-echo-failure 3
+
+        mtu 1492
+        defaultroute
+        replacedefaultroute
+        +ipv6
+      '';
+    };
+
+    environment.etc."ppp/peers/dtagdsl".enable = false;
+    environment.etc."ip-up.d/1systemd-networkd" = {
+      mode = "755";
+      text = ''
+        #!{pkgs.bash}/bin/bash
+        networkctl reconfigure "$PPP_IFACE";
+      '';
+    };
+
+    systemd.services."pppd-dtagdsl".serviceConfig =
+      let
+        preStart = ''
+          mkdir -p /etc/ppp/peers
+
+          # Created files only readable by root
+          umask u=rw,g=,o=
+
+          # Copy config and substitute env-vars
+          rm -f /etc/ppp/peers/dtagdsl
+          ${pkgs.envsubst}/bin/envsubst -i "${
+            config.environment.etc."ppp/peers/dtagdsl".source
+          }" > /etc/ppp/peers/dtagdsl
+        '';
+
+        preStartFile = utils.systemdUtils.lib.makeJobScript {
+          name = "pppd-dtagdsl-pre-start";
+          text = preStart;
+          enableStrictShellChecks = true;
+        };
+
+      in {
+        EnvironmentFile = config.sops.secrets."environments/pppd".path;
+        ExecStartPre = [
+          # "+" marks script to be executed without priviledge restrictions
+          "+${preStartFile}"
+        ];
+      };
+  };
+
+}
diff --git a/config/nixos/modules/presets/katja/router/systemd-networkd.nix b/config/nixos/modules/presets/katja/router/systemd-networkd.nix
@@ -0,0 +1,227 @@
+{
+  povSelf,
+  pkgs,
+  lib,
+  config,
+  hostConfig,
+  ...
+}:
+let
+  inherit (lib) types;
+  cfg = lib.getAttrFromPath povSelf config;
+
+in
+{
+
+  option = {
+    type = types.bool;
+    default = false;
+  };
+
+  config = lib.mkIf cfg {
+    sops.secrets.wireguardPrivKey = {
+      mode  = "640";
+      owner = "root";
+      group = "systemd-network";
+    };
+
+    systemd.network = {
+      enable = true;
+      wait-online.enable = false;
+
+      config.networkConfig = {
+        IPv4Forwarding = true;
+        IPv6Forwarding = true;
+      };
+
+      links."5-dtagdsl" = {
+        matchConfig.PermanentMACAddress = "d0:37:45:06:de:de";
+        linkConfig.Name = "dtagdsl";
+      };
+
+      links."5-iphone" = {
+        matchConfig.PermanentMACAddress = "aa:ab:b5:18:95:d9";
+        linkConfig.Name = "iphone";
+      };
+
+      netdevs."20-brlan" = {
+        netdevConfig = {
+          Kind = "bridge";
+          Name = "brlan";
+        };
+      };
+
+      netdevs."10-wg-novus" = {
+        netdevConfig = {
+          Kind = "wireguard";
+          Name = "wg-novus";
+        };
+
+        wireguardConfig = {
+          PrivateKeyFile = config.sops.secrets.wireguardPrivKey.path;
+          ListenPort     = 51820;
+          FirewallMark   = 51820;
+        };
+
+        wireguardPeers = [{
+          Endpoint   = "novus.infra.zaphyra.eu:51820";
+          PublicKey  = "J+kRRNU65JGc0yk04v6P3tFwHSQOIfq8EkfD2gFupg4=";
+          AllowedIPs = [ "::/0" ];
+          PersistentKeepalive = 10;
+        }];
+      };
+
+      networks = {
+        "5-dtagdsl" = {
+          matchConfig.Name = "dtagdsl";
+
+          address = [ "192.168.1.2/24" ];
+
+          linkConfig.RequiredForOnline      = false;
+          networkConfig.LinkLocalAddressing = false;
+        };
+
+        "5-enp1s0" = {
+          matchConfig.Name = "enp1s0";
+
+          bridge = [ "brlan" ];
+          networkConfig.ConfigureWithoutCarrier = true;
+        };
+
+        "5-iphone" = {
+          matchConfig.Name = "iphone";
+
+          networkConfig.DHCP = true;
+        };
+
+        "10-ppp-dtagdsl" = {
+          matchConfig.Name = "ppp-dtagdsl";
+
+          networkConfig = {
+            KeepConfiguration = true;
+            IPv6AcceptRA      = true;
+            DHCP              = "ipv6";
+          };
+
+          ipv6AcceptRAConfig = {
+            UseDNS = false;
+          };
+
+          dhcpV6Config = {
+            WithoutRA            = "solicit";
+            PrefixDelegationHint = "::/56";
+            IAID   = 0;
+            UseDNS = false;
+          };
+        };
+
+        "10-wg-novus" = {
+          matchConfig.Name = "wg-novus";
+
+          linkConfig.RequiredForOnline = false;
+          routes = [{
+              Destination = "::/0";
+              Table       = "1234";
+          }];
+        };
+
+        "20-brlan" = {
+          matchConfig = {
+            Name   = "brlan";
+            Driver = "bridge";
+          };
+
+          address = [
+            "${hostConfig.networking.ip4Address}/${toString hostConfig.networking.ip4PrefixLength}"
+            "${hostConfig.networking.ip6Address}/${toString hostConfig.networking.ip6PrefixLength}"
+          ];
+
+          routingPolicyRules = [
+            {
+              From     = "2a03:4000:4d:5e:acab::/112";
+              Table    = 254;
+              Priority = 1900;
+              SuppressPrefixLength = 0;
+            }
+            {
+              From     = "2a03:4000:4d:5e:acab::/112";
+              Table    = 1234;
+              Priority = 2000;
+            }
+          ];
+
+          networkConfig = {
+            ConfigureWithoutCarrier = true;
+
+            DHCPPrefixDelegation  = true;
+            IPv6PrivacyExtensions = false;
+            IPv6AcceptRA          = false;
+            IPv6SendRA            = true;
+
+            DHCPServer = true;
+            DNS        = hostConfig.networking.ip4Address;
+          };
+
+          dhcpPrefixDelegationConfig = {
+            UplinkInterface = "ppp-dtagdsl";
+            Announce        = true;
+            SubnetId        = 0;
+            Token           = "::1";
+          };
+
+          ipv6SendRAConfig = {
+            EmitDNS = true;
+            DNS     = "_link_local";
+          };
+
+          ipv6PREF64Prefixes = [{
+            Prefix = "64:ff9b::/96";
+          }];
+
+          dhcpServerConfig = {
+            PersistLeases = true;
+            PoolOffset = 100;
+            PoolSize = 100;
+            EmitDNS = true;
+            DNS = hostConfig.networking.ip4Address;
+            IPv6OnlyPreferredSec = 300;
+          };
+
+          dhcpServerStaticLeases = [
+            {
+              # accesspoint
+              MACAddress = "48:a9:8a:8e:dd:0b";
+              Address = "10.0.0.2";
+            }
+            {
+              # pbx
+              MACAddress = "34:31:c4:46:88:31";
+              Address = "10.0.0.3";
+            }
+            {
+              # scanner
+              MACAddress = "5c:f3:70:b9:35:9c";
+              Address = "10.0.0.4";
+            }
+            {
+              # printer
+              MACAddress = "70:77:81:2a:e7:96";
+              Address = "10.0.0.5";
+            }
+            {
+              # nix snowflake (wled)
+              MACAddress = "28:37:2f:6a:e7:14";
+              Address = "10.0.0.6";
+            }
+            {
+              # katja x13
+              MACAddress = "04:CF:4B:76:93:55";
+              Address = "10.0.0.10";
+            }
+          ];
+        };
+      };
+    };
+  };
+
+}
diff --git a/resources/katja/routerRuleset.nft b/resources/katja/routerRuleset.nft
@@ -0,0 +1,82 @@
+flush ruleset
+
+table inet firewall {
+        chain inbound {
+                # By default, drop all traffic unless it meets a filter
+                # criteria specified by the rules that follow below.
+                type filter hook input priority 0;
+                policy drop;
+
+                # Allow traffic from established and related packets.
+                ct state established,related accept
+
+                # Drop invalid packets.
+                ct state invalid drop
+
+                # Allow local connections.
+                iifname lo accept
+                iifname brlan accept
+
+                # Allow all ICMP and IGMP traffic, but enforce a rate limit
+                # to help prevent some types of flood attacks.
+                ip  protocol icmp      limit rate 5/second accept
+                ip  protocol igmp      limit rate 5/second accept
+                ip6 nexthdr  ipv6-icmp limit rate 5/second accept
+
+                # required for dhcp-pd to work!
+                udp dport dhcpv6-client accept
+
+                # Allow some ports
+                tcp dport ssh    accept
+                tcp dport http   accept
+                tcp dport https  accept
+                tcp dport 8443   accept comment "step-ca"
+                tcp dport 22000  accept comment "syncthing"
+                udp dport 21027  accept comment "syncthing"
+        }
+
+        chain forward {
+                # By default, drop all traffic unless it meets a filter
+                type filter hook forward priority 0;
+                policy drop;
+
+                tcp flags syn tcp option maxseg size set rt mtu
+
+                # Allow traffic from established and related packets.
+                ct state established,related accept
+
+                # Drop invalid packets.
+                ct state invalid drop
+
+                # local clients can do whatever
+                iifname brlan accept
+
+                # Allow all ICMP and IGMP traffic, but enforce a rate limit
+                # to help prevent some types of flood attacks.
+                ip  protocol icmp      limit rate 5/second accept
+                ip  protocol igmp      limit rate 5/second accept
+                ip6 nexthdr  ipv6-icmp limit rate 5/second accept
+
+                # drop incomming netbios traffic
+                tcp dport {139, 445} counter drop comment "silently drop NetBios"
+                udp dport {137, 138} counter drop comment "silently drop NetBios"
+        }
+
+        chain outbound {
+                # Allow all outbound traffic
+                type filter hook output priority 0
+                policy accept
+        }
+}
+
+table ip nat {
+        chain prerouting {
+                type nat hook prerouting priority -100
+                policy accept
+        }
+
+        chain postrouting {
+                type nat hook postrouting priority srcnat + 1; policy accept;
+                ip saddr 10.0.0.0/8 masquerade;
+        }
+}+
\ No newline at end of file