Modern DNS sinkhole · Pi-hole alternative

Minos — DNS server

Every query gets judged. A single static Go binary with an embedded web UI, light enough for a Raspberry Pi. Every DNS query is judged against your blocklists and sentenced — allowed queries are forwarded upstream over encrypted DoH or DoT. No telemetry, ever.

License Go Docker Raspberry Pi

What is Minos

Minos is a modern, user-friendly DNS sinkhole — a Pi-hole alternative — written in Go. It ships as a single static binary with an embedded web UI, light enough to run on a Raspberry Pi Zero through a Pi 4. Named for the judge of the underworld, every DNS query that arrives is judged against your blocklists and sentenced — no exceptions, no appeals (well, except pardons).

Blocked queries are answered with 0.0.0.0/:: or NXDOMAIN (your choice); allowed queries are forwarded upstream over encrypted DoH or DoT (plaintext optional). Everything is managed live from the web dashboard — no restarts — and nothing is ever sent home. No telemetry, ever.

Open-source: Minos is released under the GPLv3 licence. The full source, issue tracker, and releases live at github.com/DanDreadless/minos.

What It Does

Filtering

  • Listens for DNS queries on :53 (UDP + TCP) and judges each one against compiled blocklists (hosts, plain, and AdBlock formats).
  • Blocked queries get 0.0.0.0/:: or NXDOMAIN (your choice); allowed queries are forwarded upstream over DoH or DoT.
  • Every blocked query shows which list and rule condemned it, with a one-click pardon from the live log — never more than two clicks from seeing a block to allowing it.
  • Repeat queries are answered from a built-in response cache — concurrent identical queries collapse into one, and stale answers are served instantly while a fresh one is fetched behind them (RFC 8767).
  • A failing upstream is sidestepped automatically and re-probed until it recovers — one dead resolver never slows the whole network.

For the household

  • Device tracking (IP, MAC, hostname) with per-device groups: extra rules, full bypass, or no DNS at all — plus a one-click block for any device.
  • One-click blocked services (TikTok, YouTube, Discord…) — globally or per group, with optional schedules ("no social media after 21:00").
  • Safe Search enforcement (Google, Bing, DuckDuckGo, YouTube) — network-wide or per group, enforced by the provider so it can't be switched off.

For the network

  • Local DNS records for your LAN (nas.home.lab, wildcards, CNAMEs, PTR).
  • Conditional forwarding: route lan or your reverse zone to the router.
  • Private reverse zones answered locally (RFC 6303) — 192.168.x.x lookups never leak to public resolvers.
  • Serves encrypted DNS to clients: DoT for Android Private DNS, DoH at /dns-query — bring a certificate, or let Minos fetch and renew one automatically.

Running it

  • Web dashboard with query charts, top blocked domains, busiest clients, cache hit rate, and a live query log streamed over WebSocket.
  • Full management from the UI: blocklists, allow/deny domains, upstreams, blocking mode, retention, API token — all applied live, no restarts.
  • Prometheus /metrics with a ready-made Grafana dashboard — scrape-only, never pushes.
  • A fully documented REST API with Home Assistant recipes — everything the UI does, your automations can do.
  • Webhook / ntfy notifications: a new device on your network, an upstream failing or recovering, a new release.
  • Opt-in update check — off by default, and nothing is sent beyond the request itself.
  • Batched SQLite persistence that respects SD cards. No telemetry. Ever.

Quick Start

Minos runs on a Raspberry Pi or any Linux box — amd64, arm64, or 32-bit ARM (Pi Zero through Pi 4 on 32-bit Pi OS). Pick the install method that suits you: the one-line install script, Docker, or a build from source.

Install script (recommended)

One line installs the latest release and the systemd unit:

curl -fsSL https://raw.githubusercontent.com/DanDreadless/minos/main/deploy/install.sh | sudo sh
sudo systemctl enable --now minos

Docker

Multi-arch images are published on GHCR:

docker run -d --name minos -p 53:53/udp -p 53:53/tcp -p 8080:8080 \
  -v minos-data:/data ghcr.io/dandreadless/minos:latest
Tip: deploy/ in the repo also has a multi-arch Dockerfile and a Compose example — restart: unless-stopped gives the same boot behaviour as the systemd unit.

Build from source

Requires Go 1.22+ and Node 20+:

