feat(dns): send a name nobody holds to the pit instead of an error page - #79
Merged
Conversation
Someone types `mosh.whatever`. Today the registry has no ending called `.whatever`, so the resolver hands back clearnet's verdict — NXDOMAIN, a browser error page, and a person who just demonstrated demand for a name walks away. This turns that into the front door. Two halves. The gateway now redirects any Moshpit Host it does not serve to `app.moshcode.sh/pit?name=<host>`, where the pit offers them the ending the name sits under (moshcoder/moshcode#124). A redirect rather than a proxy: proxying would leave people signing in under a hostname no CA will vouch for, with a session cookie on a domain the app does not own. The other half is MOSHPIT_DNS_CATCHALL, off by default, which makes unclaimed names resolve to the gateway at all. Without it the funnel only works for endings someone already claimed, which is the wrong half of the audience. The boundary is the entire feature. `asdkjh.com` is NXDOMAIN too, and answering it would make this a typo-squatter for the whole internet — the behaviour ISPs were rightly hated for. So the catch-all fires only when the TLD itself is absent from the legacy root, checked by asking the upstreams for its SOA (one cached query per ending, not per name) rather than by shipping an IANA list that is stale the week after it is written. An unreachable upstream fails closed: unknown means the root has it, because the alternative is handing the internet to the catch-all during an outage. Answers say what they are: `aa` is 0 since nobody holds the name, and TXT reports `unclaimed=1`. Off by default — answering for names the registry never granted is a product decision, not a default a resolver should assume. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
ralyodio
marked this pull request as ready for review
July 31, 2026 04:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Yes —
mosh.whatevershould land on the pit ready to register. This is the resolver + gateway half; moshcoder/moshcode#124 is the page it lands on.The flow
Two halves
The gateway redirect (
deploy/Caddyfile.gateway) — any Moshpit Host it does not serve now goes toapp.moshcode.sh/pit?name=<host>. A redirect rather than a proxy on purpose: proxying would leave people signing in under a hostname no CA will vouch for, with a session cookie on a domain the app does not own. The redirect puts them on the real origin with a real padlock, where signing in works.MOSHPIT_DNS_CATCHALL(off by default) — without it, unclaimed names never resolve at all, so the funnel only works for endings someone already claimed, which is the wrong half of the audience.The boundary is the whole feature
asdkjh.comis NXDOMAIN too. Answering that would make this resolver a typo-squatter for the entire internet — what ISPs were rightly hated for. So the catch-all fires only when the TLD itself is absent from the legacy root, checked by asking the upstreams for its SOA (one cached query per ending, not per name) instead of shipping an IANA list that is stale the week after it is written.An unreachable upstream fails closed — unknown means "the root has it" — because the alternative is handing the whole internet to the catch-all during an outage.
Answers say what they are:
aais 0 (nobody holds the name; claiming authority would be a lie) andTXTreportsunclaimed=1.Verified
8 new tests covering exactly the ways this could go wrong:
aa=0, counted ascatchallasdkjh.com→ NXDOMAIN, untouchedtsc --noEmitclean. Suite: 123 pass, 1 fail —tests/coinpay-amount.test.mjs, which fails onmasterindependently of this branch (git logblames #59;setupAmountUsdcompares float error againstNumber.EPSILON, so19.99throws). Not touched here.Off by default
Turning it on makes the resolver answer for names the registry never granted. That is a product decision, so it is a flag, not a default — flip
MOSHPIT_DNS_CATCHALL=1when you want the funnel.🤖 Generated with Claude Code