88 lines
5.0 KiB
Plaintext
88 lines
5.0 KiB
Plaintext
# Managed by the mesh. dnsmasq's own defaults are replaced whole rather than
|
|
# patched, because this module owns the file and a patch would leave whatever
|
|
# was there before to be discovered later.
|
|
#
|
|
# This is one of the mesh's resolvers (novox/hq ADR 0194, 0223): it holds the
|
|
# `mesh-dns-resolver` seat, which more than one machine may hold, each answering
|
|
# the same names from the same roster. Every node and every container lists every
|
|
# holder and no public resolver, so whichever answers first gives the one answer.
|
|
# It holds the mesh's own names and nothing else (ADR 0191) — the roster is the
|
|
# mesh's, rendered into each holder; no other copy lives on any machine.
|
|
|
|
# What the mesh computed: one wildcard per machine — its name and everything
|
|
# under it — and the mesh's own suffix as a local domain, so a name under it is
|
|
# answered here or not at all and is never asked upstream. Rewritten whenever a
|
|
# machine joins or leaves, which is why the service below restarts on it: a
|
|
# reload makes dnsmasq re-read hosts files, not its configuration, and a
|
|
# wildcard is configuration.
|
|
conf-file=/etc/mesh-resolver/nodes.conf
|
|
|
|
# Every zone a module answers itself (ADR 0199): one forwarding line per zone, to
|
|
# the private address of the machine its module runs on and the port its
|
|
# answerer is published on. Nothing in a zone is answered here; what names a zone
|
|
# holds is the module's. Rewritten whenever a zone is declared or moves, and the
|
|
# service restarts on it for the same reason as above.
|
|
conf-file=/etc/mesh-resolver/zones.conf
|
|
|
|
# Where it answers: this machine's private address, so every node — and every
|
|
# container on every node, which copies its machine's resolvers — can ask; and
|
|
# loopback, for this machine's own use. Never a LAN address: a device that is
|
|
# not a member cannot reach what the mesh's names point at, and a LAN's resolver
|
|
# is its router's (ADR 0194).
|
|
#
|
|
# Named as an ADDRESS and not as the interface that carries it, on purpose. A
|
|
# container's query is addressed to this address but arrives on the runtime's
|
|
# bridge, and dnsmasq checks every query against what it was told to answer on:
|
|
# an `interface=` line admits queries by the interface they arrive on, a
|
|
# `listen-address=` line by the address they are sent to. With `interface=mesh0`
|
|
# alone, a query from a container was received and dropped without a word
|
|
# (novox/hq 04-ISSUES/110). The address admits it whatever bridge it comes in on.
|
|
#
|
|
# bind-interfaces, and never bind-dynamic (novox/hq issue 348). bind-dynamic
|
|
# re-reads the machine's addresses on every change of any link and closes each
|
|
# listener whose interface that reading did not find; a reading made while the
|
|
# container runtime deletes a bridge's virtual links fails ("index gone"), and
|
|
# then every listener is closed until a later change reads cleanly. On
|
|
# 2026-10-09 the private address was left unbound for twenty minutes, the daemon
|
|
# running and silent. bind-interfaces binds each address once, at start, and
|
|
# never closes it. It cannot bind an address that is not there yet, so the unit
|
|
# waits for it (the drop-in below); a new private address restarts the unit, as
|
|
# this file changing always did.
|
|
bind-interfaces
|
|
listen-address=${machine:address}
|
|
listen-address=127.0.0.1
|
|
|
|
# **It must never read resolv.conf to find out where to forward.** This
|
|
# machine's resolv.conf names this resolver — so a resolver that read it for
|
|
# upstreams would find itself, and every query it could not answer locally would
|
|
# loop until its receive queue filled. That is not theoretical: it filled with
|
|
# 15KB of queries and every lookup on the machine hung. no-resolv makes that loop
|
|
# impossible: the upstreams are the two lines below, and nothing on the machine
|
|
# can redirect them. The mesh's own names never reach them: the local= line in
|
|
# the file above stops them here, answered or refused.
|
|
no-resolv
|
|
server=1.1.1.1
|
|
server=8.8.8.8
|
|
|
|
# Both upstreams validate DNSSEC and say so with the Authenticated Data bit,
|
|
# and this passes that bit down rather than dropping it, which dnsmasq does
|
|
# unless told. It does not validate itself: an answer's trust is the upstream's
|
|
# and the path to it, which is what a forwarding resolver's trust always was.
|
|
# Without it a program that refuses to run behind a resolver that does not
|
|
# validate — a mail system's admin does exactly that check at start — cannot
|
|
# use this resolver (novox/hq 04-ISSUES/171).
|
|
proxy-dnssec
|
|
|
|
# A name without a dot is never forwarded, and reverse lookups of private ranges
|
|
# are answered here rather than asking the world who 10.x is.
|
|
domain-needed
|
|
bogus-priv
|
|
|
|
# **No hosts file, and no operator's files.** This machine's /etc/hosts is its
|
|
# own — the hosts module's block and the operator's lines (ADR 0199) — and the
|
|
# mesh's resolver answers every node, so a line written for one machine's own
|
|
# programs must not become an answer for all of them. Every per-node resolver
|
|
# went wrong exactly here: a hosts file read once at start, an operator's old
|
|
# line beside the mesh's, a drop-in read from a directory nobody owned.
|
|
no-hosts
|