Skip to content

dev2-edge: pit.world and the Moshpit names on Caddy, every other site on nginx - #199

Merged
ralyodio merged 6 commits into
masterfrom
dev2-edge-caddy
Oct 19, 2026
Merged

ralyodio merged 6 commits into
masterfrom
dev2-edge-caddy

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Anthony approved 2026-10-19 ("pit.world first"): nginx hands only pit.world traffic, by TLS name, to Caddy; every other site stays on nginx.

What

  • nginx stream {} on :443 (v4+v6), ssl_preread, map $ssl_preread_server_name (hostnames): pit.world, www.pit.world, *.pit.world, and the Moshpit names in dev2/edge/edge.json -> Caddy 127.0.0.1:8453; default -> nginx 127.0.0.1:8444. proxy_protocol on to both.
  • Every nginx listen 443 ssl becomes listen 127.0.0.1:8444 ssl proxy_protocol with set_real_ip_from 127.0.0.1; real_ip_header proxy_protocol; port_in_redirect off; (http level), so $remote_addr, rate limits, logs and ThreatCrush keep the visitor's address.
  • Caddy 2.11.7 (official static build, sha512-checked), unit caddy, user caddy, auto_https off, proxy_protocol listener wrapper, h1/h2 only, same upstreams/body limits as the nginx blocks, TLS 1.3-only for Moshpit names as before. live.streaming.pit.world stays on nginx for now (keep_on_nginx).
  • No new certificates. caddy-edge-certs bundles what certbot (pit.world), pit-proxy-cert (<name>.pit.world) and moshpit-renew (Moshpit names) already keep current; a .path unit reloads Caddy within a second of a renewal. Port 80 stays on nginx (ACME + http->https).
  • listen 443 guard. With the stream on :443, a vhost with listen 443 passes nginx -t but the reload cannot bind and nginx silently keeps the old config (a restart fails outright). OpenInstall bin/install.sh, setup-origin.sh (every Moshpit renewal) and certbot --nginx still write it, so nginx-edge-listen rewrites it before every nginx start/reload (systemd drop-in) and on any vhost change (.path). dev2-site vhost renders the 8444 form when the edge is on.
  • dev2-edge apply --yes does the cutover with a backup, a two-pass baseline sweep of every name, a Caddy-only check on its own port before traffic moves, one nginx reload, an after sweep, and automatic rollback on any status change. dev2-edge route off is the one-reload way back; dev2-edge rollback restores /etc/nginx from the tarball.

