feat(deploy): make /opt/moshpit a checkout, so merging ships - #15
Merged
Conversation
…body can verify
The template redirected :80 to :443, with a comment saying the only
problem was a missing 443 block. That reasoning was incomplete: it
assumes the client can verify what it lands on, and the two biggest
classes cannot.
No CA will issue for an ending outside the DNS root, so the 443 block
presents a self-signed certificate. TronBrowser, moshpit-proxy and the
SDKs check it against the registry's published pin and are fine. curl and
a stock browser have no pin to check, so they reject it — and the
redirect leaves them nowhere:
curl chovy.hacker -L
curl: (60) SSL certificate problem: self-signed certificate
Through the gateway it is worse: pit.moshcode.sh forwards the status and
not the Location, so a visitor gets a 301 pointing nowhere at all.
Now :80 serves the site. Both ports serve it, neither redirects to the
other, and each client takes the one it can verify — pin-checking clients
still get TLS, everyone else gets the page instead of an error that reads
as "Moshpit is broken".
HTTPS-only remains right for a name in the public DNS. It is not
available for a name outside it, and pretending otherwise costs the
visitor the site.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
/opt/moshpit was a hand-copied nginx/ and scripts/. A merged fix reached a box only when somebody remembered to copy it, and forgetting does not raise an error — it produces a fix that appears not to work. That cost a full afternoon today: the origin template still redirected to HTTPS on a box whose repo had stopped doing so, and every reconcile pass faithfully re-applied the stale copy over the hand-edited vhosts. The same shape bit the DNS resolver deployment twice more. Adds an updater and a 15-minute timer. It converts a hand-copied prefix into a checkout on first run rather than asking anyone to do that by hand, because an upgrade path nobody has to read about is the only kind that gets taken. The superseded tree is kept beside the new one: if somebody edited a script in place and never upstreamed it, that is the only copy holding it. Safety, in order of how badly each fails: - uncommitted changes in the prefix abort the update. Overwriting them silently is how a fix applied on the box at 3am vanishes without trace - fast-forward only; a diverged prefix is a person's problem, not a script's - a failed clone or fetch leaves the prefix exactly as it was - `nginx -t` before reload, and a failing test warns rather than aborts — the update has already landed and failing here would strand the checkout 15 minutes, not one: this reaches the network, and a merge is not urgent where an unserved name is. Randomised so a merge does not have every origin fetch at once, and Persistent so a box that was off catches up.
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
Merged
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.
Follow-up to #14, which fixed a template that then had to be copied to the box by hand.
The problem
/opt/moshpitis a hand-copiednginx/andscripts/. A merged fix reaches a box only when somebody remembers to copy it — and forgetting produces no error, just a fix that appears not to work.That cost an afternoon today. #14 removed the HTTPS redirect from the origin template; the box still had the old one, and
moshpit-reconcilefaithfully re-applied it every 60 seconds over vhosts that had been fixed by hand. The debugging looked like "the fix didn't take" rather than "the fix isn't here". The same shape bit the DNS resolver deployment twice more the same day.What this adds
scripts/moshpit-update.shplus a 15-minute timer.It converts a hand-copied prefix into a checkout on first run rather than asking anyone to do it by hand — an upgrade path nobody has to read about is the only kind that gets taken. The superseded tree is kept beside the new one, because if somebody edited a script in place and never upstreamed it, that is the only copy holding it.
Safety, ordered by how badly each would fail
nginx -tbefore reload, and a failing test warns rather than aborts: the update has already landed, and dying here would strand the checkout mid-way.Why 15 minutes and not one
Reconcile runs every minute because an unserved name is urgent. This reaches the network and a merge is not.
RandomizedDelaySecso a merge does not have every origin fetch at once;Persistent=trueso a box that was off catches up rather than waiting a full interval.Install
Copy
scripts/moshpit-update.shinto/opt/moshpit/scripts/and the two units into/etc/systemd/system/, thensystemctl daemon-reloadandsystemctl enable --now moshpit-update.timer— all as root.The first run converts
/opt/moshpitinto a checkout; every run after is a fast-forward.--dry-runsays what it would do without touching anything.