homelab-blueprint/docs/network/udm-pro-zones-migration.md
2026-06-15 11:19:21 +02:00

30 KiB

UDM Pro SE Zone-Based Firewall Migration

1. Scope

This document captures the migration of the existing UDM Pro SE network from its current VLAN layout to Zone-Based Firewalling with custom zones.

Public ingress is via Netbird, not WAN port-forwarding. A Netbird VPS is the public face; a Netbird agent runs on the Caddy host inside DMZ. No inbound listeners on the home WAN.

Public-safe notation:

  • Internal RFC1918 represented as 10.0.<vlan>.0/24.
  • Internal domain represented as home.example.com.

Current deployment:

  • Technitium runs in Docker on the Raspberry Pi at 10.0.10.5 on Office VLAN 10.
  • Office VLAN 10 is assigned to TRUSTED, so Technitium is a trusted-zone service. Explicit DNS allow rules are still required from restricted zones.

Required rollout order

Complete the migration in this dependency order:

  1. Technitium DNS first: make 10.0.10.5 authoritative for the internal zone and verify direct DNS queries from every current VLAN.
  2. Caddy and DMZ second: create VLAN 15, move Caddy to 10.0.15.5, update Technitium's caddy record, and verify reverse-proxy and Netbird traffic.
  3. Remaining zones last: assign FAMILY, MEDIA, IOT, and GUEST policies one zone at a time. Verify DHCP-provided DNS before enabling DNS DNAT for that zone.

Do not enable DNS DNAT or terminal drop rules until the direct DNS and Caddy checks for the affected zone pass.

2. Design Goals

  1. Preserve all 6 current UDM Pro SE VLANs and add only VLAN 15 for the Caddy DMZ.
  2. Use custom UniFi zones built from scratch — avoid implicit behavior in the default IoT / Hotspot zones, and avoid UniFi 9.x's intra-zone default-allow turning multi-VLAN zones into trust footguns.
  3. Keep the Proxmox host and all app VMs on VLAN 10 (no need to trunk additional VLANs to the hypervisor — Caddy lives on a dedicated host).
  4. Isolate Caddy in its own DMZ zone. Caddy is the only thing exposed to the Netbird overlay (the public attack surface), so a Caddy compromise cannot pivot to TRUSTED without traversing explicit firewall pinholes.
  5. Restrict MEDIA (TV/PS5/Apple TV) and FAMILY devices to Caddy + DNS + internet only — no access to the UDM gateway, NAS, workstations, or each other.
  6. Default-deny posture for IoT and Guest, with explicit allows only for DNS + internet.
  7. Use DNAT redirect (not block) for DNS enforcement on non-TRUSTED zones — silently captures hardcoded resolvers without breaking Smart TV / Chromecast firmware that fails on source-IP mismatches.

3. Current → Target VLAN Map

VLAN VLAN ID CIDR Status Target Zone Notes
LAN 1 10.0.1.0/24 Kept TRUSTED UDM, switch, AP, and infrastructure management
Office 10 10.0.10.0/24 Kept TRUSTED Workstations, Proxmox apps, and Technitium
DMZ 15 10.0.15.0/24 New DMZ Dedicated Caddy host (Netbird agent here)
Family 20 10.0.20.0/24 Kept FAMILY Family devices
IoT 30 10.0.30.0/24 Kept IOT Custom zone, not UniFi default IoT zone
Media 40 10.0.40.0/24 Kept MEDIA TV/PS5/Apple TV, restricted to Caddy + DNS
Guest 50 10.0.50.0/24 Kept GUEST Custom zone, not UniFi default Hotspot

Net: 6 current VLANs → 7 target VLANs. VLAN 15 is the only new network. LAN and Office intentionally share TRUSTED, where unrestricted intra-zone routing is acceptable.

4. Target Zones

UniFi 9.x permits custom zones. The defaults (Internal, IoT, Hotspot, DMZ, VPN) are not used — they stay empty. Gateway and External are mandatory and cannot be removed.

Note on UniFi intra-zone behavior: UniFi 9.x's default-allow inside a zone is not configurable. Two VLANs in the same zone can freely initiate L3 unicast to each other regardless of subnet boundaries. This design therefore puts each policy boundary in its own zone — no aggregating FAMILY+MEDIA or IOT+GUEST into shared zones.

Zone Type VLAN(s) Members Consolidates
TRUSTED Custom 1 (10.0.1.0/24), 10 (10.0.10.0/24) UDM, switch + AP mgmt, workstations, Proxmox host + app VMs, UNAS Pro, and Technitium DNS (10.0.10.5) LAN + Office
DMZ Custom 15 (10.0.15.0/24) Dedicated Caddy host (10.0.15.5) running Netbird agent New
FAMILY Custom 20 (10.0.20.0/24) Family phones / tablets / laptops Family
MEDIA Custom 40 (10.0.40.0/24) PS5, Samsung TV, Apple TV Media
IOT Custom 30 (10.0.30.0/24) Smart-home devices, Zigbee coordinator (SLZB-06U) IoT
GUEST Custom 50 (10.0.50.0/24) Visitor devices Guest
Gateway Built-in (mandatory) UDM Pro SE itself
External Built-in (mandatory) WAN

5. Address References in UniFi 10.4.57

UniFi Network 10.4.57 does not expose reusable named IP-address groups for zone-based policies. The names CADDY, DNS, BACKEND_APPS, IOT_BACKENDS, and RFC1918 in this document are design labels only.

There is nothing to create in UniFi at this step. After completing the zones in §4, verify that the addresses listed below are correct for your devices, then continue with the migration sequence in §11. Create each firewall policy only when its rollout phase tells you to do so.

Step 5 is complete when you have confirmed:

  • Caddy will use static/reserved address 10.0.15.5.
  • Technitium DNS uses static/reserved address 10.0.10.5.
  • The Caddy upstream addresses and ports in §5.4 match the current docker-compose-files/caddy/Caddyfile_template.
  • SLZB-06U uses 10.0.30.5 and the Home Automation host uses 10.0.30.6.
  • The RFC1918 CIDRs are recorded as 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16.

Do not use Settings → Policy Engine → Objects. That page applies Secure, Route, and QoS policies to selected clients or networks; it does not create firewall address objects.

How the policy tables map to the Create Policy panel

When a later phase tells you to create a policy, open Settings → Policy Engine → Policy Table → Create New Policy. In the right-side Create Policy panel, use the table row as follows:

Table column/value Exact control to use in the Create Policy panel
Policy name Keep Firewall selected at the top, then type the value into Name.
Source zone Open the Source Zone dropdown and select the named custom zone, such as MEDIA or DMZ.
Source IP = Any Under Source Zone, keep the Any radio button selected. This means every client in the selected source zone.
Source IP = an address Under Source Zone, select the IP radio button. An address-entry field appears; enter the listed source IP. Do not select Device, Network, MAC, or Identity.
Source port = Any In the Port row inside Source Zone, keep Any selected. All policies in this guide use source port Any.
Action = Allow/Block In the separate Action card, select Allow or Block exactly as listed. Do not use Reject unless the guide explicitly says so.
Destination zone Open the Destination Zone dropdown and select the listed zone. Select Any only for a policy whose destination zone is explicitly Any.
Destination IP = an address/CIDR Under Destination Zone, select the IP radio button. Enter every listed IP address or CIDR into the field that appears. Do not select App, Domain, or Region.
Destination IP = Any Under Destination Zone, keep the Any radio button selected.
Destination ports In the Port row inside Destination Zone, select Specific and enter the listed destination port or ports. Use List only if you have separately created a reusable named port list.
IP Version Select IPv4 because this guide uses IPv4 addresses.
Protocol = TCP Select TCP.
Protocol = TCP and UDP Select TCP/UDP.
Protocol/ports = Any Select protocol All and leave both source and destination ports as Any.
Connection State Keep All selected unless a policy explicitly says otherwise.
Match IPsec Leave disabled.
Syslog Logging Enable temporarily while testing if you want match logs; otherwise leave disabled.
Schedule Keep Always selected.

After filling the panel, click Add Policy. In the Policy Table, use Reorder to keep specific allow policies above broad block policies.

Do not create or enable all policies below at once. Create the DNS and Caddy allows first, test them, and add broad block policies only at the end of each zone's rollout.

5.1 Worked example: ALLOW MEDIA to CADDY web

