Connectivity & Naming Stack (OpenWRT + Technitium + ExternalDNS)
Scope
Defines how names under risu.tech are resolved for LAN, VPN, and Kubernetes workloads, and how DNS automation and failure modes behave.
Goals
- Internal names (e.g.,
wiki.risu.tech) resolve only on LAN/VPN. - Public names resolve from anywhere without exposing internal metadata.
- Internal DNS is authoritative and automated from Kubernetes via ExternalDNS.
- DNS outages degrade safely: public domains keep resolving and the platform can bootstrap without internal DNS.
Non-Goals
- Multi-site or geo-distributed DNS.
- Automating the public zone in this phase.
- Making the router a permanent authoritative DNS platform.
Roles and Responsibilities
- OpenWRT (bootstrap resolver): DHCP authority, default resolver for clients, recursion to public upstreams, conditional forward of internal zones to Technitium, local static overrides for recovery.
- Technitium DNS (internal authority): Hosts authoritative internal records and optional recursion; reachable only from LAN/VPN; uses IP-based upstream configuration.
- ExternalDNS (automation controller): Watches Kubernetes resources and reconciles allowed records into Technitium; limited to explicitly delegated hostnames.
Resolution Flows
- Internal name (normal): Client → OpenWRT → Technitium → internal VIP/endpoint.
- Public name: Client → OpenWRT → public recursive resolution.
Dependency-Loop Prevention
- Principle: nothing required to bootstrap the platform should depend on Technitium.
- Invariants:
- Clients always use OpenWRT as resolver in Phase 1.
- OpenWRT keeps minimal static records (Technitium VIP and internal ingress VIP) to reach recovery paths.
- Technitium upstreams are configured by IP or forward recursion to OpenWRT by IP.
- ExternalDNS targets Technitium by stable IP/VIP, not hostname.
Failure Behavior
- Technitium down: Internal names fail except the static overrides; public names still resolve via OpenWRT.
- ExternalDNS down: Existing records served; no new automation until it returns.
- OpenWRT DNS down: Clients lose DNS (Phase 1 SPOF); acceptable until resolver redundancy is added.
Zone Strategy
- Preferred: split-horizon
risu.tech(same zone name internal and public). - Safety controls: Technitium not reachable from WAN; ExternalDNS constrained via annotation/label allowlists, TXT ownership, and domain filters; public DNS managed separately.
- Alternative: internal sub-zone such as
int.risu.techif split-horizon proves risky.
Record Ownership
- ExternalDNS-managed: Annotated Kubernetes services/ingresses that are allowed for automation.
- Manually managed: Bootstrap overrides on OpenWRT, core infrastructure names, sensitive records.
Kubernetes Integration
- CoreDNS handles in-cluster service discovery and does not depend on Technitium.
- ExternalDNS maintains registry markers to avoid overwriting manual records.
- Prefer VIP/stable IP for Technitium reachable from OpenWRT and workloads.
Testing
- Power-cycle the cluster with OpenWRT up: public DNS must still resolve.
- Bring up cluster with Technitium delayed: control-plane access must work via OpenWRT overrides.
- Kill Technitium: public DNS works; internal names fail as expected.
- Kill ExternalDNS: existing internal names still resolve.
- WAN test: internal-only names do not resolve from cellular; LAN/VPN resolve to internal VIPs.
Implementation Notes
- Keep OpenWRT as the client-facing resolver in Phase 1; migrate clients later only after resolver redundancy exists.
- Favor IP-based configuration for anything that talks to DNS to avoid “DNS requires DNS” loops.
- Use stable VIPs where possible so OpenWRT, Technitium, and ExternalDNS share a consistent target.