# Site gateway (OPNsense replacement) for the Topton 1U boxes, as a clan # service: PPPoE WAN, VLAN-filtering bridge over the LAN ports, per-VLAN # DHCP/DNS, firewall/NAT, and the optional Omada controller / internal proxy. # # Exported as `clan.modules.router` of this flake; used here with # `module.input = "self"` and from other clans with `module.input = # ""`. README.md has the consumer view. A site joins # through the inventory: # # inventory.instances.router = { # module = { name = "router"; input = "self"; }; # roles.default.settings.mesh.subnet = ...; # fleet-wide # roles.default.machines.gw--.settings = { site = ...; ... }; # }; # # The settings schema lives in interface.nix. Implementation files that need # the settings are functions `{ settings }: `; the evaluated # settings are handed in with importApply so nothing goes through # machine-level options. The rest are plain NixOS modules. { lib, ... }: { _class = "clan.service"; manifest.name = "router"; manifest.description = "Site gateway: PPPoE WAN, VLAN bridge, DHCP/DNS, firewall/NAT"; manifest.categories = [ "Network" ]; manifest.readme = builtins.readFile ./README.md; roles.default = { description = "Turns the machine into the site's router (one instance per machine)."; interface = ./interface.nix; perInstance = { settings, machine, ... }: { nixosModule.imports = [ ./ipv6.nix ] # The proxy's TSIG secret is shared with the nameserver (acme-secret.nix). ++ lib.optional settings.proxy.enable (import ./acme-secret.nix machine.name) ++ map (file: lib.modules.importApply file { inherit settings; }) [ ./network.nix ./pppoe.nix ./firewall.nix ./dns-dhcp.nix ./crowdsec.nix ./omada.nix ./proxy.nix ./iperf.nix ./speedtest.nix ./wifi.nix ]; }; }; # A machine has exactly one WAN port and one VLAN layout; two instances would # both claim br0/ppp0 and fight over Kea/Blocky/nftables. perMachine = { instances, machine, ... }: { nixosModule.assertions = [ { assertion = lib.length (lib.attrNames instances) == 1; message = "router: ${machine.name} is a gateway in several instances (${lib.concatStringsSep ", " (lib.attrNames instances)}); a machine can only be one router."; } ]; }; }