Rehearsal (dev3, Docker, dev2's real nginx config with self-signed certs at every path)

  • 287 names: identical status before/after; Caddy matched nginx for all 68 routed names before the switch.
  • SNI routing (Caddy vs nginx by Server header), client IP 172.17.0.1 seen by Caddy upstreams (X-Real-IP/XFF) and in nginx $remote_addr, websockets through Caddy (bbs.chovy.hacker.pit.world, pit.world, family.ancestry), http->https unchanged, TLS 1.3-only + X25519MLKEM768 on Moshpit names, no :8444 in nginx redirects.
  • No failed requests across rollback + apply reloads (curl loop on 3 names).
  • Failure paths: a Caddy mismatch and an nginx -t failure both rolled back; the restored /etc/nginx was byte-identical to the backup.
  • Renewal pickup (new serial served after a cert file change), stray listen 443 repaired, path-unit semantics checked with systemd on dev3.

Tests

test/dev2-edge.test.ts (11): the listen rewrite (variants, symlinks, idempotence, reverse), render (routing, Caddy sites per edge.json, --off, realip, caddy adapt when available), cert bundling (mismatch skipped, reload only on change).

🤖 Generated with Claude Code

ralyodio and others added 2 commits October 19, 2026 20:38
… on nginx

nginx's stream module takes :443 and routes by TLS server name (ssl_preread):
pit.world, *.pit.world and the Moshpit names in dev2/edge/edge.json go to Caddy on
127.0.0.1:8453, everything else to nginx's https servers on 127.0.0.1:8444, both
with a PROXY protocol header so client addresses survive.

- dev2/dev2-edge: render / apply / route on|off / rollback / sweep / status
- dev2/edge/edge-box: the box side; apply backs up /etc/nginx, sweeps every name
  twice, checks Caddy answers like nginx on its own port before any traffic moves,
  switches with one nginx reload, sweeps again and rolls back on any change
- caddy-edge-certs (+ .path/.timer): Caddy loads bundles of the certificates
  certbot, pit-proxy-cert and moshpit-renew already renew; Caddy issues nothing
- nginx-edge-listen (+ nginx.service drop-in, .path): rewrites any `listen 443`
  a tool writes later (install.sh, setup-origin.sh, certbot --nginx), which would
  otherwise pass nginx -t and then silently fail to bind on reload
- dev2-site vhost renders the 8444 form when the edge is on
- test/dev2-edge.test.ts

Rehearsed on dev3 against a copy of dev2's nginx config: 287 names same status
before/after, SNI routing, client IP in nginx and Caddy upstreams, websockets,
http->https, no dropped requests across the switch and the rollback, renewal
pickup, stray listen 443 repair, rollback restores /etc/nginx byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

ThreatCrush Security Scan

41 finding(s)

HIGH/CRITICAL: 15 | MEDIUM: 12 | LOW: 14

Severity Rule Location
HIGH py-ssrf-outbound-request dev2/dev2-site:151
HIGH py-ssrf-outbound-request dev2/dev2-site:1060
HIGH py-ssrf-outbound-request dev2/dev2-site:1789
HIGH sh-remote-script-execution root-ubuntu.sh:3250
HIGH sh-remote-script-execution root-ubuntu.sh:3251
HIGH sh-remote-script-execution root-ubuntu.sh:5146
HIGH sh-remote-script-execution root-ubuntu.sh:5150
HIGH sh-remote-script-execution root-w3bs-os.sh:3632
HIGH sh-remote-script-execution root-w3bs-os.sh:3633
HIGH sh-remote-script-execution root-w3bs-os.sh:5558
HIGH sh-remote-script-execution root-w3bs-os.sh:5568
HIGH sh-remote-script-execution root-w3bs-os.sh:5575
HIGH sh-remote-script-execution root-w3bs-os.sh:5591
HIGH sh-remote-script-execution root-w3bs-os.sh:5596
HIGH sh-plaintext-download root-w3bs-os.sh:6278
MEDIUM sql-template-interpolation dev2/dev2-site:1286
MEDIUM sql-template-interpolation dev2/dev2-site:1363
MEDIUM sh-remote-script-execution root-ubuntu.sh:5354
MEDIUM redos-nested-quantifier src/domain-free.ts:56
MEDIUM redos-nested-quantifier src/emoji.ts:167
MEDIUM redos-nested-quantifier src/icon.ts:166
MEDIUM redos-nested-quantifier src/mail.ts:1047
MEDIUM sql-template-interpolation src/users-dump.ts:487
MEDIUM sql-string-concatenation src/users-dump.ts:507
MEDIUM sql-template-interpolation src/users-dump.ts:540
MEDIUM sql-string-concatenation src/users-dump.ts:574
MEDIUM redos-nested-quantifier src/wcag.ts:556
LOW secret-generic-credential src/credentials.ts:36
LOW secret-generic-credential src/credentials.ts:53
LOW secret-generic-credential src/credentials.ts:56
LOW secret-generic-credential src/credentials.ts:61
LOW secret-generic-credential src/user-export.ts:689
LOW secret-generic-credential src/user-export.ts:695
LOW secret-generic-api-key test/credentials.test.ts:208
LOW secret-generic-credential test/mail.test.ts:141
LOW secret-generic-credential test/proxy.test.ts:69
LOW secret-generic-credential test/proxy.test.ts:85
LOW secret-generic-credential test/shorten.test.ts:36
LOW secret-database-url test/users-dump.test.ts:108
LOW secret-database-url test/users-dump.test.ts:119
LOW secret-database-url test/users-dump.test.ts:120

Snippets are redacted; ThreatCrush never prints matched credential material.

Comment thread dev2/edge/edge-box Fixed
Comment thread dev2/edge/edge-sweep Fixed
…; route waits for the reload

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread dev2/edge/edge-box Fixed
ralyodio and others added 3 commits October 19, 2026 20:41
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ralyodio
ralyodio merged commit 6cf5154 into master Oct 19, 2026
5 checks passed
@ralyodio
ralyodio deleted the dev2-edge-caddy branch October 19, 2026 21:14
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.

2 participants