1. Prerequisites
- A clean Debian 12 (bookworm) or
Debian 13 (trixie) machine: VPS, Pi 4/5
with SSD, or a Proxmox LXC. nomina + BIND are light —
512 MB RAM is enough for a small homelab; 2 GB if you
load big RPZ feeds.
- Public IPv4 (and ideally IPv6) reachable
on 53/udp and 53/tcp.
The whole point of authoritative DNS is being reachable
from any resolver on the internet.
- A domain you actually control — i.e.
you can change its NS records at the registrar to point
at the box you're installing on. Without that, nothing
you serve from nomina will be visible to the world.
One nameserver vs two: the DNS spec wants at
least two NS records per zone. For a single-server homelab
you can register both as the same IP (works, slightly
fragile) — or pair nomina with a free secondary like
BuddyNS /
Hurricane Electric
via the slave-zone feature (covered below).
2. Install nomina
curl -fsSL https://apt.netforge.it/free/key.gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/netforge.gpg
echo "deb [signed-by=/usr/share/keyrings/netforge.gpg] https://apt.netforge.it/free stable main" \
| sudo tee /etc/apt/sources.list.d/netforge.list
sudo apt update
sudo apt install nomina
sudo nomina admin create yourname
sudo systemctl start nomina
The install pulls in BIND9 and dnsutils. The postinst lays
out /srv/nomina/ (zones, RPZ feeds, DNSSEC keys,
backups, admins.json), generates a 256-bit session secret,
and wires /etc/bind/named.conf to include
/srv/nomina/named.conf.local — so you never edit
BIND's config by hand.
3. First login
nomina binds to 127.0.0.1:8053 — the panel is
private. SSH-tunnel to reach it the first time:
ssh -L 8053:127.0.0.1:8053 root@your-server
# then open http://127.0.0.1:8053/ in your browser
Log in, enrol 2FA on /account. The panel itself
is read-mostly until you add a zone — the first run is
intentionally empty.
4. First master zone
Go to /zones, click + New zone.
Pick:
- Name:
example.com (no
trailing dot)
- Type: master — you're
the authority for this zone
- SOA email:
hostmaster@example.com
(RFC convention; people might mail you here when there's
a DNS issue)
- Primary NS:
ns1.example.com.
(with the trailing dot — it's an FQDN). This is the name
clients see in the SOA record.
On save, nomina writes
/srv/nomina/zones/example.com.db with a fresh
SOA + a single NS record at the apex, registers the zone
with BIND via named.conf.local, and runs
named-checkconf + rndc reconfig.
At the registrar: change
example.com's NS to point at the IP of this
box (and any secondaries you've set up). Allow up to 48 h
for the parent zone TTL to expire and the world to see your
new authority.
5. Add records
On the zone page, click + Add record. Each
record has four fields:
| Name | TTL | Type | Value |
@ | 3600 | A | 198.51.100.10 |
www | 3600 | CNAME | example.com. |
@ | 3600 | MX | 10 mail.example.com. |
@ | 3600 | TXT | "v=spf1 mx -all" |
missus._domainkey | 3600 | TXT | "v=DKIM1; k=rsa; p=…" |
Use @ for the apex (the zone name itself).
Trailing dots matter on values that are hostnames — without
them BIND appends the zone name. nomina runs
named-checkzone after every save and rolls back
automatically if the result doesn't parse, so you can't
break a live zone with a typo.
From the CLI:
nomina zones record add example.com www A 198.51.100.10.
Same validation, same auto-rollback, same SOA serial bump.
6. DNSSEC
On the zone page, click DNSSEC → Enable.
nomina turns on KASP (BIND's modern key/signing manager) for
the zone — BIND generates the KSK + ZSK, signs the zone,
and rotates the ZSK quarterly without your involvement.
The DNSSEC tab shows the DS records you
need to paste at your registrar to complete the chain of
trust. They look like:
example.com. IN DS 12345 13 2 ABCD1234EF…
Add them at the registrar, give them an hour or two, then
verify on
dnsviz.net
or
DNSSEC Analyzer. Once green, your zone is DNSSEC-signed
end-to-end.
DNSSEC keys are critical operator state.
They live under /srv/nomina/dnssec/<zone>/
with mode 0700, owned by root. They're included in
nomina backup. Lose them and you cannot resign
your zone — you'd have to disable DNSSEC at the registrar
(DS record removal) and start over with new keys.
7. RPZ blocklists
RPZ (Response Policy Zones) lets BIND lie to clients about
specific names — return NXDOMAIN for known-bad domains
regardless of what their real authoritative servers say. If
you also use this BIND as a recursive resolver for a LAN /
home network, RPZ becomes a Pi-hole-style ad/threat blocker
built into your DNS server.
On /rpz, enable the curated feeds you want.
nomina ships:
- URLhaus (abuse.ch) — active malware C2
+ phishing
- Hagezi threat / pro tiers — broader
ads, trackers, malware
- OISD big — community-curated ads /
trackers / malware
- NetForge mining — cryptominer pools
Each feed shows estimated RAM impact so you don't load 5 GB
of feed onto a Pi 4. Whitelist and
custom block tabs let you override feed
decisions per name.
The nomina-rpz-update systemd timer refreshes
enabled feeds every 12 h (each feed has its own refresh
policy in the catalog). Feeds are written to
/srv/nomina/rpz/<feed>.zone, then BIND
gets rndc reload'd.
8. Slave & forward zones
Slave zones replicate a master that lives
elsewhere. Use them for: pairing nomina with a free
secondary (BuddyNS, HE), running a backup server, or
shadowing an upstream's zone. Add the master's IP and
(optional) TSIG key; nomina configures BIND to do AXFR/IXFR
on a NOTIFY trigger.
Forward zones don't store data — they
delegate resolution of a sub-tree to specific upstream
resolvers. Useful for split-horizon (your internal
example.lan resolves to LAN IPs via a private
resolver, the rest of the world to public IPs).
9. Propagation check
On /propagation, type a name and click
Check. nomina queries the name in parallel
across:
- Cloudflare 1.1.1.1, 1.0.0.1, 1.1.1.2 (security)
- Quad9 9.9.9.9, 149.112.112.112
- Google 8.8.8.8, 8.8.4.4
- AdGuard 94.140.14.14
- Your system resolver
You can also paste an arbitrary resolver IP. The result
table shows answer, TTL, and a green/yellow/red indicator
if the resolver disagrees with your authoritative answer —
useful for spotting cache-poisoning or registrar lag during
a migration.
10. Backups & migration
Everything nomina manages lives under /srv/nomina/
as plain files (no SQLite). Backup is rsync.
sudo rsync -aHAX --delete /srv/nomina/ backup-host:/srv/nomina-snapshot/
# new box, after `apt install nomina`
sudo rsync -aHAX backup-host:/srv/nomina-snapshot/ /srv/nomina/
sudo nomina rehydrate
nomina rehydrate regenerates
named.conf.local + response-policy.conf
from the zone files on disk and runs
rndc reconfig.
For granular restore the /backup page
bundles a tarball with full manifest. Restore can target one
zone, one RPZ feed, or the whole tree.
11. Troubleshooting
First stop:
sudo nomina check
Walks filesystem, BIND install, named-checkconf,
admins.json, and reports each step ✓ / ! / ✗.
Daemon logs:
sudo journalctl -u named -n 100 --no-pager
sudo journalctl -u nomina -n 100 --no-pager
Quick "is the zone served?" probes:
# Local BIND
dig @127.0.0.1 example.com SOA
dig @127.0.0.1 example.com DNSKEY +dnssec
# Public resolution
dig @1.1.1.1 example.com SOA
dig @8.8.8.8 example.com DNSKEY +dnssec
If you ever need to nuke nomina and rebuild:
apt purge nomina intentionally does not
delete /srv/nomina/. Zone files and DNSSEC
private keys are critical operator state — even cascade
purges from unrelated package removals leave them alone. To
actually wipe, remove the directories by hand —
sudo rm -rf /srv/nomina /etc/nomina — that's an
explicit, deliberate action you have to take.