Use this example to learn how the columns in the policy tables below map to the Create Policy panel. This policy permits devices in the MEDIA zone to reach only Caddy at 10.0.15.5 on HTTP and HTTPS.

  1. Open Settings → Policy Engine → Policy Table → Create New Policy.
  2. At the top of Create Policy, select Firewall.
  3. Set Name to ALLOW MEDIA to CADDY web.
  4. Under Source Zone:
    • Select zone MEDIA.
    • Select Any for the source matcher.
    • Leave source Port set to Any.
  5. Under Action, select Allow.
  6. Under Destination Zone:
    • Select zone DMZ.
    • Select IP, then enter 10.0.15.5.
    • Under Port, select Specific, then enter destination ports 80 and 443.
  7. Under IP Version, select IPv4.
  8. Under Protocol, select TCP.
  9. Under Connection State, leave All selected. UniFi's default return traffic policy permits replies to this allowed connection.
  10. Leave Match IPsec disabled.
  11. Enable Syslog Logging during rollout if you want to confirm policy matches; it may be disabled after validation.
  12. Under Schedule, select Always.
  13. Optionally set Description to Allow Media clients to reach the Caddy reverse proxy on HTTP/HTTPS.
  14. Click Add Policy.
  15. In the Policy Table, ensure this allow policy is above BLOCK MEDIA to RFC1918 and any terminal MEDIA block policy.

The finished policy should read approximately:

Name:              ALLOW MEDIA to CADDY web
Action:            Allow
Source Zone:       MEDIA
Source:            Any
Source Port:       Any
Destination Zone:  DMZ
Destination IP:    10.0.15.5
Destination Ports: 80, 443
IP Version:        IPv4
Protocol:          TCP
Connection State:  All
Schedule:          Always

For every remaining policy in this guide, follow the same panel order and replace only the values shown in that policy's table row.

5.2 Policies targeting Caddy (CADDY)

Create both policies:

Policy name Action Source zone Source IP Destination zone Destination IP Protocol / destination ports
ALLOW FAMILY to CADDY web Allow FAMILY Any DMZ 10.0.15.5 TCP 80,443
ALLOW MEDIA to CADDY web Allow MEDIA Any DMZ 10.0.15.5 TCP 80,443

These policies do not clash with zones. The zone selects the broad path, such as MEDIA to DMZ; destination IP 10.0.15.5 narrows that path to Caddy only.

5.3 Policies targeting Technitium DNS (DNS)

Create one allow policy for each listed source zone:

Policy name Action Source zone Source IP Destination zone Destination IP Protocol / destination port
ALLOW DMZ to DNS Allow DMZ Any TRUSTED 10.0.10.5 TCP and UDP 53
ALLOW FAMILY to DNS Allow FAMILY Any TRUSTED 10.0.10.5 TCP and UDP 53
ALLOW MEDIA to DNS Allow MEDIA Any TRUSTED 10.0.10.5 TCP and UDP 53
ALLOW IOT to DNS Allow IOT Any TRUSTED 10.0.10.5 TCP and UDP 53
ALLOW GUEST to DNS Allow GUEST Any TRUSTED 10.0.10.5 TCP and UDP 53

5.4 Caddy to TRUSTED backend policies (BACKEND_APPS)

Create these policies from the current docker-compose-files/caddy/Caddyfile_template. Keep separate policies for different destination ports so one backend is not accidentally allowed to use another backend's port.

Every policy in this table uses:

  • Action: Allow
  • Source zone: DMZ
  • Source IP: 10.0.15.5
  • Destination zone: TRUSTED
  • Protocol: TCP
Policy name Destination IP Destination port(s) Current upstream purpose
ALLOW CADDY to LAN web devices 10.0.1.5, 10.0.1.8 80 Lite-8 and TP-Link switch UIs
ALLOW CADDY to Technitium UI 10.0.10.5 5380 Technitium admin UI
ALLOW CADDY to NAS apps 10.0.10.24 5000,5055,6767,7878,8000,8080,8096,8191,8282,8989,9696 NAS and media-stack apps
ALLOW CADDY to PBS 10.0.10.8 8007 Proxmox Backup Server
ALLOW CADDY to Proxmox 10.0.10.10 8006 Proxmox
ALLOW CADDY to Bento PDF 10.0.10.6 8080 Bento PDF
ALLOW CADDY to Beszel 10.0.10.13 8090 Beszel
ALLOW CADDY to Drawio 10.0.10.9 8080 Drawio
ALLOW CADDY to Gramps 10.0.10.17 5000 Gramps
ALLOW CADDY to Immich 10.0.10.15 2283 Immich
ALLOW CADDY to IT Tools 10.0.10.7 80 IT Tools
ALLOW CADDY to Paperless 10.0.10.11 8000 Paperless-ngx
ALLOW CADDY to Speedtest 10.0.10.16 80 Speedtest
ALLOW CADDY to YTD 10.0.10.14 3033 MeTube/YTD

Delete or disable a policy when its matching Caddy upstream is removed.

5.5 Caddy to IOT backend policies (IOT_BACKENDS)

Both policies use action Allow, source zone DMZ, source IP 10.0.15.5, destination zone IOT, and protocol TCP:

Policy name Destination IP Destination port(s) Purpose
ALLOW CADDY to Zigbee 10.0.30.5 80 SLZB-06U web UI
ALLOW CADDY to Home Automation 10.0.30.6 1880,8080,8123 Node-RED, Zigbee2MQTT, and Home Assistant

5.6 RFC1918 block policies

After the specific allow policies above work, create one RFC1918 block policy for each restricted source zone. For each policy, set destination zone to Any and enter all three destination CIDRs:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
Policy name Action Source zone Source IP Destination zone Destination IPs Protocol / ports
BLOCK DMZ to RFC1918 Block DMZ Any Any All three RFC1918 CIDRs Any
BLOCK FAMILY to RFC1918 Block FAMILY Any Any All three RFC1918 CIDRs Any
BLOCK MEDIA to RFC1918 Block MEDIA Any Any All three RFC1918 CIDRs Any
BLOCK IOT to RFC1918 Block IOT Any Any All three RFC1918 CIDRs Any
BLOCK GUEST to RFC1918 Block GUEST Any Any All three RFC1918 CIDRs Any

Policy order is mandatory: place the specific Caddy, DNS, and backend allow policies above these RFC1918 block policies. Otherwise, the broad RFC1918 blocks will match and drop the intended traffic first.

6. Public Ingress via Netbird

Home WAN has no inbound listeners. Public traffic flow:

Internet → Netbird VPS (public face) → WireGuard mesh → Caddy host (Netbird agent, VLAN 15)
                                                              ↓
                                                       reverse-proxies to BACKEND_APPS on VLAN 10

Implications:

  • No port-forward rule on the UDM.
  • No External → DMZ firewall rule needed.
  • Caddy receives app traffic on its Netbird tunnel interface (wt0), not on its VLAN 15 interface from WAN.
  • The DMZ zone still earns its keep: the Netbird tunnel is the public attack surface. Compromise of the VPS or Caddy must not pivot to TRUSTED except via explicit pinholes.
  • Caddy needs outbound WAN for Netbird signal/STUN + ACME DNS-01 — handled by the standing DMZ → External allow.

TLS termination model assumed: TLS passthrough at the VPS (home Caddy handles certs, sees real SNI). If the VPS terminates TLS instead, Caddy receives plaintext over the tunnel and does not need outbound :53 to public DNS providers.

7. Zone Policy Matrix

Policy objective: default drop. Apply each table top-to-bottom and include the listed terminal block rule so the design does not depend on an implicit UniFi default.

7.1 TRUSTED

# From To Action Protocol/Port Purpose
1 TRUSTED TRUSTED Allow any Intra-zone (Proxmox ↔ apps ↔ NAS ↔ workstations)
2 TRUSTED any Allow any Admin path; Trusted is the management zone

DNS for TRUSTED: DHCP option 6 → 10.0.10.5. This design does not force DNAT for TRUSTED because workstations are trusted. Office clients and Technitium share 10.0.10.0/24, so their DNS traffic does not traverse the UDM Pro SE and cannot be redirected there. LAN VLAN 1 traffic is routed, but remains unenforced by policy.

7.2 DMZ

# From To Action Protocol/Port Purpose
1 DMZ (CADDY) TRUSTED (BACKEND_APPS) Allow TCP, app-specific ports Caddy → backend pinhole
2 DMZ DNS Allow UDP/TCP 53 Internal name resolution
3 DMZ (CADDY) IOT (IOT_BACKENDS) Allow TCP 80, 1880, 8080, 8123 Proxied IoT and Home Automation UIs
4 DMZ External Allow any Netbird signal/STUN + ACME DNS-01 + Docker pulls
5 DMZ Gateway Block any No UDM admin from Caddy
6 DMZ RFC1918 (minus explicit pinholes) Block any No lateral movement
7 DMZ any Block any Drop all other unmatched traffic

