# DNS — split-horizon `*.hubris.network` LAN clients resolve `*.hubris.network` to the [Caddy reverse proxy](../containers/121-caddy.md) (`192.168.8.175`). Public clients resolve to the IONOS VPS (`82.165.190.79`) via an IONOS wildcard, where they hit the [VPS traefik public ingress](ingress.md). There is **no wildcard on the LAN side**. Every subdomain needs an explicit entry. ## Components - **Authoritative public DNS:** IONOS. `*.hubris.network → 82.165.190.79` (was `74.118.126.4` until 2026-04-22). - **LAN authoritative for `hubris.network` records:** dnsmasq on [authentik (124)](../containers/124-authentik.md), `192.168.8.180:53` and `127.0.0.1:53`. Config at `/etc/dnsmasq.d/hubris-split.conf`. Forwards everything else to `1.1.1.1` and `8.8.8.8` (`no-resolv`, `server=...`). - **PVE host** (`192.168.8.77`): resolver is the local Netbird daemon at `100.122.38.109:53`, which forwards to the LAN/upstream and learns hubris.network answers via that path. `netbird status` says "Nameservers: 0/0 Available" — confirming netbird does NOT manage a hubris.network zone; it just caches whatever the system resolver returns. - **Some LXCs** keep router DNS (`192.168.8.1`) or Tailscale MagicDNS (`100.100.100.100`), both of which return the public IONOS A record. Those LXCs need either a `/etc/hosts` override or local dnsmasq — see [mesh migration](mesh.md) for which technique applies where. ## Live entries (as of 2026-04-28) ``` address=/auth.hubris.network/192.168.8.175 address=/git.hubris.network/192.168.8.175 address=/media.hubris.network/192.168.8.175 address=/paperless.hubris.network/192.168.8.175 address=/books.hubris.network/192.168.8.175 address=/home.hubris.network/192.168.8.175 address=/cloud.hubris.network/192.168.8.175 address=/matrix.hubris.network/192.168.8.175 address=/proxmox.hubris.network/192.168.8.175 address=/docker.hubris.network/192.168.8.175 address=/jellyseerr.hubris.network/192.168.8.175 address=/qbit.hubris.network/192.168.8.175 address=/sab.hubris.network/192.168.8.175 address=/blog.hubris.network/192.168.8.175 address=/photos.hubris.network/192.168.8.175 address=/artifacto.hubris.network/192.168.8.175 address=/plato.hubris.network/192.168.8.175 address=/zimaos.hubris.network/192.168.8.175 address=/nfs-export.hubris.network/192.168.8.200 ``` Note: `nfs-export.hubris.network` is the only `.hubris.network` entry that points to a non-HTTP service (NFSv4 on port 2049). It bypasses [caddy (121)](../containers/121-caddy.md) because NFS is L4, not HTTP — Caddy has nothing to do. ## Why split-horizon The IONOS wildcard points at the VPS for public ingress (per-host routers in [VPS traefik](ingress.md)). The VPS only routes hostnames it knows — anything else 404s. So LAN clients pointing at the public IP are a dead end for any service that isn't explicitly published. The dnsmasq override on LXC 124 keeps LAN traffic on the home Caddy. ## The gotcha that cost a debug session (2026-04-22) Creating a new Caddyfile site block is necessary but **not sufficient**. Without the LXC-124 dnsmasq entry, LAN queries fall through to upstream, get the public IONOS answer, and time out. Symptom: "subdomain doesn't load" even though Caddy config + cert are fine. ## Recipe — adding a new subdomain 1. Edit `/etc/caddy/Caddyfile` on [caddy (121)](../containers/121-caddy.md), commit + push to `dtoro/caddy-conf`. Webhook reloads caddy. See [auto-deploy](auto-deploy.md). 2. Append to `/etc/dnsmasq.d/hubris-split.conf` on [authentik (124)](../containers/124-authentik.md): ``` address=/.hubris.network/192.168.8.175 ``` 3. `pct exec 124 -- systemctl restart dnsmasq` — reload/SIGHUP may not pick up the new `address=` line; hard restart is the reliable path. 4. Verify: `dig @192.168.8.180 +short .hubris.network` → `192.168.8.175`. 5. On macOS clients, flush: `sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder`. > The dnsmasq config is **not** tracked in git. If you stand up a `dtoro/dnsmasq-conf` repo, wire it like `caddy-conf` (webhook on LXC 124). ## Public path — what does and doesn't follow the LAN map - Hostnames published in [VPS traefik dynamic config](ingress.md) (currently `artifacto.hubris.network`, `blog.hubris.network`) reach a real backend over the netbird mesh. - Anything else with a `*.hubris.network` URL hits the VPS but isn't routed anywhere — returns 404. - `netbird.hubris.network` is its own thing — TCP passthrough at the VPS, served by netbird-proxy. Doesn't follow the file-provider router pattern. ## Long-term plan Either: - Move split-horizon DNS to the LAN router so `*.hubris.network → 192.168.8.175` is answered for every LAN client. Eliminates per-LXC overrides. - Or, once the [Tailscale → Netbird migration](mesh.md) completes, every LXC's resolver becomes the netbird daemon, which already learns hubris.network answers via the system resolver chain. ## Related - [Caddy (121)](../containers/121-caddy.md) — every LAN entry points here - [Ingress (VPS traefik)](ingress.md) — public-side counterpart - [Mesh migration](mesh.md) — per-LXC DNS workarounds during the transition - [Authentik (124)](../containers/124-authentik.md) — host of the split-horizon dnsmasq ## Changelog ### 2026-05-14 — `nfs-export.hubris.network` added (direct, non-HTTP) NFSv4 export server [nfs-export (102)](../containers/102-nfs-export.md) at `192.168.8.200`. Direct entry, not Caddy-fronted — NFS is L4, no HTTP reverse-proxy meaningful. ### 2026-05-14 — `zimaos.hubris.network` added (Caddy-fronted, standard pattern) New LAN entry for [100-zimaos](../vms/100-zimaos.md) → [caddy (121)](../containers/121-caddy.md) → `192.168.8.195`. Briefly pointed direct-to-VM during install for the initial smoke-test, then re-pointed once a Caddyfile block was added (`reverse_proxy 192.168.8.195` + IONOS DNS-01 TLS). ### 2026-05-13 — `plato.hubris.network` added; `files.hubris.network` removed New LAN-only entry for [plato (126)](../containers/126-plato.md). Same day, the `files.hubris.network` entry for the just-decommissioned seafile experiment was dropped; queries now fall through to the public IONOS answer (no LAN backend). ### 2026-05-12 — `files.hubris.network` added (since removed 2026-05-13) Originally added for the seafile (LXC 125) Nextcloud-replacement evaluation. Pointed at 192.168.8.175 (Caddy reverse-proxied to 192.168.8.185:80). Entry removed when the experiment was torn down a day later. ### 2026-04-28 — wiki entry created Initial documentation. 16 active entries. ### 2026-04-22 — IONOS wildcard moved 74.118.126.4 → 82.165.190.79 Public path now lands on the VPS traefik, not the old yunohost. Necessary for the [public ingress](ingress.md) pattern. The LAN dead-end semantics didn't change — public DNS still doesn't help LAN clients reach LAN-only services. ### 2026-04-22 — three caddy sites without DNS entries (jellyseerr, qbit, sab) Caddy + certs were working but LAN resolution failed because the dnsmasq lines weren't added. Lesson recorded; entries added later that day. ### 2026-04-21 — dnsmasq stood up on LXC 124 Co-located with Authentik. Initial entries cover everything routed through Caddy.