Files
oikos/containers/107-dns.md
dtoro 0ff592d237 DNS Phase 4: attempted single-zone, reverted (managed zone load-bearing)
Deleting the NetBird managed-zone replica broke mesh-peer DNS: the Mac
(NetBird 0.68.3) could not resolve hubris.network via the home-lab-dns
nameserver group (-> 192.168.8.2) even though it shows "Available" and the
192.168.8.0/24 route is present. Forwarding to the routed-LAN IP does not
actually serve queries on the current client. Restored the managed zone via
dns-sync.py and re-enabled the cron; resolution recovered.

Correction to Phase 2: the route fix delivered roaming-peer *service
connectivity* (the real iPhone win) but did NOT enable DNS forwarding. The
original "NetBird won't forward to Technitium for mesh peers" finding
stands; managed zone + sync are retained as load-bearing.

To finish single-source later: upgrade clients to 0.71.x, or point the
nameserver group at a mesh-native DNS IP (join CT 107 to the mesh).

Docs: dns.md + 107-dns.md corrected to reflect retained managed zone.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 15:33:33 +02:00

6.8 KiB
Raw Blame History

107 — dns

Homelab DNS server (Technitium). Replaces the dnsmasq that lived on 124 — authentik; single-purpose, one job.

At a glance

  • Hostname: dns
  • IP: 192.168.8.2 (static — stable, decoupled from any app)
  • Privilege: privileged (Docker-in-LXC, features: nesting=1)
  • Resources: 1 core / 1 GiB / 8 GiB rootfs
  • Created: 2026-06-01, Debian 13. Its own resolver is 1.1.1.1 (no circular dependency on the DNS it serves).

Role

Authoritative split-horizon DNS for hubris.network on the LAN/mesh, plus recursive forwarding (1.1.1.1, 8.8.8.8) for everything else. Technitium runs in Docker (technitium/dns-server:latest, network_mode: host), web console on :5380.

The hubris.network zone

  • Specific A overrides: app names → 192.168.8.175 (Caddy), nfs-export → 192.168.8.200, auth/sso/... as needed.
  • auth.hubris.network → 82.165.190.79 (VPS Authentik), sso.hubris.network → 192.168.8.175 (LAN forward-auth outpost).
  • Wildcard *.hubris.network → 82.165.190.79 — mirrors the public IONOS wildcard so undefined names (e.g. netbird) resolve to the VPS, matching public behaviour.
  • MX / SPF-TXT / CAA replicated from public so an authoritative zone doesn't shadow hubris.network email/cert records.

Config / access

  • /opt/technitium/docker-compose.yml; admin password in /opt/technitium/admin_password.txt (mode 600 — sops-encrypt in Phase 5).
  • Console: http://192.168.8.2:5380 (user admin).
  • API: http://192.168.8.2:5380/api/... (token via /api/user/login). Zone was built via the API.

Who points here

  • NetBird mesh peers: resolve hubris.network via the NetBird managed DNS zone (kept in sync from this Technitium — see dns-sync below). This is load-bearing, not redundant: a Phase 4 test (2026-06-21) that deleted the managed zone broke resolution for mesh peers. The home-lab-dns nameserver group (→ 192.168.8.2, applied to all peers) shows Available but does not actually serve queries on the current client (Mac 0.68.3) — forwarding to the routed-LAN IP silently returns nothing. The 2026-06-21 route fix (added Core192.168.8.0/24) restored service connectivity for roaming peers but did not change DNS-forwarding behavior.
  • Homelab DHCP clients: Technitium's own DHCP scope hands out 192.168.8.2 as the DNS server for 192.168.8.x leases (see DHCP section below).
  • Plain LAN clients (192.168.178.x): Fritz!Box DHCP still hands out Fritz!Box itself (192.168.178.1) as DNS, but the Fritz!Box now forwards upstream to Technitium — DNSv4 server set to 192.168.8.2 (Internet → Filter → DNS Server, 2026-06-17). So household clients get split-horizon *.hubris.network answers via Fritz!Box→Technitium, with no NetBird dependency. (This is the change that decoupled the on-prem tier from the mesh — see dns.md 2026-06-17.)