7.3 MEDIA

# From To Action Protocol/Port Purpose
1 MEDIA CADDY Allow TCP 80, 443 Split-horizon access to internal services
2 MEDIA DNS Allow UDP/TCP 53 Name resolution (via DNAT redirect — see §8)
3 MEDIA External Allow any Internet (streaming, PSN, updates)
4 MEDIA Gateway Block any No UDM admin
5 MEDIA RFC1918 Block any No access to TRUSTED/FAMILY/IOT/GUEST
6 MEDIA any Block any Drop all other unmatched traffic

7.4 FAMILY

# From To Action Protocol/Port Purpose
1 FAMILY CADDY Allow TCP 80, 443 Split-horizon access to internal services
2 FAMILY DNS Allow UDP/TCP 53 Name resolution (via DNAT redirect — see §8)
3 FAMILY External Allow any Internet
4 FAMILY Gateway Block any No UDM admin
5 FAMILY RFC1918 Block any No access to TRUSTED/MEDIA/IOT/GUEST
6 FAMILY any Block any Drop all other unmatched traffic

7.5 IOT

# From To Action Protocol/Port Purpose
1 IOT IOT Allow any Intra-zone (hub ↔ devices)
2 IOT DNS Allow UDP/TCP 53 Name resolution (via DNAT redirect — see §8)
3 IOT External Allow any Cloud updates / vendor services
4 IOT RFC1918 Block any No lateral movement
5 IOT Gateway Block any No UDM admin
6 IOT any Block any Drop all other unmatched traffic

Home Assistant, Zigbee2MQTT, Node-RED, and SLZB-06U remain inside IOT. Their east-west traffic is permitted by the IOT intra-zone rule.

# From To Action Protocol/Port Purpose
- IOT (10.0.30.6) IOT (10.0.30.5) Allow TCP 6638 Zigbee2MQTT ↔ Zigbee coordinator

7.6 GUEST

# From To Action Protocol/Port Purpose
1 GUEST DNS Allow UDP/TCP 53 Name resolution (via DNAT redirect — see §8)
2 GUEST External Allow any Internet
3 GUEST RFC1918 Block any Total isolation from internal
4 GUEST Gateway Block any No UDM admin
5 (network setting) Client isolation ON Guest-to-guest blocked at L2
6 GUEST any Block any Drop all other unmatched traffic

7.7 Compact zone-to-zone matrix

↓ From / To → TRUSTED DMZ FAMILY MEDIA IOT GUEST Gateway External
TRUSTED any any any any any any any any
DMZ ⚠ pinhole¹ ⚠ proxy pinholes any
FAMILY ⚠ DNS² ⚠ proxy³ any
MEDIA ⚠ DNS² ⚠ proxy³ any
IOT ⚠ DNS² any any
GUEST ⚠ DNS² (isolated) any

Legend: allow · block · ⚠ allow only listed flows.

Footnotes:

  1. DMZ → TRUSTED pinhole: Caddy IP only, targeting BACKEND_APPS IPs on app-specific TCP ports. Include only routes actually published in docker-compose-files/caddy/Caddyfile_template, including Technitium TCP 5380 when dns01 is enabled. Drop all other DMZ → TRUSTED traffic.
  2. DNS via DNAT redirect (§8) — destination 10.0.10.5:53 on UDP/TCP only; all other :53 is silently rewritten.
  3. Proxy access: TCP 80, 443 to Caddy IP only.

8. DNS Handling — DNAT Redirect Strategy

Use UDM Pro SE Destination NAT (DNAT) policies to redirect DNS traffic to Technitium. This is invisible to the client (no source-IP mismatch error) and replaces the brittle "block :53 to !DNS" approach.

Why DNAT instead of block

A hard :53 block breaks devices that hardcode 8.8.8.8 (some Smart TVs, Chromecasts). DNAT silently rewrites those queries to Technitium. Client thinks it got a reply from 8.8.8.8; the UDM's reverse-NAT puts the masked source IP back on the return packet.

Why TRUSTED does not use DNAT in this design

TRUSTED does not get a DNAT rule because its workstations are trusted, not because every TRUSTED client can be intercepted consistently. Office clients share a subnet with Technitium, so their DNS traffic does not cross the UDM Pro SE. LAN VLAN 1 queries do cross it, but enforcing only part of TRUSTED adds complexity without matching the policy objective.