make build          # builds web UI + single binary into bin/minos
./bin/minos serve   # starts DNS on :53 and the web UI on :8080

First Run

First run writes a commented default config to minos.yaml. Point a device's DNS at the machine running Minos and open http://<host>:8080.

Local development without root: set dns.listen: ":5353" in the config and test with dig @127.0.0.1 -p 5353 doubleclick.net.

CLI Verbs

The CLI talks to the running instance:

minos status        # counters, rules, pause state
minos pause 5m      # pause blocking for five minutes
minos resume        # resume blocking
minos import pihole /etc/pihole   # bring your Pi-hole settings with you

Deploying on a Raspberry Pi (or any Linux box)

The install script puts the binary in /usr/local/bin and installs the hardened systemd unit. Built from source instead?

sudo install -m 755 bin/minos /usr/local/bin/minos
sudo cp deploy/minos.service /etc/systemd/system/
1
Free port 53

Disable the systemd-resolved stub listener (or dnsmasq) so Minos can bind :53.

2
Give the machine a fixed IP

Clients will point at this address, so it must not change.

3
Firewall ports 53 / 8080 to your LAN only

Never expose an open resolver or the admin UI to the public internet.

4
Point your router's DHCP DNS at the machine

Set the DHCP DNS option to the Minos host and every device on the network follows automatically.

The step-by-step walkthrough — including host-tuning notes for busy networks — is in docs/getting-started.md.

Encrypted DNS

Minos forwards upstream over DoH or DoT (plaintext optional) and can also serve encrypted DNS to your clients: DoT for Android Private DNS, and DoH at /dns-query. Bring your own certificate, or let Minos fetch and renew one automatically via ACME — Let's Encrypt through Cloudflare, deSEC, DuckDNS, or RFC 2136.

Family Controls

  • Device tracking & groups — every device (IP, MAC, hostname) can be placed in a group with extra rules, full bypass, or no DNS at all, plus a one-click block for any device.
  • Blocked services — one click blocks TikTok, YouTube, Discord and more, globally or per group, with optional schedules such as "no social media after 21:00".
  • Safe Search enforcement — Google, Bing, DuckDuckGo and YouTube, network-wide or per group, enforced by the provider so it can't be switched off on the device.

Network Features

  • Local DNS records for your LAN — nas.home.lab, wildcards, CNAMEs, and PTR records.
  • Conditional forwarding — route lan or your reverse zone to the router.
  • Private reverse zones answered locally (RFC 6303) — 192.168.x.x lookups never leak to public resolvers.

Dashboard, Metrics & API

  • Dashboard — query charts, top blocked domains, busiest clients, cache hit rate, and a live query log streamed over WebSocket.
  • Live management — blocklists, allow/deny domains, upstreams, blocking mode, retention, and API token are all applied live, with no restarts.
  • Prometheus — a scrape-only /metrics endpoint with a ready-made Grafana dashboard.
  • REST API — a fully documented API with Home Assistant recipes; everything the UI does, your automations can do.
  • Notifications — webhook / ntfy alerts for a new device, an upstream failing or recovering, or a new release.

Migrating In

Already running Pi-hole or AdGuard Home? Bring your settings across in one command:

minos import pihole /etc/pihole

…or upload gravity.db / AdGuardHome.yaml in the UI. You can export and restore the whole Minos config as YAML at any time.

Documentation

  • Getting started — install, host prep, systemd, encrypted DNS, monitoring, and the full config reference.
  • REST API reference — every endpoint, with examples.
  • Home Assistant recipes — blocking switch, sensors, bedtime automations, events on your phone.
  • Roadmap — what shipped, what's under consideration.

Roadmap

Everything from the July 2026 competitive review has shipped — the resolver core (cache, dedup, serve-stale, failover health, private reverse zones), family controls, the Pi-hole/AdGuard importer with a UI uploader, client-facing DoT/DoH with automatic ACME certificates, metrics, notifications, an opt-in update check, and the release pipeline. The only item still under consideration is DNSSEC validation; details are in docs/roadmap.md.

Developing

Go 1.22+, Node 20+.

make test    # runs the Go suite with the race detector
make lint    # runs golangci-lint and the frontend type check
make bench   # runs the filter engine benchmarks

See CLAUDE.md in the repo for architecture, conventions, and performance budgets.

License

Minos is released under the GPLv3 licence. See the repository for the full text.