dns-sync (Technitium = authoring source)

/opt/dns-sync/sync.py (cron */10, logs /var/log/dns-sync.log) reconciles this zone's named A-records → the NetBird managed DNS zone via the NetBird API (/api/dns/zones/{id}/records). Token at /opt/dns-sync/netbird-token (mode 600; source of truth in sops secrets/netbird-pat.yaml). Edit DNS only here; the sync propagates to the mesh. It deletes NetBird records absent from Technitium. Tracked: scripts/dns-sync.py.

Why this exists — RETAINED (Phase 4 reverted 2026-06-21). The managed zone is the mechanism that actually answers hubris.network for mesh peers. We tried to retire it (forward to Technitium instead) on the theory that a missing route was the only blocker — adding Core to the 192.168.8.0/24 distribution did fix roaming-peer service connectivity. But deleting the managed zone then broke DNS resolution for mesh peers: forwarding to 192.168.8.2 reports Available yet does not serve queries on the current client (Mac 0.68.3). So the original "NetBird won't forward to Technitium for mesh peers" finding stands. The managed zone + this sync are kept. To remove them, forwarding must first be made to actually work — candidates: upgrade clients to 0.71.x, or point the nameserver group at a mesh-native DNS IP (join CT 107 to the mesh) rather than the routed-LAN 192.168.8.2. See dns.md changelog 2026-06-21.

DHCP

Technitium also runs a DHCP server for the homelab subnet (enabled 2026-06-02):

  • Scope: homelab192.168.8.241 192.168.8.254
  • Gateway: 192.168.8.1 (Proxmox vmbr0 alias)
  • DNS: 192.168.8.2 (self)
  • Lease time: 24 h

Replaces the DHCP that was previously served by the Slate AX router. Static-IP LXCs (.101.239) are excluded from the pool. Pool narrowed from .100.240 to .241.254 on 2026-06-03 to eliminate IP conflict risk.

Changelog

2026-06-06 — dns-sync cron installed (had been missing since deployment)

Although the 2026-06-03 changelog claimed "cron */10", no crontab was actually configured on the LXC. The sync was running only via ad-hoc manual invocations during incident debugging. Fixed by adding /etc/cron.d/dns-sync.

2026-06-03 — DHCP pool narrowed to .241.254

Previous pool .100.240 overlapped with all static LXCs/VMs (.101.239). Shrunk via API (/api/dhcp/scopes/set). 11 stale DHCP leases in .101.110 remain until natural expiry (2026-06-04). See plan.

2026-06-03 — dns-sync added (Technitium → NetBird managed zone)

This Technitium became the single DNS authoring source; /opt/dns-sync/sync.py (cron */10) reconciles named A-records into the NetBird managed zone via the API. Fixed previously-broken mesh names (sso, nfs-export, mcp, secrets) by adding them to the managed zone; reaped obsolete files/photos-new. See dns.md.

2026-06-02 — DHCP server enabled; replaces Slate AX DHCP

Enabled Technitium's built-in DHCP server for 192.168.8.0/24 (scope homelab, range .100.240, gateway 192.168.8.1, DNS self). Previously the Slate AX sub-router served DHCP for the homelab subnet. With the Slate AX retired and Proxmox now the subnet router, Technitium takes over DHCP. Configured via the Technitium API (/api/dhcp/scopes/set). DHCP LXCs kept their Slate AX leases until expiry, then renewed from Technitium.

2026-06-01 — created; replaced dnsmasq on 124

Stood up Technitium at 192.168.8.2, imported the split-horizon zone (specific A + wildcard + MX/SPF/CAA), made it the primary nameserver in the NetBird home-lab-dns group. Verified all names resolve with dnsmasq/124 stopped; LXC 124 retired.