deploy(nginx): terminate TLS with the *.wiggleverse.org wildcard, drop per-host certbot

Restructure the ohm vhost from the pre-certbot template into an explicit
80->443 redirect + hand-managed 443 TLS block, pointed at the wildcard cert
installed on the VM (/etc/ssl/certs/wiggleverse-wildcard.crt + the key under
/etc/ssl/private). Adds modern ssl_protocols/session settings that previously
came from certbot's managed snippet. All CSP/HSTS/security headers, root, and
locations preserved verbatim. Enables flipping ohm to the Cloudflare orange
cloud (SSL mode Full strict). Cert files must be installed before reload;
retire the old cert with `certbot delete` once cut over.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ben Stull
2026-06-02 02:57:02 -07:00
parent 848de4cd8a
commit 34a65e099e
+39 -10
View File
@@ -8,24 +8,53 @@
# /etc/nginx/sites-enabled/ # /etc/nginx/sites-enabled/
# sudo nginx -t && sudo systemctl reload nginx # sudo nginx -t && sudo systemctl reload nginx
# #
# Then add the Let's Encrypt cert: # TLS: this vhost terminates with the *.wiggleverse.org wildcard cert installed
# sudo certbot --nginx -d ohm.wiggleverse.org # on the VM (see the ssl_* directives in the 443 block below). This REPLACES the
# Certbot will rewrite this file to add the 443 listener and certificate # old per-host certbot cert — the live file certbot previously rewrote on the VM
# directives; the rest of the config below stays as written. # is superseded once you install this one. Put the cert files in place first:
# sudo install -m 600 -o root -g root privkey.pem /etc/ssl/private/wiggleverse-wildcard.key
# sudo install -m 644 fullchain.pem /etc/ssl/certs/wiggleverse-wildcard.crt
# then `sudo nginx -t && sudo systemctl reload nginx`. Once cut over, retire the
# old cert: `sudo certbot delete --cert-name ohm.wiggleverse.org`.
#
# Cloudflare: with an origin wildcard in place, set SSL/TLS mode to Full (strict)
# and flip ohm to the orange cloud (proxied). If this is a Cloudflare Origin CA
# cert it ONLY validates behind the proxy — so cut the cert over and proxy in the
# same change; do not leave ohm grey-cloud with an Origin CA cert.
# HTTP → HTTPS redirect. Cloudflare also redirects at the edge once proxied, but
# keep the origin honest for direct hits.
server { server {
listen 80; listen 80;
listen [::]:80; listen [::]:80;
server_name ohm.wiggleverse.org; server_name ohm.wiggleverse.org;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ohm.wiggleverse.org;
# TLS — *.wiggleverse.org wildcard installed on the VM (see top comment).
# These files must exist before `nginx -t` / reload, or nginx fails to start.
ssl_certificate /etc/ssl/certs/wiggleverse-wildcard.crt;
ssl_certificate_key /etc/ssl/private/wiggleverse-wildcard.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSLwiggle:10m;
ssl_session_timeout 1d;
# NOTE: once proxied behind Cloudflare, $remote_addr is a Cloudflare edge IP.
# To restore the real client IP (for logging / Turnstile / rate limits), add a
# real_ip block (set_real_ip_from <CF ranges>; real_ip_header CF-Connecting-IP;).
# Left out here to avoid baking stale CF ranges into the repo — see follow-up.
# v0.25.0 security hardening (audit 0026 M2/L8) # v0.25.0 security hardening (audit 0026 M2/L8)
# #
# NOTE: certbot promotes THIS server block to the HTTPS listener # NOTE: these response headers live in the HTTPS (443) server block. They use
# (`listen 443 ssl`) and adds a separate port-80 → 443 redirect # `add_header ... always` so they also apply to nginx-generated error
# block (see the install comment above). These response headers # responses (4xx/5xx), not just 200s.
# therefore ride into the HTTPS server block on the VM. They use
# `add_header ... always` so they also apply to nginx-generated
# error responses (4xx/5xx), not just 200s.
# #
# `server_tokens off` (L8) — suppress the nginx version in the # `server_tokens off` (L8) — suppress the nginx version in the
# Server header and on error pages so we don't advertise the # Server header and on error pages so we don't advertise the