Network¶
Last Updated: 2026-04-16 Purpose: Network topology, VLANs, DNS, and external access setup.
Physical Setup¶
All networking runs on UniFi equipment managed by the UCG Ultra. The switch topology is a chain from the bedroom wardrobe outward:
UCG Ultra (Bedroom wardrobe)
├── Port 2 → Bedroom AP (U7LT)
└── Port 3 → Bedroom Switch (USW Mini 5)
├── Port 5 → Living Room Switch (US8P60)
│ ├── Port 2 → Office Switch (USW Mini 5)
│ │ └── Port 3 → Office AP (U7LT)
│ └── Port 6 → Living Room AP (U7PG2)
└── (other ports → local bedroom devices)
For full hardware specs (models, MACs, firmware) see Hardware Inventory — Network Equipment.
WAN / Internet¶
WAN1 — Primary (Vodafone ADSL)¶
| Provider | Vodafone ADSL |
| Modem | Bedroom wardrobe, connected to phone socket behind curtain |
| Modem gateway | 192.168.99.254 |
| UCG Ultra port | 2.5GE WAN (port 5) |
| UPS backed | Yes (bedroom UPS) |
WAN2 — Backup (Three LTE)¶
| Provider | Three UK — LTE |
| Router | Zyxel LTE3302-M432 at 192.168.2.254 |
| Signal | -56 dBm RSSI (excellent) |
| UCG Ultra port | GE port 4 (configured as WAN2) |
| Mode | Failover only — activates automatically when WAN1 fails |
| NAT | Double NAT (Zyxel router mode + UCG Ultra) — harmless with Tailscale; no port forwarding used |
| UPS backed | Yes (bedroom UPS) |
Failover Configuration¶
WAN failover is handled automatically by the UCG Ultra: - Health check: Pings 8.8.8.8 and 1.1.1.1 every 5 seconds - Trigger: 80% packet loss to both targets over 30 seconds - Failback: Automatic when WAN1 recovers
VLANs¶
| VLAN | Name | Subnet | Purpose | DNS |
|---|---|---|---|---|
| — | MainLAN | 192.168.1.0/24 | Primary devices and servers | 192.168.1.11, 192.168.1.111 |
| 20 | IoT | 192.168.20.0/24 | IoT devices with internet access | 1.1.1.1, 4.4.4.4 (Cloudflare, direct) |
| 30 | NoT | 192.168.30.0/24 | IoT devices without internet access | 192.168.1.11, 192.168.1.111 |
| 66 | Guest | 192.168.40.0/27 | Guest WiFi (isolated) | Router |
| — | VPN | 192.168.3.0/24 | L2TP VPN server pool | — |
All of MainLAN, IoT and NoT sit inside the same UniFi Internal firewall zone, so traffic between them is permitted by default. NoT's isolation comes from internet_access_enabled: false on the network plus a Drop all other NoT catch-all policy, with narrow allow rules above it (Home Assistant, Mosquitto, DNS, NTP).
Cross-VLAN allow rules¶
IoT and NoT are each isolated by a catch-all BLOCK at the bottom of the Internal → Internal policy list, with every exception stacked above it:
| Index | Policy |
|---|---|
| 10000–10026 | the Allow … exceptions (Home Assistant, Mosquitto, DNS, NTP, Plex, Sonos, LMS, …) |
| 10027 | Allow Kindle to CWA — 192.168.20.244 → 192.168.1.80:8083/tcp |
| 40000 | BLOCK Drop IoT from local network — IoT → All local IP Addresses |
| 40001 | BLOCK Drop all other NoT |
Allow rules here only ever need one direction.
Allow Established and Related(index 10009, Internal → Internal) already permits the reply path for every session an allow rule opens. Adding a matching return rule is redundant — the only reasonAllow IoT to DNS Servershas a(Return)twin is that it is a predefined UniFi pair, not a pattern to copy.
To add an exception: create the policy, then drag it above the relevant 40000-series BLOCK. Anything left below it is silently dead.
Read the live list with:
unifi-q.py "v2/api/site/default/firewall-policies"
The claude code UniFi admin is read-only — it can list policies but gets 403 on any write, so rule changes must be made in the UI.
Time (NTP)¶
NoT has no internet, so devices there must use a local time source. Lotus (192.168.1.80) and Cooper (192.168.1.60) both serve NTP; the UCG does not.
⚠️ The
Allow all Local to NTPpolicy originally specified a source port of 123 as well as a destination port of 123. Only a classicntpdbinds local port 123 as a client — SNTP clients like Tasmota use an ephemeral port, so the rule never matched them and every NoT device sat at1970-01-01indefinitely. Fixed 2026-07-28 by setting the source port to Any on the Internal → Internal instance of the rule. See Lessons Learned.
Key IP Addresses¶
| Device | Hostname | IP |
|---|---|---|
| Gateway / Router | UCG Ultra | 192.168.1.1 |
| Bedroom Switch | — | 192.168.1.2 |
| Living Room Switch | — | 192.168.1.3 |
| Office Switch | — | 192.168.1.4 |
| Proxmox NUC | Pacific | 192.168.1.10 |
| Home Assistant VM | HomeAssistant | 192.168.1.12 |
| Desktop PC | Brabham | 192.168.1.40 |
| Backup NAS | Cooper | 192.168.1.60 |
| Primary NAS | Lotus | 192.168.1.80 |
| Local docs (nginx on Lotus) | docs.home | 192.168.1.81 |
| Gabriela dashboard (on Lotus) | gabriela.home | 192.168.1.82 |
| Bedroom AP | — | 192.168.1.171 (DHCP) |
| Living Room AP | — | 192.168.1.123 (DHCP) |
| Office AP | — | 192.168.1.101 (DHCP) |
| Primary DNS | 192.168.1.11 | |
| Secondary DNS | 192.168.1.111 |
Switches¶
| Name | IP | Location | Uplink |
|---|---|---|---|
| Bedroom Switch | 192.168.1.2 | Bedroom wardrobe | UCG Ultra Port 3 |
| Living Room Switch | 192.168.1.3 | Living room | Bedroom Switch Port 5 |
| Office Switch | 192.168.1.4 | Office outbuilding | Living Room Switch Port 2 |
Full specs (model, ports, firmware) in Hardware Inventory.
Access Points & WiFi¶
| Name | IP | Location | Uplink |
|---|---|---|---|
| Bedroom AP | 192.168.1.171 (DHCP) | Bedroom | UCG Ultra Port 2 |
| Living Room AP | 192.168.1.123 (DHCP) | Living room | Living Room Switch Port 6 |
| Office AP | 192.168.1.101 (DHCP) | Office outbuilding | Office Switch Port 3 |
All three APs broadcast four SSIDs on both 2.4 GHz and 5 GHz:
| SSID | VLAN | Purpose |
|---|---|---|
| 2SVT-Main | MainLAN | Primary network — trusted devices |
| IoT | IoT (20) | IoT devices with internet access |
| NoT | NoT (30) | IoT devices without internet access |
| Guest | Guest (66) | Isolated guest access |
Full specs (model, firmware) in Hardware Inventory.
2.4 GHz channel plan¶
Channels are pinned manually and auto-optimisation/RRM is left off — an RRM run can drop an AP onto a jammed channel. 2.4 GHz stays at 20 MHz width.
| AP | 2.4 GHz channel | Notes |
|---|---|---|
| Bedroom AP | 1 | |
| Living Room AP | 6 | Restored 2026-07-29 after the channel-6 jamming incident was resolved |
| Office AP | 1 | Shares ch1 with Bedroom; both are lightly loaded (cu_total 25 and 29) at opposite ends of the property |
2.4 GHz is shared with two Zigbee meshes — Sonoff/Zigbee2MQTT on channel 26 and Hue on channel 25, both at the top of the band. WiFi 1/6/11 are the only non-overlapping channels and they leave three gaps:
| Band | MHz | Occupant |
|---|---|---|
| WiFi ch 1 | 2401–2423 | Bedroom AP, Office AP |
| gap | 2423–2426 | Zigbee 15 (2425) — free |
| WiFi ch 6 | 2426–2448 | Living Room AP |
| gap | 2448–2451 | Zigbee 20 (2450) — free |
| WiFi ch 11 | 2451–2473 | free |
| top | 2473–2483 | Zigbee 25 (Hue), Zigbee 26 (Sonoff) |
Why the Office AP is still on ch1 rather than ch11: WiFi ch11's upper edge leaves only ~2 MHz to Zigbee 25 and ~7 MHz to Zigbee 26. Measured evidence (the Living Room AP sat on ch11 from 07-27 to 07-29, in the same room as both coordinators) showed no distance-correlated degradation of the Sonoff ch26 mesh — so ch11 is probably safe, especially for an AP in the outbuilding. But Hue on ch25 exposes no link metrics and remains unmeasured. The clean path is to move Hue 25 → 15 first, removing the only tight adjacency, then take the Office AP to 11 for a full 1/6/11 split.
Do not move the Sonoff coordinator off channel 26 — 75 devices, and battery TRVs/sensors often won't follow a channel change (hand re-pairing). Note ch26 runs at reduced TX power on CC2652 coordinators (band-edge limits), so suspect it first for any range or dropout issue.
Zigbee link quality is measurable via the sensor.*_linkquality entities — these are created disabled by default by Zigbee2MQTT and were all enabled on 2026-07-29. Baseline: min 18, max 142, average 69. Newly paired devices arrive with their LQI entity disabled and need enabling individually.
Diagnosing a jammed channel: cu_total ≥ 95 with cu_self_rx/cu_self_tx ≈ 0 and tx_packets ≈ 0 means external interference, not a busy AP. Read via unifi-login-api api/s/default/stat/device → radio_table_stats[]. stat/spectrumscan is not exposed on this UniFi version, so putting an AP on a channel is the only way to observe it.
External Access¶
Services are accessed externally via Tailscale + SWAG:
- Cloudflare DNS —
*.djchome.ukwildcard A record resolves to Lotus's Tailscale IP (100.106.140.33) - SWAG (reverse proxy on Lotus) — handles SSL termination and routes to the correct container
- Tailscale — only devices on the Tailnet can reach the Tailscale IP, so services are private by default
No ports are directly forwarded from the internet. Access requires being on the Tailnet.
A Tailscale exit node runs on Pacific (LXC 103), allowing Tailnet devices to route all traffic through the home network.
Exception: docs.djchome.uk is hosted on Cloudflare Pages and protected by Google authentication. It is accessible from anywhere without Tailscale.
SWAG Hot Spare¶
A standby SWAG instance runs on Cooper (Tailscale IP: 100.126.183.94). A failover script on Cooper monitors Lotus SWAG every 5 minutes and automatically updates the *.djchome.uk Cloudflare wildcard record to point to Cooper if Lotus is unreachable for two consecutive checks (~10 minutes). It fails back automatically when Lotus recovers.
See Cooper server doc for full details.
Domain¶
| Domain | djchome.uk |
| Wildcard | *.djchome.uk |
| DNS provider | Cloudflare |
| Docs site | docs.djchome.uk (Cloudflare Pages + Google Auth) |
| Cloudflare Pages project | homelab-docs |
| GitHub repo | danieljclark/homelab-docs |
DNS¶
| Server | IP | Notes |
|---|---|---|
| Primary | 192.168.1.11 | |
| Secondary | 192.168.1.111 |
AdGuard Home is installed on Pacific (LXC 101) but is not currently active as the primary DNS resolver.
The IoT VLAN (20) uses Cloudflare DNS (1.1.1.1 / 4.4.4.4) directly, bypassing local DNS filtering.
Notable IoT VLAN devices:
| Device | IP | Notes |
|---|---|---|
| Sonoff Zigbee Bridge (Tasmota) | 192.168.20.10 | Zigbee coordinator — living room, UPS backed, connects to HA via WiFi |
Security Posture¶
- No direct port forwarding from internet to internal services
- External access requires Tailscale (mesh VPN)
- IoT devices isolated on VLAN 20 (internet access) or VLAN 30 (no internet)
- Guest WiFi isolated on VLAN 66 — small pool, no access to internal devices
- Admin interfaces (Unraid, Proxmox, SWAG) not exposed externally
- L2TP VPN server available for legacy VPN clients
Documentation Access¶
| URL | Hosted on | Availability | |
|---|---|---|---|
| Cloud docs | https://docs.djchome.uk | Cloudflare Pages | Anywhere (requires Google login) |
| Local docs | http://docs.home (192.168.1.81) | nginx:alpine on Lotus (br0) | Home network only — syncs from GitHub every 30 min |