Reusable cnx.router.* module for the Topton 1U boxes replacing OPNsense: PPPoE WAN (optionally VLAN-tagged, AIS: 10, secret credentials incl. username), VLAN-filtering bridge, nftables NAT/firewall with MSS clamp, Kea DHCP with per-VLAN lease time, Blocky DNS, DHCPv6-PD, CrowdSec with the ZeroTier mesh whitelisted, optional Omada controller, ZFS disk. Fleet baseline rides along: admins sops group is now derived for every machine in clan.nix (secrets encrypt to it from the first vars generate) and time sync is chrony everywhere instead of systemd-timesyncd.
44 lines
1.5 KiB
Nix
44 lines
1.5 KiB
Nix
# TP-Link Omada SDN controller for sites with Omada APs/switches. There is no
|
|
# nixpkgs package, so it runs as a podman container (mbentley/omada-controller,
|
|
# the de-facto standard image). Host networking because device adoption relies
|
|
# on L2 broadcast discovery (UDP 29810) on the mgmt VLAN; the default-deny
|
|
# input firewall keeps its ports unreachable from WAN and non-mgmt VLANs.
|
|
{
|
|
config,
|
|
lib,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.cnx.router;
|
|
mesh = import ../mesh-hosts.nix { inherit config lib; };
|
|
in
|
|
{
|
|
options.cnx.router.omada.enable =
|
|
lib.mkEnableOption "TP-Link Omada SDN controller (podman container)";
|
|
|
|
config = lib.mkIf (cfg.enable && cfg.omada.enable) {
|
|
virtualisation.podman.enable = true;
|
|
virtualisation.oci-containers = {
|
|
backend = "podman";
|
|
containers.omada = {
|
|
image = "docker.io/mbentley/omada-controller:5.15";
|
|
extraOptions = [ "--network=host" ];
|
|
environment.TZ = config.time.timeZone;
|
|
volumes = [
|
|
"/var/lib/omada/data:/opt/tplink/EAPController/data"
|
|
"/var/lib/omada/logs:/opt/tplink/EAPController/logs"
|
|
];
|
|
};
|
|
};
|
|
|
|
# Admin UI (8043) also reachable over the mesh, like Grafana on control.
|
|
networking.firewall.extraInputRules = ''
|
|
ip6 saddr ${mesh.subnet} tcp dport 8043 accept comment "omada ui over the mesh"
|
|
'';
|
|
|
|
# Controller state (adopted devices, site config, cert) — declared as clan
|
|
# state so a borgbackup client can pick it up; backup wiring is a later step.
|
|
clan.core.state.omada.folders = [ "/var/lib/omada" ];
|
|
};
|
|
}
|