2.5 KiB
dnsmasq — LAN wildcard DNS
Summary
Provides name resolution for guest laptops so *.ulicraft.local resolves to the
Docker host. Replaces the homelab's AdGuard (dropped for the LAN party). Image:
jpillora/dnsmasq (dnsmasq wrapped in webproc, optional web UI on :8080).
Config is a file, not env-driven — /etc/dnsmasq.conf, standard dnsmasq
format. Rendered from a template by tooling/render-config.sh.
Only guest laptops point their DNS here. Stack-internal resolution is handled by
Docker network aliases on Caddy (see 02-caddy.md), so dnsmasq is not on the
critical path for the server's own services.
Config template
dnsmasq/dnsmasq.conf.tmpl:
# wildcard: every *.ulicraft.local → host LAN IP
address=/${BASE_DOMAIN}/${HOST_LAN_IP}
# upstream optional; party is offline so may be omitted
no-resolv
Air-gap spoof records (see 11)
For full client air-gap, this file also spoofs the real upstream hosts → our
Caddy mirror (piston-meta/piston-data/libraries.minecraft.net/
maven.neoforged.net/resources.download.minecraft.net/meta.prismlauncher.org).
Full list + rationale in 11-full-airgap-mirror.md. Keep in sync with the
capture step. Auth hosts (session/textures/api.mojang) are NOT spoofed — drasl
handles those via authlib-injector.
Gotcha — port 53 conflict
Linux Docker hosts usually run systemd-resolved bound to :53. Publishing
53:53 will fail with address already in use. Resolve by one of:
- Bind dnsmasq only to the LAN IP: publish
${HOST_LAN_IP}:53:53/udp(+tcp) - Or disable resolved's stub listener (
DNSStubListener=no) and restart resolved
Gotcha — .local / mDNS
See overview. Avahi may shortcut *.local to multicast before hitting dnsmasq.
Test on a macOS client early; if broken, switch BASE_DOMAIN to .lan.
Tasks
- Add
dnsmasqservice todocker-compose.yml(jpillora/dnsmasq) - Create
dnsmasq/dnsmasq.conf.tmplwith wildcardaddress=line - Wire
render-config.shto emitdnsmasq/dnsmasq.conf(gitignored) - Decide port-53 strategy (bind to
HOST_LAN_IPvs disable resolved stub) - Publish
53/udp+53/tcp; mount rendered conf read-only - Optionally expose webproc UI (8080) behind Caddy as
dns.ulicraft.local - Document guest DNS setting (set DNS server =
HOST_LAN_IP) - Verify
*.localresolves on Windows + macOS + Linux guests (mDNS check) - Add air-gap spoof
address=records (see 11) once capture confirms the host list