# Site gateways: the `router` service instance (modules/clan/router). One # instance for the fleet; each site adds its machine with the site's port / # VLAN layout under roles.default.machines..settings. Everything else # (PPPoE, Kea/Blocky, nftables, IPv6-PD, CrowdSec, iperf3, speedtest) follows # from the service. Imported by clan.nix. { config, lib, ... }: let hosts = import ./modules/hosts.nix; mesh = import ./modules/mesh-hosts.nix { dir = config.directory; inherit lib; }; in { inventory.instances.router = { module = { name = "router"; input = "self"; }; # Fleet-wide settings: admin paths (SSH, scrapes, iperf3, Omada UI) are # opened to the mesh; internal proxy names live under # .cnx.network with wildcard certs issued via DNS-01 against # ns1 (which must declare the gateway's acme-secret.nix generator). roles.default.settings = { mesh.subnet = mesh.subnet; proxy = { domain = "cnx.network"; acme.nameserver = hosts.ns1.ipv4; acme.email = "postmaster@cnx.email"; }; }; # Chiang Mai (site 1): Topton 1U, Intel N300, 4x i226-V 2.5G. Port roles # use the expected igc names — verify against facter.json after the # first install and adjust if the box enumerates differently. roles.default.machines.gw-cnx-1.settings = { site = "cnx"; siteId = 1; wan.interface = "enp1s0"; wan.vlanId = null; # this ISP runs PPPoE untagged on the port wan.macAddress = "a8:b8:e0:01:06:87"; trunkPorts = [ "enp2s0" ]; # STAGING (remove at cutover, move enp3s0 back into trunkPorts): # DHCP-client uplink into the existing OPNsense LAN so the box has # internet + mesh while it runs alongside the old router. stagingPort = "enp3s0"; # Dedicated on-site recovery port: untagged mgmt, always available even # if the switch config is broken. accessPorts.enp4s0 = "mgmt"; # Replaces the newedge.house OPNsense box; renumbered to the fleet # convention (10.1..0/24, router .1, pool .100-.199). The old # untagged LAN becomes tagged mgmt — infra switch ports get PVID 10. vlans = { mgmt = { id = 10; # 10.1.10.0/24 — servers, APs, switches, Omada, admin dhcp.reservations.storinator01 = { hwAddress = "7c:c2:55:e0:d6:40"; ipAddress = "10.1.10.53"; }; }; lan.id = 20; # 10.1.20.0/24 — trusted clients iot.id = 40; # 10.1.40.0/24 voip.id = 50; # 10.1.50.0/24 dmz.id = 60; # 10.1.60.0/24 unit1.id = 110; # 10.1.110.0/24 unit2.id = 120; # 10.1.120.0/24 unit3.id = 130; # 10.1.130.0/24 unit4.id = 140; # 10.1.140.0/24 unit5 = { id = 150; # 10.1.150.0/24 dhcp.reservations.newt = { hwAddress = "7c:d3:0a:21:58:0b"; ipAddress = "10.1.150.22"; }; }; }; # This site runs the Omada controller for its APs/switches. omada.enable = true; # Internal reverse proxy: real wildcard cert *.cnx1.cnx.network; Blocky # resolves the names to the router's LAN address for mgmt+lan clients. proxy = { enable = true; services.omada = { # Omada's UI is HTTPS with a self-signed cert on the host network. backend = "https://127.0.0.1:8043"; insecureSkipVerify = true; }; }; }; }; }