Skip to content

feat(caddy): respond to load-balanced pronode.prosopo.io alongside per-host#2670

Open
forgetso wants to merge 1 commit into
mainfrom
feat/caddy-global-domain
Open

feat(caddy): respond to load-balanced pronode.prosopo.io alongside per-host#2670
forgetso wants to merge 1 commit into
mainfrom
feat/caddy-global-domain

Conversation

@forgetso

Copy link
Copy Markdown
Member

Summary

  • Extracts the existing route/handler block in docker/provider.Caddyfile into a (provider_site) snippet imported by two site blocks
  • {$CADDY_DOMAIN} (pronodeN.prosopo.io) keeps ACME HTTP-01 — works because each pronode's A record points to one IP
  • Adds {$CADDY_GLOBAL_DOMAIN} (pronode.prosopo.io) with tls internal as a placeholder cert. DNS round-robins this hostname across all pronodes, which breaks HTTP-01 per-node renewal; the real cert strategy (shared storage, DNS-01, or pre-provisioned PEM) is intentionally a follow-up
  • The layer4 :443 SNI router needs no change — its matcher only catches *.t.{$CADDY_DOMAIN} for the dns-trap subzone, so both the per-host and load-balanced hostnames fall through to the default 127.0.0.1:8443 upstream where Caddy now multiplexes by SNI

Why this PR

First step toward DNS-based provider load balancing: caddy needs to terminate TLS on pronode.prosopo.io so the frontend can do an initial round-robin hop before redirecting to a specific pronodeN.prosopo.io for the rest of the flow. Cert distribution for the shared hostname is a separate problem and is left as a deliberate placeholder.

Test plan

  • Deploy to a staging pronode with CADDY_GLOBAL_DOMAIN=staging.pronode.prosopo.io set in env
  • openssl s_client -connect <pronodeN>:443 -servername pronodeN.prosopo.io → real Let's Encrypt cert
  • openssl s_client -connect <pronodeN>:443 -servername staging.pronode.prosopo.io → Caddy-CA self-signed cert (expected placeholder)
  • Same route { } (rate limits, header_up reverse proxy, metrics, robots.txt) is served on both hostnames

🤖 Generated with Claude Code

…r-host

Extracts the existing route/handler block into a `(provider_site)` snippet
imported by two site blocks:

- `{$CADDY_DOMAIN}` (pronodeN.prosopo.io) keeps ACME HTTP-01 auto-HTTPS —
  it works because each pronode's A record points to one IP.
- `{$CADDY_GLOBAL_DOMAIN}` (pronode.prosopo.io) uses `tls internal` as a
  placeholder cert. DNS round-robins this hostname across all pronodes so
  HTTP-01 challenges land on whichever node DNS hands out, breaking
  per-node renewal. The real cert strategy (shared storage, DNS-01, or
  pre-provisioned PEM) is intentionally deferred to a follow-up.

The layer4 :443 router needs no change — its SNI matcher only catches the
`*.t.{$CADDY_DOMAIN}` dns-trap subzone; pronode.prosopo.io and
pronodeN.prosopo.io both fall through to the default 127.0.0.1:8443
upstream, where Caddy now multiplexes by SNI between the two site blocks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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