main
  1{den, ...}: {
  2  den.hosts.tribios = {
  3    address = {
  4      ipv4.tailscale = "100.127.6.231";
  5      ipv6.tailscale = "fd7a:115c:a1e0:675d:6820:4fa0:fddc:a59";
  6    };
  7    settings.services.mihomo = {
  8      autoStart = true;
  9      tailscaleWebControl = true;
 10      interfaces = {
 11        wan = "enP3p49s0";
 12        lan = ["br-lan"];
 13      };
 14    };
 15    settings.services.kea = {
 16      interfaces = ["br-lan"];
 17      staticRange = {
 18        start = "192.168.52.2";
 19        end = "192.168.52.50";
 20      };
 21      poolEnd = "192.168.52.200";
 22      router = "192.168.52.1";
 23      dnsServers = ["223.5.5.5" "119.29.29.29"];
 24      extraReservations = [
 25        {
 26          # AP.
 27          hostname = "ap";
 28          mac = "f4:f6:47:33:56:98";
 29          ip = "192.168.52.2";
 30        }
 31      ];
 32    };
 33  };
 34
 35  den.aspects.tribios = {
 36    includes = [
 37      den.aspects.services.kea
 38      den.aspects.services.mihomo
 39      den.aspects.services.mihomo.tproxy
 40    ];
 41
 42    nixos = {
 43      pkgs,
 44      lib,
 45      ...
 46    }: {
 47      boot.kernel.sysctl = {
 48        "net.ipv4.ip_forward" = 1;
 49        "net.ipv4.conf.all.send_redirects" = 0;
 50        "net.ipv4.conf.default.send_redirects" = 0;
 51        "net.ipv4.conf.br-lan.send_redirects" = 0;
 52        "net.ipv6.conf.all.forwarding" = 1;
 53        "net.ipv6.conf.br-lan.forwarding" = 1;
 54      };
 55
 56      # Interfaces (from nixos-factor):
 57      # wan: enP3p49s0 (2.5Gbps)
 58      # lan: enP4p65s0 (2.5Gbps), end0 (1.0Gbps)
 59      networking = {
 60        useNetworkd = true;
 61        bridges = {
 62          br-lan = {
 63            interfaces = ["enP4p65s0" "end0"];
 64          };
 65        };
 66        interfaces = {
 67          br-lan = {
 68            useDHCP = false;
 69            ipv4.addresses = [
 70              {
 71                address = "192.168.52.1";
 72                prefixLength = 24;
 73              }
 74            ];
 75          };
 76        };
 77
 78        firewall = {
 79          enable = true;
 80          trustedInterfaces = ["br-lan"];
 81        };
 82
 83        nat = {
 84          enable = true;
 85          internalInterfaces = ["br-lan"];
 86          externalInterface = "enP3p49s0";
 87        };
 88      };
 89
 90      # The WAN is behind the company NAT (192.168.100.x), so miniupnpd
 91      # must allow a private external IP to serve NAT-PMP mappings.
 92      services.miniupnpd = {
 93        enable = true;
 94        externalInterface = "enP3p49s0";
 95        internalIPs = ["br-lan"];
 96        upnp = false;
 97        natpmp = true;
 98        appendConfig = "ext_allow_private_ipv4=yes";
 99      };
100
101      systemd.services.miniupnpd = {
102        after = ["systemd-networkd.service"];
103        serviceConfig = {
104          ExecStartPre = pkgs.writeShellScript "miniupnpd-check-wan" ''
105            ${lib.getExe' pkgs.iproute2 "ip"} -4 -o addr show dev enP3p49s0 scope global | ${lib.getExe' pkgs.gnugrep "grep"} -q .
106          '';
107          Restart = "on-failure";
108          RestartSec = 30;
109        };
110      };
111    };
112  };
113}