This is the education page for how a laptop finds a nameserver. How to mint credentials and wire adapters (keytab, TSIG, PowerDNS API): integrations. Zone modes and the lattice-dns binary: dns. Adapters: bind-ddns, ad-ddns, powerdns. Admin path: manuals/admin.
Lattice does two DNS jobs and never mixes them in one process:
- Update names after a lease — the worker writes A/PTR (and deletes them) via an adapter. dhcpd does not talk DNS on Ack.
- Answer for zones Lattice owns —
lattice-dnsis an authoritative server for those zones only. Recursion is off.
Most sites only need (1). (2) is optional. Neither job makes Lattice the resolver the laptop uses for google.com or for the AD forest.
1. The laptop is a stub
A Windows / macOS / Linux DHCP client is a stub resolver. After Ack it has a list of DNS server IPs from DHCP option 6. Every lookup — printer-01.office.example.com, dc01.ad.example.com, google.com — is sent to that list.
The stub does not:
- Walk NS records from the root
- Read the NS you set on a Lattice zone
- Discover
lattice-dnsby itself - Fail over to AD because Lattice REFUSED
google.com
NS records tell other nameservers where a zone lives. They do not tell a workstation “use this as my DNS server.” Option 6 does that (or a static NIC config).
Lattice does not fill option 6 when you enable DDNS or embedded. You set it as a subnet DHCP option (code 6, payload {"addresses":["10.0.0.1","10.0.0.2"]}), or the machine is configured by hand. Mask, router, and lease-time are built-in from the subnet row. DNS servers are not.
DHCP option 15 (domain name) and search lists only change which suffix the stub appends. They do not choose the server.
laptop (stub)
|
| every name
v
whatever option 6 said
(AD, Unbound, BIND, or — rarely — lattice-dns)
2. The recursive resolver is someone else
Unbound, BIND as a cache, or AD DNS (many forests use the DCs as both authoritative and recursive) is a recursive resolver. It:
- Accepts the stub’s query
- Follows NS / forwards stub zones / uses slave zones
- Caches
- Talks to
lattice-dnsor a DC on the client’s behalf
That is why the production-shaped picture is:
laptop --option 6--> Unbound or AD or BIND
|
+--> lattice-dns only for office.example.com
+--> DCs ad.example.com, _msdcs
+--> the internet everything else
lattice-dns is the box in the middle of one zone, not the box the laptop points at.
3. Pick one mode per zone
Do not set embedded and bind_tsig / ad_gsstsig / powerdns_http on the same zone. Split brain: two writers, two answers.
| Mode | What the laptop asks (option 6) | Who talks to lattice-dns | How names get into DNS |
|---|---|---|---|
| Keep AD / BIND / PowerDNS | Unchanged (DCs or existing BIND) | Nobody on the query path | Worker RFC 2136 / HTTP after Ack |
| Hidden primary | BIND (or Unbound in front of BIND) | BIND secondaries, AXFR from Lattice | embedded bumps serial; secondaries transfer |
| Published lattice-dns | lattice-dns VIP — only if that zone is all they will query | The laptop itself | Snapshot from leases + static |
Ack never waits. A dead BIND or a slow AXFR delays names, not leases. outbox / Overview lag.
Keep AD or BIND (usual day one)
Workstations already query the DCs. You do not change option 6.
laptop --option 6--> DC / BIND
dhcpd --SQL--> Postgres
worker --RFC 2136 / GSS-TSIG / HTTP--> DC / BIND / PowerDNS
lattice-dns (idle for this zone)
Use this for ad.example.com and _msdcs. Lattice must not host the forest.
Hidden primary (usual if Lattice owns the DHCP zone)
Laptops still do not point at Lattice. BIND is type secondary (older configs: type slave); the primary is the lattice-dns VIP. Parent NS at the registrar or internal parent is BIND, not Lattice. Syntax: BIND ARM — zone types.
laptop --option 6--> BIND (or Unbound → BIND)
BIND --AXFR/IXFR--> lattice-dns VIP :53
worker --embedded--> Postgres serial bump + NOTIFY
lattice-dns is doing the job: compiling leases and static records into a zone and serving it to secondaries. Clients never configured it.
Published lattice-dns (a dedicated internal zone only)
You choose to put the lattice-dns address in option 6. Then the stub sends every name there. Off-zone → REFUSED. google.com fails. dc01.ad.example.com fails.
That is correct only when clients in that zone never look up anything else (office.example.com only). It is wrong as the site resolver.
If you want laptops to use Lattice names and the internet / AD, put Unbound (or BIND as a cache) in option 6, and conditional-forward only our zones:
# Unbound — sketch, not a shipped file
forward-zone:
name: "office.example.com."
forward-addr: 10.0.0.10@53 # lattice-dns VIP
forward-zone:
name: "20.20.10.in-addr.arpa."
forward-addr: 10.0.0.10@53
Leave AD on the DCs (another stub-zone / forward). Do not forward the forest at Lattice.
4. What lattice-dns is doing when you use it
Authoritative only (RecursionAvailable=0). In-memory snapshot from Postgres:
- SOA/NS from
dns_zone - A/AAAA/PTR from leased rows and
static_record - MX/SRV/CAA from static records
The embedded adapter does not send RFC 2136 to lattice-dns. It bumps dns_zone.serial and NOTIFY. lattice-dns reloads. Off-zone REFUSED; missing name NXDOMAIN; name in zone wrong type NODATA.
AXFR is TCP (ACL + optional TSIG). IXFR only from the previous compiled snapshot; process restart → next transfer is AXFR.
Listen on :53 on the node or the HA VIP. Binary notes: dns.
5. Why Lattice is not Unbound
Recursive lookup, forwarding, RPZ, public DNS, DNSSEC, and hosting the AD forest are v1 non-goals (01-VISION.md). Unbound already does recursion. AD already does the forest. Principle: adapter, don’t colonize — day one does not mean “repoint every workstation.”
A Lattice recursive forwarder would own “the internet is down,” cache, _msdcs, and Infoblox-shaped DNS security. The product is IPAM + scale-out DHCP + updates (and optional authoritative for our zones). Option 6 still points at AD, Unbound, or BIND.
6. Checklist
- One adapter per zone
- Forest /
_msdcsstays on the DCs (adapter-only, neverembedded) - Option 6 is set on purpose (DHCP option code 6). Enabling
embeddeddid not set it - Option 6 is not the lattice-dns VIP unless that zone is all clients query, or Unbound sits in front
- Hidden primary: parent NS = BIND;
allow_transfer/also_notify= slave IPs - Published + real site: Unbound in option 6; forward only Lattice zones
- After Ack, missing names → Overview outbox lag, not a DHCP failure