# Site gateway Chiang Mai (site 1): Topton 1U, Intel N300, 4x i226-V 2.5G. # Port roles below use the expected igc names — verify against facter.json # after the first install and adjust if the box enumerates differently. { config, lib, ... }: { imports = [ ../../modules/router ../../modules/monitoring/exporters.nix (import ../../modules/dns/acme-gw-secret.nix "gw-cnx-1") ]; clan.core.sops.defaultGroups = [ "admins" ]; # Until the install generates facter.json (which normally provides this). nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; # ZFS (disko.nix) needs a stable machine-unique hostId; derive it from the # hostname so every gateway gets one for free when copied for a new site. networking.hostId = builtins.substring 0 8 ( builtins.hashString "sha256" config.networking.hostName ); cnx.router = { enable = true; site = "cnx"; siteId = 1; wan.interface = "enp1s0"; wan.vlanId = null; # this ISP runs PPPoE untagged on the port trunkPorts = [ "enp2s0" # "enp3s0" # STAGING: serves as the uplink below until cutover ]; # 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; }; }; }; # STAGING (remove at cutover, and restore enp3s0 to trunkPorts): DHCP-client # uplink into the existing OPNsense LAN so the box has internet + mesh while # it runs alongside the old router. Default-deny firewall on this interface # (it's in no VLAN zone); PPPoE simply retries until the WAN port is cabled. # Do NOT connect the trunk ports to the production switch while staging — # Kea on tag 10 would fight the OPNsense LAN DHCP in one broadcast domain. systemd.network.networks."05-staging" = { matchConfig.Name = "enp3s0"; networkConfig.DHCP = "ipv4"; }; time.timeZone = "Etc/GMT-7"; # UTC+7 (Thailand, fixed offset, no DST) services.chrony.enable = true; }