Lantern
Lantern is a self-hosted DNS and DHCP server for home networks: a single stateless Go binary combining dynamic host configuration, a recursive DNS resolver with caching and DoH upstream fallback, hosts-format ad blocking, and passive p0f-style device fingerprinting. Inspired by Pi-hole, it targets minimal hardware — a Raspberry Pi, NUC, or VM.
It started as a Claude Cowork prototype called homedns, built around one requirement: tell it your subnet and every address it leases gets valid forward and reverse DNS, with the lease table as the single source of truth for both. That prototype settled the architecture — Go 1.22, miekg/dns and insomniacslk/dhcp, CGo-free SQLite, JSON config with validation and hot reload — before the work moved into this repository under its current name. On top of it sit a Pi-hole-style web dashboard driven by server-sent events, a full REST API, latency percentiles via hdrhistogram, hot config reload on SIGHUP, and drop-in systemd/launchd/Docker deployment. Development was heavily Claude Code-assisted: the commit history shows AI-paired work on the GitHub Actions CI pipeline, Docker-based DNS/DHCP integration tests, a release workflow with cross-platform binaries, and a test-coverage push from 29.5% to 47.5%.
Features landed to date include blocklist subscriptions with pause/resume, a two-tier cache, UniFi config import, a DNS-only deployment mode, and lease detail pages that pull together the lease itself, the device fingerprint, a paginated DHCP/DNS event history, per-host query stats, and a button that releases a dynamic lease outright. The live-data pages have taken most of the recent attention. The DNS query log now actually renders its event stream — the SSE handler had been logging to the browser console and never touching the DOM — as a capped, auto-scrolling table badged by where each answer came from: blocked, local, cached, or upstream. Chart.js moved out of the base layout onto the two pages that need it, after its CDN fetch turned out to be blocking every page render. And DHCP option 61 client IDs are hex-encoded rather than cast to a string, because the option carries a hardware-type byte plus a MAC in binary and printing it as text produced unreadable garbage.
Testing happens on a deliberately isolated segment: Lantern binds to a USB ethernet adapter, NAT scripts give test clients a route out, and a development runner pulls, rebuilds, and brings the interface up on every launch so there is never a stale binary on the bench. Going live is scripted as a reversible cutover rather than a migration — one script starts the service and prints the single gateway setting to change, its counterpart stops it and prints the revert — because the household's DNS and DHCP are still held by a UniFi gateway with Pi-hole resolving in front of it, and taking over name resolution for a working home is a change worth being able to undo in one command. Shipped as tagged releases with pre-built Linux and macOS binaries.
Lantern provides a single self-hosted service that hands out IP addresses and resolves domain names for a home network, while also caching lookups, blocking ads via host lists and identifying devices passively. It was created to replace the existing router-based DNS/DHCP setup with something lightweight that can run on modest hardware and be switched on or off in one step.