Rules

Zone DHCP option 6 DNAT rule :53 block
TRUSTED 10.0.10.5 None None (trust workstations)
DMZ 10.0.10.5 None (Caddy needs ACME DNS-01 out to WAN)
FAMILY 10.0.10.5 dst !10.0.10.5 UDP/TCP 53 → 10.0.10.5:53 — (DNAT replaces)
MEDIA 10.0.10.5 same as FAMILY
IOT 10.0.10.5 same as FAMILY
GUEST 10.0.10.5 same as FAMILY

Practically, this is one DNAT entry with source = group of {FAMILY, MEDIA, IOT, GUEST}.

Technitium prerequisite — Allowed Networks

The repository compose template defaults TECHNITIUM_RECURSION_ACL to include RFC1918 networks. Verify that the running server still permits every client subnet under Settings → DNS Server → Allowed Networks (ACL), especially if the UI configuration has overridden the container startup defaults:

  • 10.0.10.0/24 (TRUSTED)
  • 10.0.1.0/24 (TRUSTED infrastructure)
  • 10.0.15.0/24 (DMZ — Caddy split-horizon lookups)
  • 10.0.20.0/24 (FAMILY)
  • 10.0.30.0/24 (IOT)
  • 10.0.40.0/24 (MEDIA)
  • 10.0.50.0/24 (GUEST)

9. Caddy Host Hardening (VLAN 15)

The Caddy host is a dedicated machine (or dedicated VM on its own hypervisor — not the main Proxmox host). It is the only member of DMZ.

  1. Untagged access port on the switch — feeding port is access-mode VLAN 15, no trunk.
  2. SSH source-locked to TRUSTED:
    ufw allow from 10.0.1.0/24 to any port 22 proto tcp
    ufw allow from 10.0.10.0/24 to any port 22 proto tcp
    ufw deny 22/tcp
    
  3. Lock down wt0 (Netbird interface) — only Caddy listening ports accept tunnel traffic:
    ufw allow in on wt0 to any port 80,443 proto tcp
    ufw deny in on wt0
    
  4. Permit intended LAN-side proxy clients on Caddy's VLAN interface:
    ufw allow from 10.0.1.0/24 to any port 80,443 proto tcp
    ufw allow from 10.0.10.0/24 to any port 80,443 proto tcp
    ufw allow from 10.0.20.0/24 to any port 80,443 proto tcp
    ufw allow from 10.0.40.0/24 to any port 80,443 proto tcp
    
  5. No Docker socket mount. docker-compose.yml for Caddy must not include /var/run/docker.sock:/var/run/docker.sock. Prevents container-escape → host root via socket abuse.
  6. Drop capabilities: cap_drop: [ALL] + cap_add: [NET_BIND_SERVICE] in the Caddy compose service. Container can bind 80/443, nothing else.
  7. Netbird agent runs as a host systemd service, not inside the Caddy container. Keeps tunnel state out of the proxy blast radius.
  8. ACME via DNS-01 only — no inbound HTTP listener needed (and none possible without port-forward). Caddy needs outbound :443 to your DNS provider's API.

10. Wi-Fi SSID → VLAN Mapping

SSID VLAN Zone Purpose
home-trusted 10 TRUSTED Personal phones, laptops, workstations
home-family 20 FAMILY Family devices
home-iot 30 IOT Smart-home devices (2.4 GHz typically)
home-guest 50 GUEST Visitors — client isolation on

Media devices (TV, PS5, Apple TV) are wired to TL-SG108 with port-based VLAN 40 tagging on the uplink to the Lite-8.

11. Migration Sequence

Phase 0 — Back up and inventory

  1. Back up the UDM Pro SE configuration.
  2. Confirm the six current VLANs, DHCP scopes, switch port profiles, and SSID mappings.
  3. Record the current Caddy address, backend application addresses, and ports.
  4. Inventory the address values represented by the DNS, CADDY, BACKEND_APPS, IOT_BACKENDS, and RFC1918 design labels in §5. These values will be entered directly into Policy Table rules.

Phase 1 — Establish Technitium DNS

  1. Deploy Technitium at 10.0.10.5 by following the Technitium deployment guide.
  2. Configure the internal primary zone and verify recursion, blocking, and direct lookups from LAN and Office.
  3. Add all current and target client networks to Technitium Allowed Networks (§8), including the future DMZ subnet 10.0.15.0/24.
  4. Configure every current VLAN's DHCP option 6 to advertise 10.0.10.5.
  5. Add temporary firewall allows for UDP/TCP 53 from every current VLAN to destination IP 10.0.10.5. Do not add DNS DNAT yet.
  6. Renew a client lease on each VLAN and verify both direct and normal resolver queries:
    dig @10.0.10.5 example.com
    dig example.com
    
  7. Continue only after Technitium's query log shows successful requests from LAN, Office, Family, IoT, Media, and Guest.

Phase 2 — Move Caddy into DMZ

  1. Create VLAN 15 (10.0.15.0/24) and the DMZ custom zone.
  2. Stand up the dedicated Caddy host at 10.0.15.5 by following the Caddy Raspberry Pi deployment guide; apply the host hardening in §9.
  3. Allow DMZ to DNS, DMZ to External, and Caddy to the required BACKEND_APPS ports before adding DMZ block rules.
  4. Install the Netbird agent and verify its tunnel to the VPS.
  5. Update Technitium's caddy.home.example.com record to 10.0.15.5.
  6. Verify Caddy from LAN and Office, then from the Netbird path.
  7. Add the remaining DMZ block rules only after proxying, DNS, ACME, and Netbird checks pass.

Phase 3 — Apply remaining zones

Apply zones one at a time in this order: FAMILY → MEDIA → IOT → GUEST. For each zone:

  1. Create the custom zone and assign its existing VLAN.
  2. Add allow rules for DNS, CADDY where applicable, and External.
  3. Renew a client DHCP lease and verify normal DNS, internet access, and intended Caddy access.
  4. Add the RFC1918, Gateway, and terminal block rules.
  5. Repeat the functional and isolation tests.
  6. Enable DNS DNAT for that zone last, then verify a query sent to a public resolver appears in Technitium's query log:
    dig @1.1.1.1 example.com
    

Keep the previous zone/firewall configuration backup until 24-48h of soak passes without rule misses.

12. Validation Checklist

DNS gate

  1. DHCP on every VLAN advertises 10.0.10.5.
  2. Direct and normal DNS queries work from every VLAN.
  3. Technitium's query log identifies requests from every client subnet.
  4. Technitium web administration is reachable only from TRUSTED.

Caddy gate

  1. UDM Pro SE shows VLAN 15 with Caddy at 10.0.15.5.
  2. caddy.home.example.com resolves to 10.0.15.5.
  3. Caddy resolves internal names through Technitium and public ACME names without DNS DNAT interception.
  4. Caddy reaches only required BACKEND_APPS ports and cannot reach UDM administration or unrelated trusted hosts.
  5. Caddy's Let's Encrypt DNS-01 renewal and Netbird ingress both succeed.

Zone gate

  1. FAMILY and MEDIA can resolve DNS, reach intended Caddy services, and access the internet, but cannot reach other internal hosts.
  2. IOT can resolve DNS and access required cloud services; Zigbee2MQTT can still reach SLZB-06U over TCP 6638.
  3. GUEST can resolve DNS and access the internet, but cannot reach internal hosts or other guests.
  4. DNS DNAT tests from FAMILY, MEDIA, IOT, and GUEST appear in Technitium's query log.
  5. The 6 custom zones contain the intended 7 VLANs; unused default zones are empty.

13. Open Decisions

  1. TLS termination at VPS or home Caddy? Default in this doc: passthrough to home Caddy. If switched to VPS-terminates, drop the outbound :443 to DNS provider requirement (move ACME to VPS).
  2. Apple TV / Chromecast cross-zone casting: if family phones (FAMILY) need to cast to Apple TV (MEDIA), enable mDNS reflector between FAMILY ↔ MEDIA and add explicit AirPlay/Chromecast pinholes (TCP 5000/7000 for AirPlay, 8008/8009 for Chromecast). Off by default.
  3. Wired Media uplink: TL-SG108 is unmanaged — it passes tagged VLAN 40 transparently but cannot enforce port-VLAN binding. If untrusted devices ever land on it, replace with a managed access switch.
  4. TRUSTED :53 enforcement: currently trust workstation hygiene. Hard enforcement for Office requires moving Technitium or clients across a routed boundary; UDM Pro SE rules cannot intercept same-subnet DNS traffic.