Files
ulicraft-server-v1/plan/13-dns-and-run-modes.md
2026-05-24 06:06:33 +02:00

66 lines
2.9 KiB
Markdown

# DNS strategy + run modes
How names resolve and which layers come up. Supersedes the "dnsmasq is core"
assumption in `01-dnsmasq.md`.
## Domain: `.lan`, not `.local`
`BASE_DOMAIN=ulicraft.lan` by default. `.local` is intercepted by mDNS on
macOS/Linux and does **not** resolve through a normal unicast DNS server
(that was the `DNS_PROBE_FINISHED_NXDOMAIN`). Use `.local` only with the mDNS
path below.
## Run modes — `tooling/build-stack.sh --up <mode>`
| Mode | Compose layers | Use |
|---|---|---|
| `online` | base + static | internet present; landing + launcher; no mirror |
| `airgap` | base + static + mirror | no internet; full asset mirror on `:443` (default) |
| `core` | base | debugging |
Base = drasl, minecraft, mc-backup, caddy(auth+packwiz). `static` = apex landing +
launcher + `/ca.crt`. `mirror` = upstream spoof vhosts (`tls internal`) + `:443` +
caddy aliases. `--up` prints the DNS records for the chosen mode.
## DNS: your own party server (primary)
You run the party DNS. Generate records with `tooling/dns-records.sh <mode>`:
- `online` → service names (`${BASE_DOMAIN}`, `auth.`, `packwiz.`, `mc.`) → `HOST_LAN_IP`
- `airgap` → the above **plus** the spoofed upstreams (`meta.prismlauncher.org`,
`piston-meta`/`piston-data.mojang.com`, `libraries.minecraft.net`,
`maven.neoforged.net`, `resources.download.minecraft.net`) → `HOST_LAN_IP`
Output formats: plain, `/etc/hosts`, BIND zone, dnsmasq `address=`, plus the
Minecraft SRV line. Minecraft needs no port (`mc.${BASE_DOMAIN}` defaults to 25565).
## Optional resolver layers
- **dnsmasq** (`docker-compose.dnsmasq.yml`) — turnkey DNS if you don't run your
own. Binds `${HOST_LAN_IP}:53`. Serves the rendered `dnsmasq/dnsmasq.conf`
(wildcard + airgap spoofs).
- **mDNS / Avahi** (`docker-compose.avahi.yml`, `ENABLE_MDNS=true`) — zero-config
`.local` for guests (macOS/Linux native; Windows needs Bonjour). See below.
## mDNS path (ENABLE_MDNS=true + BASE_DOMAIN=*.local)
The `avahi` container publishes the service names to the **host's** avahi-daemon
over its D-Bus socket (it does NOT run its own daemon — that collides with the
host on `:5353`).
Requirements / gotchas (build-stack warns on these):
- host runs `avahi-daemon`; `/run/dbus/system_bus_socket` mounted in.
- `security_opt: apparmor=unconfined` on the container (docker-default AppArmor
blocks the D-Bus publish).
- multi-interface hosts (e.g. many docker bridges) → avahi self-collides
("Local name collision"); set `allow-interfaces=<lan-nic>` in
`/etc/avahi/avahi-daemon.conf`.
- mDNS resolves **only** `.local`, so it cannot serve the air-gap upstream
spoofs (real public hostnames) — those always need real DNS.
## Status (tested 2026-05-24)
- `.lan` + own-DNS path: verified end-to-end (apex/auth/packwiz/ca.crt/mirror
all 200, minecraft healthy).
- mDNS publish mechanism: verified reaching host avahi; full green-light blocked
on this dev box only by its 38 docker bridges (allow-interfaces fixes it).