Docs menu Architecture

Network

The UniFi network behind the lab. Sixteen routed VLANs in twelve firewall zones, the zone-policy model and what each zone may reach, DNS and DHCP, Wi-Fi, Threat Management, and how the segmentation got to its current shape.

Updated Source in the repo: Infrastructure/Network/UniFi/README.md Infrastructure/Network/UniFi/Configuration/ Infrastructure/Network/UniFi/Documentation/Change Records/ Guides/UniFi-Network.md

My network runs on UniFi Network 10.6.106 with one gateway, three switches and one access point. The gateway routes 16 VLANs and sorts them into 12 firewall zones. UniFi owns the VLANs, zones, gateway policies, local DNS, VPNs and switch port profiles; the Proxmox host firewall is a separate layer that lives with the cluster.

Figures are from the controller readback of 2026-09-24 unless a line says otherwise.

Hardware

DeviceModelRole
Ahsoka GatewayCloud Gateway Fiber (UCG-Fiber)Routes every LAN, zone firewall, DNS, DHCP, WireGuard, Threat Management
Bane Switch POESwitch Pro Max 16 PoECore switch, 10 GbE uplink to the gateway
Mace SwitchDevice code USWED352.5 GbE downstream of Bane
Jango SwitchDevice code USWED352.5 GbE downstream of Mace
Anakin APDevice code UAPA6A9, 2.4, 5 and 6 GHzThe only access point

Firmware, uplink ports and power are on Hardware. The controller holds 23 networks: the 16 routed LANs below, two WANs, the ProtonVPN client network and four remote-user VPN servers. Internet 2 is configured as a failover WAN but had no link or address.

VLANs and zones

Names ending in -A belong to the segmented AlphaSec infrastructure tier. Unsuffixed VLANs serve household and general lab devices.

NetworkVLANZoneDHCPWhat belongs here
ManagementuntaggedInternalYesNetwork fabric only: gateway, switches, access point, Protect cameras
Server-Provision5InternalYes, with network boot optionsBare-metal Galaxy nodes during PXE install, before they move to MGMT-A and Cluster-Net
Trusted10InternalYesHousehold phones, tablets, laptops and personal streaming devices
IoT20UntrustedYesSmart-home gear, cameras, TVs, appliances, the printer
DMZ30DmzYes, narrow rangeInternet-facing workloads
Personal-A40InternalYesMy lab and utility guests: Docker hosts, automation, pentest and development VMs
Proton-WiFi45InternalYes, Quad9 resolversWireless clients whose traffic must leave through ProtonVPN
Secure50InternalYes, domain controllers as DNSJedi PC, my privileged workstation
Secure Client60InternalYes, domain controllers as DNSEnd-user PCs such as ObiPC
IDENTITY-A65AlphaSec-IdentityYes, narrow rangeActive Directory: two domain controllers, a management server, a test workstation
MGMT-A70AlphaSec-MgmtYes, narrow rangeProxmox node management, web GUI, SSH and Corosync link0
Cluster-Net71AlphaSec-MgmtNoneCorosync link1 only; no Internet access
Security-A72AlphaSec-ObservabilityYesSIEM and log workloads: security-01 (Wazuh) and splunk-siem
MONITOR-A73AlphaSec-ObservabilityYesmonitor-01: Prometheus, Grafana and their exporters
SERVERS-A80AlphaSec-ServersYesInternal application and database servers: app-01, alpha-prod-01
Access-A85AlphaSec-AccessYesReverse proxy and remote-access tooling: docker-network

The 12 zones, seven built-in and five custom:

ZoneTypeVLANsPurpose
InternalBuilt-inManagement, Server-Provision (5), Trusted (10), Personal-A (40), Proton-WiFi (45), Secure (50), Secure Client (60)Household, workstation and general lab networks
UntrustedBuilt-inIoT (20)Devices with no reason to reach the LAN
DmzBuilt-inDMZ (30)Internet-exposed workloads, blocked from Internal
ExternalBuilt-inInternet 1, Internet 2, ProtonVPN clientEverything outside
VpnBuilt-inFamilyVPN, Management Access, Game-Access, TempRemote-user WireGuard clients
GatewayBuilt-inNoneThe gateway itself, used as a destination for DNS and NTP
HotspotBuilt-inNoneUnused
AlphaSec-ServersCustomSERVERS-A (80)Internal apps and data
AlphaSec-MgmtCustomMGMT-A (70), Cluster-Net (71)Hypervisor management plane and cluster interconnect
AlphaSec-ObservabilityCustomSecurity-A (72), MONITOR-A (73)Detection, logging and monitoring
AlphaSec-AccessCustomAccess-A (85)Internal HTTPS front door and VPN mesh
AlphaSec-IdentityCustomIDENTITY-A (65)Active Directory

Two zones hold two VLANs each. Sharing a zone shares a trust posture, not a broadcast domain: MGMT-A and Cluster-Net stay separate VLANs, and so do Security-A and MONITOR-A.

Note: The UniFi zone endpoint returns an empty network list for every zone, so I read membership from each network’s own firewall_zone_id instead. Zone membership was last read that way on 2026-09-07.

UniFi network diagram: the two WAN uplinks, ProtonVPN client and NetBird mesh outside the gateway, the gateway, switches and access point, then the sixteen networks grouped into their firewall zones with VLAN IDs and representative members

The sixteen networks and their zones as read from the controller on 2026-09-24. Click to enlarge.

The zone-policy model

Ahsoka runs UniFi’s zone-based firewall. Traffic between two zones is blocked by default, so every cross-zone path in the lab exists because a policy names it. On 2026-09-26 the controller held 88 user-defined policies, 80 allows and eight blocks. That count leaves out the zone defaults and response companions the controller generates on its own.

The pieces a policy is built from:

ObjectCountUse
Network Lists22Ten IPv4 address groups (AG-) and 12 port groups (PG-). A policy that references a list follows its membership, so moving a host means editing one list and checking what references it.
Client groups16MAC-based groups, mostly household. The policy schema has no client-group selector, so admin MACs are written inline in the policies that need them.
OON policies4Only QoS for D is enabled. Two route through ProtonVPN with a kill switch when enabled; both are off.
Traffic routes1VPN - Proton, which sends Proton-WiFi out through the ProtonVPN client with a kill switch
Port forwards0

Order matters inside a source-destination pair. The egress sets for Access, Observability and Identity are each three policies at indexes 10000, 10001 and 10002: allow web, allow NTP, block everything else. If the block sits above the allows, web and NTP fail together. Automatic respond-policy generation is off for the Access and Observability trios.

Policy names keep their original wording after a zone rename, so seven still read AlphSec or A-Servers while the zones read AlphaSec.

What may talk to what

This is the policy table in prose, grouped by destination.

Management plane (AlphaSec-Mgmt). The broad allow from Internal is disabled. Only named devices get in: my admin devices by MAC to the Proxmox admin port group, ubuntu-dev by its own explicit policy, one dashboard host to Grey’s API, and the monitoring collector to node_exporter, the Proxmox API and NUT. The WireGuard VPN zone keeps broad access on purpose. Every one of these paths also has to pass the Proxmox Datacenter firewall on the node itself.

Servers (AlphaSec-Servers). Internal, the management zone and the VPN may reach SERVERS-A. The Internal allow covers every Internal network on every port, including Management, Server-Provision and Personal-A, which is broader than it looks. The Temp VPN is blocked from SERVERS-A and from Personal-A, Secure, Secure Client and Management.

Access (AlphaSec-Access). Internal and VPN clients may reach the reverse proxy. Going the other way, the proxy may reach each backend only on that backend’s listed web ports, one policy per backend. Three more policies let specific clients outside Internal reach the proxy over HTTPS: the container-management agents on alpha-prod-01 and security-01, and the domain test workstation. Access-A’s own egress is web and NTP from three named addresses, then a block.

Observability (AlphaSec-Observability). Internal and VPN clients may reach it. Inside the zone, the monitoring collector may scrape the security pair’s exporters, and Splunk may post to the alert bot on monitor-01. Every Wazuh agent source (SERVERS-A, the DMZ host, the five nodes, the reverse proxy, monitor-01 and the identity zone) has a narrow allow to the Wazuh manager on its agent ports. The collector reaches out to node_exporter on Personal-A hosts, SERVERS-A, the reverse proxy, the DMZ host and the identity servers’ Windows exporter. Jedi PC keeps a break-glass path to the monitoring UIs. Egress is web and NTP from the three observability hosts, then a block, plus DNS to the gateway for the collector.

Identity (AlphaSec-Identity). Secure and Secure Client reach the domain controllers on the Active Directory client port set, and the privileged workstation reaches the identity servers on the Windows admin port set. RDP is open to the identity hosts from Trusted and Secure, from two Personal-A hosts and from the Management Access VPN. Windows Admin Center is reachable from the two workstation networks and three named phones and laptops, and in turn may reach Secure Client over WinRM. The identity zone sends syslog to Splunk, may reach MeshCentral from the management server and the test workstation only, and uses the gateway for DNS and NTP. Its Internet egress is the web, NTP, block trio.

DMZ. Two block policies stop the DMZ from reaching Internal. Four admin MACs from Internal and the Management Access VPN may reach into the DMZ. The DMZ host’s outbound allows are narrow, named host-and-port rules.

Personal-A. Trusted is blocked from Personal-A even though both sit in Internal. Ten named device MACs may reach it, a separate policy lets two devices reach the media host, and the monitoring collector scrapes it.

IoT. Isolated from Internal, with one exception: Internal may reach the printer on the printing ports.

Proton-WiFi. It needs no policy. Its containment is the network isolation toggle, which blocks it from every other network, plus L2 isolation on the SSID so its own clients cannot reach each other.

DNS and DHCP

The gateway is the resolver for the LAN, and it answers a set of static local records that public DNS does not hold. On 2026-10-05 there were 31: 25 names pointing at Nginx Proxy Manager (one per live proxy host), five Proxmox node names on MGMT-A and one for Windows Admin Center on HQ-MGT01. Every internal HTTPS name follows the same pattern: one A record per proxy host, pointing at the proxy. How those names are used is on Access paths.

DHCP is on for every LAN except Cluster-Net. DMZ, IDENTITY-A and MGMT-A run narrow ranges, and the servers on them sit outside those ranges on fixed addresses. A DHCP reservation pins win11-dev on Personal-A. Three networks get non-default DNS:

  • Secure and Secure Client hand out the two domain controllers, first and second, since 2026-09-09. Domain members have to resolve through the controllers; pointing them at the gateway breaks service location lookups.
  • Proton-WiFi hands out Quad9, so lookups leave through ProtonVPN with everything else.
  • Server-Provision advertises the PXE boot server and the galaxy-ipxe.efi loader filename, which is how a bare-metal node finds Galaxy PXE.

The identity zone and the monitoring collector have explicit allows to the gateway for DNS, because the gateway is its own zone.

Wi-Fi

Anakin AP is the only access point and broadcasts on 2.4, 5 and 6 GHz. On the 2026-09-06 readback the controller had five WLANs, three enabled. The two the records name:

  • Proton-WiFi on VLAN 45, both bands, WPA2/WPA3 transition mode with PMF set to optional (the only valid value in transition mode), and L2 isolation on. I left the SSID disabled until the traffic route existed, because an enabled SSID with no route looks private and is not.
  • Alpha-Sec-IoT, disabled, bound to IoT VLAN 20 since the 2026-07-27 consolidation.

The 2026-07-27 firewall audit found no guest network or guest WLAN.

VPNs and port profiles

All remote-user VPN servers are WireGuard on the gateway. Only Management Access is enabled; FamilyVPN, Game-Access and Temp are disabled, and I have not confirmed in the interface whether One-Click VPN is still configured. One WireGuard client, ProtonVPN, provides the Proton egress.

Port profileModeNative networkTagged
ManagementUplinkManagementAll
TrustedEdgeTrusted (10)None
IoTEdgeIoT (20)None
Proxmox-TrunkUplinkNoneAll except Management, IoT, Trusted, Secure and Proton-WiFi
Server-ProvisionUplinkServer-Provision (5)All except Management, IoT, Trusted, DMZ, Secure and Proton-WiFi

Warning: The controller stores Proxmox-Trunk as an exclusion list and adds every new network to it automatically. A new VLAN does not reach the Proxmox nodes until I take it off the list. VLAN 45 stays excluded on purpose: a wireless VPN-egress network has no reason to reach a hypervisor.

Threat Management

Threat Management runs under CyberSecure on the gateway at the Standard (Free) protection level, with intrusion prevention on and 32,918 signatures on 2026-08-30.

SettingValue
Selected networksTrusted, IoT, Personal-A, Secure, Secure Client, MGMT-A, DMZ
Detection modeNotify and Block, since 2026-08-31
Active detectionsAll categories fully enabled except Protocol Vulnerabilities, 11 of 12

DMZ joined the list on 2026-08-30. I first left detection on Notify, meaning alert and forward, because I wanted to see what the signatures matched before letting them drop anything. I switched to Notify and Block the next day, before any signature match had been recorded, and I wrote that down rather than pretend the precondition was met. Detection mode is one gateway-wide setting, so blocking now applies to all seven inspected networks, and a false positive can drop traffic on Trusted and MGMT-A, not just the DMZ.

Eight networks were outside inspection when I last read the page: Management, Server-Provision, Proton-WiFi, Cluster-Net, Security-A, MONITOR-A, SERVERS-A and Access-A. Cluster-Net carries Corosync and nothing else, so inspecting it would add latency to the traffic least tolerant of it. The rest are a throughput decision, because every added network costs gateway processing. IDENTITY-A was created after that capture and its inspection state is not recorded.

How the segmentation got here

DateChange
2026-07-12Moved Wazuh, Prometheus, Grafana, Splunk and the log collectors into Security-A in one change, updating guest addresses, client targets and firewall destinations together.
2026-07-26Prometheus and Grafana moved again, to monitor-01 on MONITOR-A.
2026-07-27MGMT-A lockdown: disabled the broad Internal-to-management allow and cut one dashboard host to API only.
2026-07-27Zone and object consolidation (below). Deleted the AD-SERVERS network and Secure-V (VLAN 100).
2026-07-28Two more Kasm lab zones brought the count back to 16.
2026-08-07The internet-facing VM moved from DMZ-A (VLAN 90) to DMZ (VLAN 30), and Proxmox-Trunk started carrying VLAN 30.
2026-08-08Management Access VPN allowed into the DMZ.
2026-08-10Built Proton-WiFi (VLAN 45).
2026-08-19The Kasm decommission deleted its five VLANs (74, 75, 77, 78, 79), five zones and 68 policies, leaving 11 zones.
2026-08-29Deleted the empty DMZ-A (VLAN 90).
2026-08-30 / 31DMZ added to Threat Management; detection moved to Notify and Block.
2026-09-07IDENTITY-A on VLAN 65 and the AlphaSec-Identity zone, making 12 zones. VLAN 65 was admitted on Proxmox-Trunk.
2026-09-09Identity NTP allow moved above the block, and client DNS moved to the domain controllers.

The 2026-07-27 consolidation is the one that shaped the current model. Repeated selectors had become maintenance debt: monitor-01 appeared in 15 policies, the reverse proxy in nine. I created reusable address and port groups, moved 35 exact selectors across 24 policies onto them, and left 11 partial or mixed selectors inline where a group would have widened access. Cluster-Net moved into the management zone, and Security-A merged into the monitoring zone as AlphaSec-Observability. The total policy count, including generated ones, went from 431 to 361; custom policies from 61 to 59; zones from 16 to 14. I repointed policies before moving Security-A, so a stale block could not stop matching mid-change.

The identity-zone fix on 2026-09-09 is a good example of why order matters. The NTP allow sat below the catch-all block, so it never ran, and the domain controller holding the PDC emulator role fell back to its own CMOS clock. Every machine in the domain inherits that drift. Moving the allow above the block was the whole fix.

Backlog

  • Decide how far Threat Management coverage goes across the eight uninspected networks.
  • Confirm in the interface whether One-Click VPN is still configured.

Operating notes I keep because each one bit me once: an interrupted create still creates (a cancelled call on 2026-09-19 left two identical policies a millisecond apart), a deleted policy is not enforced at once (a probe still connected right after a delete and was refused about a minute later), and a policy update can silently drop its description. I verify selectors, action, enabled state, index and protocol after every change, and I test from the source host.

Records

Written from the public Homelab repository on GitHub, which records the lab's changes, incidents and current state.