Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@moshcoder/moshpit-dns

Resolve Moshpit names on this machine — from curl, any browser, any program.

npm i -g @moshcoder/moshpit-dns
sudo moshpit-dns enable
moshpit-dns service install     # keep it running across reboots

Zero dependencies. Everything comes from node: builtins.

Why it exists

The Moshpit registry speaks HTTP, not DNS. pit.moshcode.sh answers /api/moshpit/resolve?name=… and nothing listens on port 53, so curl https://california.oranges/ fails everywhere. A browser extension that redirects tabs works, but redirecting is not resolving, and nothing outside that browser benefits from it.

This is the bridge: a tiny authoritative resolver that answers Moshpit endings out of the registry's HTTP API, and is deliberately silent about everything else.

It answers AAAA and A from the name's target, and CNAME, MX and TXT from the records its owner publishes in the Pit. Question types it does not serve get an empty NOERROR rather than NXDOMAIN — the name exists, there is just nothing to say about that question, and denying the name outright would take its address down with it.

A name pointed at a hostname rather than an address answers with the CNAME it published, for the client to chase through its own resolver. This bridge never does clearnet DNS itself.

Names also answer one level down. An owner who publishes records for *.chovy.hacker covers everything under their name: a question for foo.chovy.hacker is asked of the registry as-is, the wildcard is tried as a literal name when that misses, and the answer comes back owned by the name that was asked — standard wildcard semantics. A sub-name missing from both is NXDOMAIN rather than parked: parking sells the bare label, and there is nothing to park a sub-name to.

One suffix, not your whole resolver

Each OS has a way to send one suffix to a different nameserver without becoming the resolver for everything, and this uses that on each:

macOS /etc/resolver/<tld>, read per query — nothing to restart
Linux systemd-resolved Domains=~tld routing-only domains, or dnsmasq
Windows one NRPT rule per namespace

That choice is the whole safety story. Becoming the machine's nameserver would put every lookup on the box behind this bridge; routing only Moshpit endings means the worst failure is that Moshpit names stop working.

Commands

moshpit-dns enable            route the endings here and start the bridge
moshpit-dns disable           undo both
moshpit-dns status [--json]   what is running, what is routed, does it work
moshpit-dns refresh           re-apply routing for endings claimed since

moshpit-dns service install   keep the bridge running across reboots
moshpit-dns service uninstall stop doing that

moshpit-dns tlds [--json]     list the endings claimed in the Pit
moshpit-dns records <name...> [--type AAAA|CNAME|MX|TXT] [--json]
                             inspect records published for names
moshpit-dns resolve <name...> [--concurrency N] [--json]
                             what names resolve to, and why
moshpit-dns start [--ttl N]   run the bridge in the foreground
moshpit-dns install           print the resolver config without applying it

--dry-run prints the exact file contents and commands before anything runs. This edits system DNS under sudo, so being inspectable first is the point.

tlds, records, resolve, and status accept --json for scripts and monitoring. The JSON includes registry reachability, published AAAA/CNAME/MX/TXT records, the final DNS address for a resolution, and structured status warnings without mixing human-readable lines into stdout. Failures such as an unreachable registry still produce valid JSON and a non-zero exit status where the command normally fails. For compatibility, resolving or inspecting one name returns the established JSON object. Multiple names return an ordered array and exit non-zero when any name is invalid or the registry cannot answer it. Repeated names share one registry lookup while still retaining their original positions in the output. Batch lookups run eight at a time by default; use --concurrency N to lower the load on a small self-hosted registry or raise it for a larger one without changing output order.

records and resolve take third-level and wildcard names as well: moshpit-dns records '*.chovy.hacker' inspects what an owner published for everything under their name, and foo.chovy.hacker resolves through it.

moshpit-dns resolve california.oranges --json | jq .address
moshpit-dns resolve california.oranges blue.eggs --json | jq '.[].address'
moshpit-dns records california.oranges MX --json | jq '.records[]'
moshpit-dns records california.oranges blue.eggs --type MX --json | jq '.[].records'
moshpit-dns status --json | jq '.warnings[]?.code'

DNS answers use a 30-second TTL by default. Pass --ttl N to start, enable, or service install to choose a whole number of seconds from 0 through 4294967295. enable carries the value into its detached bridge, and service install records it in the persistent service definition.

moshpit-dns start --ttl 300
sudo moshpit-dns enable --ttl 300
moshpit-dns service install --ttl 300

Registry requests time out after 4000 milliseconds by default so an unavailable endpoint cannot leave DNS queries hanging indefinitely. Pass --timeout N to choose a positive whole-number deadline in milliseconds. The value is carried into detached bridges and persistent service definitions as well as foreground commands.

moshpit-dns resolve california.oranges --timeout 1500
moshpit-dns start --timeout 1500
sudo moshpit-dns enable --timeout 1500
moshpit-dns service install --timeout 1500

What needs root, and what does not

Only enable, disable and refresh — the acts that edit system DNS. The bridge listens on 5354 and the service that keeps it alive is a user service, so nothing else asks for privileges.

Windows is the exception on port: an NRPT rule has nowhere to put one, so the bridge must be on 53 there. Refused at plan time with the reason, rather than producing a rule that points at a port nothing is listening on.

Two states worth knowing

Routing up, bridge down. Names fail instead of falling through to your normal resolver. status says so loudly, and service install is what stops it happening after a reboot.

Routing is a snapshot. Arbitrary endings share no common suffix, so every one is listed by name. An ending claimed after you enabled will not resolve until sudo moshpit-dns refresh. status compares the counts and tells you when they have drifted.

Self-hosting

--registry https://your.pit anywhere, and the routing follows it. Nothing here is specific to pit.moshcode.sh beyond the default.

License

MIT.

About

Resolve Moshpit names on this machine. A tiny DNS bridge for .whatever endings, routed per-suffix so the rest of the internet is untouched.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages