Skip to content

fix(dns): enable installs the proxy and the root without help - #472

Merged
ralyodio merged 1 commit into
mainfrom
fix/automate-trust-and-proxy
Aug 30, 2026
Merged

fix(dns): enable installs the proxy and the root without help#472
ralyodio merged 1 commit into
mainfrom
fix/automate-trust-and-proxy

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Three bugs, each of which forced a manual step. Together they were the manual setup a desktop needed.

1. The proxy lookup used root's home

proxyWrapperPath() called homedir(). dns enable escalates, so that's /root — where moshpit-proxy is definitively not installed. It reported "no pinned-TLS proxy installed" on a machine with one running, and told people to install what they already had.

Now uses operatorHome(), which this codebase already had for exactly this mistake. Same for the generated unit and MOSHPIT_PROXY_DIR, which were pointing a system service at /root/.moshpit — where the local root isn't.

2. The trust check could never pass

requireNameConstraints refused any root that didn't permit every claimed ending. But the root is minted by moshpit-proxy for the endings it serves — a handful — while the registry has sold 18,224.

So it refused a working root for not covering 18,000 endings nobody was trying to reach. And its advice (regenerate the root) cannot help: the new root is scoped to the same handful.

A root that covers some of what you resolve is worth what it covers. It installs now, and reports the shortfall. Refused only when it covers none — then it's the wrong root, not a partial one.

The gate that matters is untouched. A root permitting an ending we don't resolve can vouch outside the namespace, and is still refused.

3. Both refusals printed the whole list

At 18,224 endings that's several screens — not a diagnostic, but the reason the line above it goes unread. summarise caps at eight and a count.

Why this is the automation

The proxy service installs because the wrapper is found. The root reaches the system store because a partial root is no longer a refusal — which is what curl needs, and what moshpit-trust alone never provides (it does NSS only).

Tests

Four rewritten around the new policy: refused when it covers none (and names them), installed when partial (with missing and a covers 2 of 3), still refused when it reaches past Moshpit, and one asserting a refusal stays under 400 characters with 500 endings in play.

Suite: 2744 tests, 0 failures.

Still open

http:// on a Moshpit name hits port 80 on the machine — the local web server, if there is one — because proxy mode points names at loopback and the proxy only owns 443. That needs moshpit-proxy to take :80 as well.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ThnQwoieWt8VR6N7gtgnhp

Three bugs, each of which forced a manual step, and together they were the
whole of the manual setup a desktop needed.

1. `proxyWrapperPath()` looked in homedir(). `dns enable` escalates, so that
   is /root — where moshpit-proxy is definitively not installed. It reported
   "no pinned-TLS proxy installed" on a machine with one running, and told
   people to install what they already had. Now the operator's home, via the
   `operatorHome` this codebase already had for exactly this mistake. Same for
   the generated unit and MOSHPIT_PROXY_DIR, which were pointing a system
   service at /root/.moshpit — where the local root is not.

2. `requireNameConstraints` refused any root that did not permit *every*
   claimed ending. The root is minted by moshpit-proxy for the endings it
   serves — a handful — while the registry has sold 18224, so this could never
   pass on a real machine. It refused a working root for not covering 18000
   endings nobody was trying to reach, and the advice it gave (regenerate the
   root) could not help, because the new root is scoped to the same handful.

   A root that covers some of what you resolve is worth what it covers, so it
   installs and reports the shortfall. Refused only when it covers none of them
   — then it is the wrong root, not a partial one.

   The gate that matters is untouched: a root permitting an ending we do not
   resolve can vouch outside the namespace, and is still refused.

3. Both refusals printed the full list. At 18224 endings that is several
   screens, which is not a diagnostic — it is why the line above it goes
   unread. `summarise` caps it at eight and a count.

Together these are what made `dns enable` finish the job: the proxy service
installs because the wrapper is found, and the root reaches the system store
because a partial root is no longer a refusal — which is what curl needs and
what `moshpit-trust` alone never provides.

Four tests rewritten around the new policy, including one asserting a refusal
stays under 400 characters with 500 endings in play. Suite: 2744, 0 failures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01ThnQwoieWt8VR6N7gtgnhp
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

1 finding(s) in the 3 file(s) this pull request changes.

MEDIUM: 1

Severity Rule Location
MEDIUM insecure-temp-file test/trust.test.mjs:277
90 pre-existing finding(s) elsewhere in the repository — **HIGH/CRITICAL**: 8 | **MEDIUM**: 72 | **LOW**: 10

Not introduced by this pull request. The full set is in the Security tab.

Severity Rule Location
HIGH js-ssrf-outbound-request apps/pwa/public/sw.js:45
HIGH tls-verification-disabled apps/pwa/src/lib/moshpit-gateway.mjs:299
HIGH sh-remote-script-execution install.sh:86
HIGH sh-remote-script-execution install.sh:90
HIGH sh-remote-script-execution install.sh:202
HIGH sh-remote-script-execution install.sh:213
HIGH sh-remote-script-execution install.sh:219
HIGH tls-verification-disabled src/dns.mjs:766
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:139
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:153
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:179
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:373
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:377
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:422
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:671
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:867
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:869
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:928
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:974
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:1044

…and 70 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit a0f7066 into main Aug 30, 2026
6 checks passed
@ralyodio ralyodio mentioned this pull request Aug 30, 2026
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