# 09 — DNS & Ingress Serves: **R-DNS-01/02/03**, **R-C2-01**, works with **R-TLS-***. Related: [ADR-0002 (Cilium/Gateway API)](../decisions/adr-0002-cni-cilium.md). ## Naming model - All services live at `.home.keithjackson.dev` (e.g. `plex.home.keithjackson.dev`). - The **root** `home.keithjackson.dev` serves the **Command & Control UI** ([12](12-command-center-ui.md)). - Public apex `*.keithjackson.dev` resolves to the network's public IP; `*.home.keithjackson.dev` is the platform's zone. ## DNS automation (R-DNS-02) - **ExternalDNS** watches Gateway/HTTPRoute (and Service) resources and manages records in the authoritative DNS provider (Cloudflare, per OQ-4) automatically — a new service's DNS appears from its declared intent, no manual record editing. - Records for `*.home.keithjackson.dev` are created/updated/removed as services come and go. ## Split-horizon resolution (R-DNS-03) Internal and external answers differ: - **External** (`*.home.keithjackson.dev` from the internet): resolves to the public IP; reaches the edge router, which forwards `public`-class services to the in-cluster Gateway. - **Internal** (LAN clients): resolves `.home.keithjackson.dev` to the **internal Gateway address** directly, avoiding hairpinning through the public IP. - **PiHole** (itself an onboarded service) provides internal LAN DNS and the split-horizon answers for `.home.keithjackson.dev`; the trusted Let's Encrypt cert is served either way ([08](08-tls-and-certificates.md)). > DNS is thus both a platform capability *and* a hosted service. Bootstrapping order matters: the > platform needs working DNS before PiHole is fully managed — handled by the bring-up sequence in > [`roadmap/phases.md`](../roadmap/phases.md). ## Ingress (north-south) via Gateway API - **Gateway API implemented by Cilium** is the ingress layer (no separate ingress controller; reuses the CNI, [ADR-0002](../decisions/adr-0002-cni-cilium.md)). - A shared **Gateway** defines HTTPS listeners on `*.home.keithjackson.dev` terminating TLS with the cert-manager cert ([08](08-tls-and-certificates.md)). - Each service contributes an **HTTPRoute** mapping its hostname to its Service — rendered from the ServiceDefinition, not hand-authored. - **Exposure class** is declared per service: - `internal` — reachable only on the LAN (no edge port-forward; internal DNS only). - `public` — additionally reachable from the internet via the edge router forwarding 80/443 to the Gateway. ## Edge integration - The edge router/firewall forwards inbound 80/443 for `public` services to the Gateway's address and applies multi-WAN inbound rules as needed (OQ-1). - `internal` services are never port-forwarded; they rely on internal DNS + Gateway on the LAN. - A stable ingress VIP for the Gateway is provided by the cluster's LB strategy (Cilium L2 announcement / BGP / a chosen LB); pin the mechanism in the networking bring-up. ## Interaction with default-deny Ingress opens **north-south** paths to the specific service; it does **not** relax **east-west** default-deny ([03](03-networking-isolation-and-egress.md)). A service being publicly reachable does not let other in-cluster services reach it unless an explicit allow rule exists. ## Acceptance gates - A new service's `.home.keithjackson.dev` record appears automatically and routes to it. - `internal` services are unreachable from the public internet; `public` services are reachable and TLS-valid. - Internal clients resolve to the internal Gateway (no public hairpin) and get a trusted cert. - The root `home.keithjackson.dev` serves the C2 UI. ## Open questions - **OQ-1/OQ-4** — edge router product + DNS provider API (affects ExternalDNS provider config and inbound WAN rules). - Gateway LB/VIP mechanism (Cilium L2 vs BGP) — pin during networking bring-up.