From f3ffdae9099cf5a14ca8c904ee5c93e4bebfeacf Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 31 Aug 2026 14:23:02 +0200 Subject: [PATCH] Record the resolver as built, and the two things it must not do A service is reached at ..internal, so what resolves is anything under a node's name. The mesh writes the data and runs no daemon; two roles, two claims, because systemd-resolved cannot serve a wildcard at all. Both prohibitions were found by a machine rather than by reasoning: an address systemd already held, and reading resolv.conf for upstreams that now point at itself. --- 03-DESIGN/01-to-be/08-connectivity.md | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/03-DESIGN/01-to-be/08-connectivity.md b/03-DESIGN/01-to-be/08-connectivity.md index 627fae0..2c8b300 100644 --- a/03-DESIGN/01-to-be/08-connectivity.md +++ b/03-DESIGN/01-to-be/08-connectivity.md @@ -277,6 +277,41 @@ joins, and a module that did not would be one whose containers cannot reach anyt somebody starts by hand is not the mesh's to configure, and reaching into every container on a machine — declared or not — is what a nameserver in `resolv.conf` would be for. +### The resolver, built + +*2026-08-31.* **A service is reached at `..internal`** — the first label is the +service, the rest is the node — so what resolves is *anything under a node's name*, going to that +node. What routes it once it arrives is a proxy's, and stays separate. + +**The mesh writes the data and runs no daemon.** One wildcard per machine, from the same set that +writes the hosts file. A resolver is third-party software and runs *on* the mesh rather than being +*of* it: the mesh has no business shipping one, choosing which one, or knowing its configuration +language. Swapping dnsmasq for unbound changes that module and nothing in the control plane. + +**Two roles, two claims, because they are different things.** systemd-resolved cannot answer a +wildcard at all — it routes the mesh's suffix to something that can. Treating serving and asking +as one role produces a module that cannot work. + +| | claims | | +|---|---|---| +| serving | `the-dns-port` | answers the wildcards | +| asking | `the-resolver-configuration` | decides what the machine asks | + +So *which* resolver is not a mesh-wide decision. One machine can use what systemd already owns and +another can run dnsmasq, and two of either on one machine is refused rather than fought over. + +**Two things a resolver must not do**, both found by a machine rather than by reasoning: + +- **Take an address something else holds.** systemd-resolved holds `127.0.0.53` *and* `127.0.0.54`. +- **Read `resolv.conf` for its upstreams.** Whatever points a machine at the mesh writes the + resolver's own address there, so it becomes its own upstream and every query it cannot answer + loops until its receive queue fills. It needs no upstream: only the mesh's suffix is routed to + it. + +*Checked on two machines, through the path an application takes — nsswitch, files, then DNS — +because the module deciding what the machine asks is half of what is being tested and only that +path goes through it.* + **That is now the second reason to want a resolver**, and it is a different one from the trigger above: