Research 033 measured the laptop's VPN client and the mesh overwriting each other's resolver file in nine of nine sessions, each time cutting off one kind of name. The operator chose a resolver module on a node seat of its own, installed only where something requires split-dns, with the VPN client's module carrying the adapter. Graduates research 033 into to-be 50, and amends connectivity §2, to-be 48 §10, the seats and the glossary.
80 lines
4.8 KiB
Markdown
80 lines
4.8 KiB
Markdown
---
|
|
status: graduated
|
|
initiated: 2026-10-07
|
|
became:
|
|
- 02-DECISIONS/0247-a-machine-with-a-vpn-client-routes-names-by-domain-through-a-resolver-of-its-own.md
|
|
- 03-DESIGN/01-to-be/50-split-dns-on-a-machine-with-a-vpn-client.md
|
|
touches:
|
|
- 02-DECISIONS/0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md
|
|
- 02-DECISIONS/0117-a-machines-uplink-is-a-seat.md
|
|
- 03-DESIGN/01-to-be/08-connectivity.md
|
|
- the node-uplink seat and its holders
|
|
- the node-engine's reconcile of a file another program rewrites
|
|
---
|
|
|
|
# 033 — Split DNS with a VPN client
|
|
|
|
## What is investigated
|
|
|
|
How a machine of the mesh resolves three kinds of name at once — the mesh's (`*.internal`), a
|
|
corporate network's reached through a VPN client, and public ones — when the VPN client writes
|
|
`/etc/resolv.conf` itself.
|
|
|
|
[ADR 0223](../../02-DECISIONS/0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md) gives
|
|
every machine one resolver file listing the mesh's two resolvers and nothing else, written by the holder
|
|
of the machine's uplink ([ADR 0117](../../02-DECISIONS/0117-a-machines-uplink-is-a-seat.md)). On the
|
|
laptop, a corporate VPN client replaces that file when it connects, with its own servers and eight search
|
|
domains. The node-engine finds the file changed and writes the mesh's back on its next reconcile. From
|
|
then on, for the rest of the session, the corporate names do not resolve; in the minutes before it, the
|
|
mesh's names did not. Neither program knows the other exists.
|
|
|
|
The questions:
|
|
|
|
1. **How the VPN client sets DNS** on Linux: does it overwrite the file, use `resolvconf`, or talk to
|
|
systemd-resolved or NetworkManager; what it backs up and restores; whether it re-asserts its file.
|
|
2. **What it pushes**: how many servers, which domains, over which link, and what routes.
|
|
3. **How often the two collide** on the live mesh, and what each collision costs.
|
|
4. **The options**: per-link routing in systemd-resolved, adding the VPN's servers to the mesh's file,
|
|
forwarding the corporate domains from the mesh's resolvers, standing back while the VPN is up, and
|
|
any other — and what each means for ADR 0223 and for the machines that run no VPN.
|
|
|
|
## Why
|
|
|
|
The operator uses the VPN for work, every working day. While it is up the laptop is either cut off from
|
|
the mesh (agents saw lookups fail) or cut off from the corporate network, depending on which program
|
|
wrote the file last. A rule of the mesh that a machine's own work program silently breaks — or that
|
|
breaks the machine's owner's work — is a rule that cannot be kept as stated.
|
|
|
|
A sibling decision proposed alongside this effort, ADR 0241 (machine network health), makes the
|
|
node-engine detect and report an outside writer of the resolver file. That says the fault; this effort
|
|
asks how it stops being one.
|
|
|
|
## What it touches
|
|
|
|
ADR 0223's rule that a machine lists only the mesh's resolvers, and its rejection of a local forwarder;
|
|
ADR 0117's list of what an uplink holder declares; the networkmanager module (the uplink holder on the
|
|
laptop); the node-engine's correction of a file changed on the machine; connectivity §2.
|
|
|
|
## Where it stands
|
|
|
|
Evidence gathered read-only on the laptop and options weighed, 2026-10-07:
|
|
|
|
- [01 — The evidence](01-evidence.md): the VPN client always *moves* the resolver file aside and writes
|
|
its own (two servers, eight search domains), restores its backup on disconnect, and never re-asserts;
|
|
it does not configure systemd-resolved or NetworkManager per link on this machine. In every one of the
|
|
nine sessions since the node-engine's journal begins, the node-engine wrote the mesh's file back within
|
|
1 s to 3.5 min; once the VPN client's restore of a stale backup was itself corrected.
|
|
- [02 — Options](02-options.md): six, from systemd-resolved per-link routing to replacing the VPN
|
|
client.
|
|
- [03 — Recommendation](03-recommendation.md): on a machine that declares a VPN client, the uplink's
|
|
holder runs systemd-resolved as a local router on the machine's private address, and hands it the
|
|
VPN's servers and domains the moment the VPN client writes them; every other machine is unchanged.
|
|
A proposed decision text with how each rule is checked.
|
|
|
|
**Graduated 2026-10-07** into [ADR 0247](../../02-DECISIONS/0247-a-machine-with-a-vpn-client-routes-names-by-domain-through-a-resolver-of-its-own.md)
|
|
and [to-be 50](../../03-DESIGN/01-to-be/50-split-dns-on-a-machine-with-a-vpn-client.md). The mechanism is
|
|
the recommendation's: systemd-resolved routing the VPN's domains over its link. Who runs it differs, by
|
|
the operator's decision. The resolver is a module of its own on a node seat, `node-resolver`, rather than
|
|
part of the uplink's holder, which has two forms. The VPN client's module carries the adapter, so no
|
|
setting declares a VPN client. The interim *defer* setting is not adopted. The record says why.
|