Skip to content

Track the resolver setup that only existed on the box - #9

Merged
ralyodio merged 1 commit into
mainfrom
resolver-config
Aug 1, 2026
Merged

Track the resolver setup that only existed on the box#9
ralyodio merged 1 commit into
mainfrom
resolver-config

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

moshpit-dns.service and the systemd-resolved drop-in were configured by hand on a live machine and lived in no repository. The working DNS setup was one disk failure from being lost, and impossible to reproduce on a second box.

Both are committed here exactly as deployed (verified byte-identical to the running machine), along with the reasoning that is easy to get wrong.

The bridge runs as the primary resolver, with no TLD list at all

That is not a shortcut. A per-TLD list cannot be made to work, for two independent reasons:

1. It does not scale. moshcode dns install --write emits every claimed ending as a routing domain — 5,661 on one line, ~60KB. systemd-resolved caps search domains near 1090 and drops the rest alphabetically:

Failed to add search domain '~zoology', ignoring: Argument list too long

8,199 of those in a single restart. ~hacker and ~eggs fell past the cut — configured on disk, absent from the resolver.

2. Curating the list does not fix it either. A routing domain selects a scope, and a scope tries its servers in order. With an upstream in the same scope, .hacker went to 67.207.67.3, came back NXDOMAIN, and systemd-resolved treated that as final. The bridge was never asked. This is why the "just trim the list" fix kept appearing to work and didn't.

Sending every query to the bridge removes both problems. It answers Moshpit names from the registry and forwards the rest upstream (mode=clearnet).

Two things that cost real debugging time

The 00- prefix is load-bearing. systemd-resolved appends DNS= in filename order and uses the first server, rotating only on failure — never on NXDOMAIN. So pre-existing resolvers stay listed as a genuine fallback if the bridge stops, instead of shadowing it. Same servers, same list: ordering is the entire difference between a safety net and the bug.

MOSHPIT_DNS_CATCHALL must stay unset. It parks every unresolved name on the registry's parking address, so on a machine's own resolver github.com resolves to a parking page. Documented alongside the symptom to look for: if clearnet names start returning a 69.46.46.x address, check for a stray moshcode dns start bound to 127.0.0.1:5354 — a loopback bind beats the service's 0.0.0.0 bind and silently wins every local query. That was the actual root cause of the outage.

Restart=always because it is the resolver now. It replaced an orphaned process (PPID 1, no unit) that would have stayed dead.

Note on placement

moshpit-dns would be the more natural home, but that directory is not a git repository on any machine I can see. This repo already carries the deployment-side config (nginx/moshpit-gateway.conf, nginx/moshpit-origin.conf), so it is the closest existing home. Worth moving if moshpit-dns ever gets version-controlled.

🤖 Generated with Claude Code

moshpit-dns.service and the systemd-resolved drop-in were configured by hand
on a live machine and lived in no repository, so the working DNS setup was
one disk failure from being lost and impossible to reproduce.

Both are here as deployed, with the reasoning that is easy to get wrong:

- the bridge runs as the machine's primary resolver, with no list of Moshpit
  endings at all. A per-TLD list cannot work -- 5,661 routing domains blow
  systemd-resolved's ~1090 cap, and even a curated list fails because a
  routing domain selects a *scope*, and an upstream in that scope answers
  NXDOMAIN before the bridge is asked.
- the drop-in is named 00- so it is read first; resolved uses the first
  server and rotates only on failure, never on NXDOMAIN, so pre-existing
  resolvers remain a real fallback instead of shadowing the bridge.
- MOSHPIT_DNS_CATCHALL must stay unset: it parks every unresolved name, so
  github.com resolves to a parking page.

Restart=always because it is the resolver now; it replaced an orphaned
process that would have stayed dead.
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@ralyodio
ralyodio marked this pull request as ready for review August 1, 2026 18:51
@ralyodio
ralyodio merged commit 1f635f7 into main Aug 1, 2026
3 checks passed
@ralyodio
ralyodio deleted the resolver-config branch August 1, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant