From febe4b72bc9181f960ce03e49c72b3e33c1faf02 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 16 Aug 2026 17:16:17 +0100 Subject: [PATCH] chore(migration): all DNS through VyOS to Google, NAS out of the path The NAS is legacy for ad.itaz.eu and those records now live in Cloudflare, so the zone resolves publicly -- verified: nas001.ad.itaz.eu and kvm-macstudio1.ad.itaz.eu both answer from 8.8.8.8. That removes the reason for a conditional forward and lets the NAS leave the DNS path entirely. Two changes: - `service dns forwarding name-server` is now 8.8.8.8 and 8.8.4.4, the same pair the USG used on its WAN, instead of 10.0.0.194. - Every VLAN is handed the gateway as its resolver. UniFi set an explicit resolver on LoT only (the NAS); carrying that over would have kept the NAS in the path for one VLAN and not the other five, which is the sort of asymmetry nobody remembers a year later. The NAS is still referenced 9 times, all legitimate and checked: 4 NAT destination rules, the 4 matching firewall accepts for those port forwards, and its own DHCP reservation. No DNS references remain. Validated by loading vyos001's real running config on the labsim router and applying the full delta -- all 318 commands accepted, no errors. Installed on both boxes and verified in place: priority 200/100, upstream 8.8.8.8 + 8.8.4.4, six client resolvers, 377 lines each. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01DMVzWZgiKW2wquf5z8S1yH --- migration/unifi-to-vyos.py | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/migration/unifi-to-vyos.py b/migration/unifi-to-vyos.py index d2480c6..0c94ed0 100755 --- a/migration/unifi-to-vyos.py +++ b/migration/unifi-to-vyos.py @@ -31,10 +31,13 @@ import os import re import sys -# Where the production upstream resolver lives. Verified authoritative for -# ad.itaz.eu (SOA nas001.ad.itaz.eu) and also recursive, so it can serve as the -# single forwarder target. -UPSTREAM_DNS = "10.0.0.194" +# Upstream resolvers for VyOS's own forwarder -- the same pair the USG used on +# its WAN (wan_dns1/wan_dns2). The NAS at 10.0.0.194 is deliberately NOT here: +# it is legacy for ad.itaz.eu, and those records now live in Cloudflare, so the +# zone resolves publicly (verified: nas001.ad.itaz.eu and kvm-macstudio1 both +# answer from 8.8.8.8). That means no conditional forward is needed and the NAS +# is out of the DNS path entirely. +UPSTREAM_DNS = ["8.8.8.8", "8.8.4.4"] # labsim equivalents, keyed by VLAN id. Only VLAN 10 needs a /23: every one of # the 31 reservations is in LoT, which spans 10.0.0.x and 10.0.1.x, and a /24 @@ -150,14 +153,12 @@ def build(inv: dict, mode: str) -> tuple[list[str], dict]: out.append(f"{base} subnet-id {vlan}") out.append(f"{base} option default-router {gw}") - # Preserve UniFi's explicit resolver where it set one (LoT -> the NAS); - # otherwise hand out the gateway, which is what the USG does today and - # what `service dns forwarding` below will answer on. - for ns in (n["dhcp_dns"] or [gw]): - mapped = ns if ns not in (UPSTREAM_DNS,) or mode == "prod" else gw - if mode == "sim" and ns == UPSTREAM_DNS: - mapped = gw # no NAS in the sim; the router resolves - out.append(f"{base} option name-server {mapped}") + # Every VLAN is handed the gateway as its resolver, so all lookups go + # through VyOS and out to the upstreams above. UniFi set an explicit + # resolver on LoT only (the NAS); that is deliberately not carried over + # -- the NAS is legacy and pointing clients at it would keep it in the + # path for one VLAN and not the others. + out.append(f"{base} option name-server {gw}") if n["domain_name"]: out.append(f"{base} option domain-name '{n['domain_name']}'") @@ -198,11 +199,8 @@ def build(inv: dict, mode: str) -> tuple[list[str], dict]: vlan = vlan_of(n) out.append(f"set service dns forwarding listen-address {m.gateway(vlan, n)}") out.append(f"set service dns forwarding allow-from {m.net(vlan)}") - if mode == "prod": - out.append(f"set service dns forwarding name-server {UPSTREAM_DNS}") - else: - # The sim has no NAS; forward to whatever the sim host can reach. - out.append("set service dns forwarding name-server 1.1.1.1") + for ns in UPSTREAM_DNS: + out.append(f"set service dns forwarding name-server {ns}") out.append("set service dns forwarding cache-size 10000") stats["clamped"] = m.clamped