Create one self-signed certificate, print its fingerprint, and serve multiple backends through Caddy.
Platform
- Primary target: Linux/macOS shell with
bash - Caddy itself also works on Windows, but the bundled helper is bash-first
Quick scout
Check only the proxy and cert tools:
command -v openssl
command -v caddy
Workflow
- Generate a leaf cert with SANs for the actual host/IP.
- Print the SHA-256 fingerprint as the server identity.
- Start Caddy with that cert/key or add routes through the local admin API.
- Keep the admin API local only.
- Return one URL and one fingerprint.
- Validate both the certificate identity and backend reachability.
- Tell the user how to remove routes or rotate the cert.
Generate cert
openssl req -x509 -newkey rsa:2048 -noenc \
-keyout key.pem -out cert.pem -days 365 \
-subj "/CN=proxy.local" \
-addext "subjectAltName=IP:127.0.0.1,DNS:localhost"
Print identity
openssl x509 -in cert.pem -noout -fingerprint -sha256
Simple Caddyfile shape
:8443 {
tls cert.pem key.pem
handle_path /files/* {
reverse_proxy 127.0.0.1:8080
}
handle_path /app/* {
reverse_proxy 127.0.0.1:3000
}
}
Use handle_path when the upstream expects requests at /. If the upstream is path-aware already, plain handle may be fine. Say which case you are using instead of assuming subpaths will just work by magic.
Validate
curl -kI https://127.0.0.1:8443/
openssl x509 -in cert.pem -noout -fingerprint -sha256
- Open one routed path per backend and confirm assets/redirects resolve correctly.
- If clients connect by IP, confirm the cert SAN includes that IP.
- If using the admin API, confirm it only listens on localhost or another trusted local socket.
Troubleshooting
- Browser says hostname mismatch: regenerate the cert with the real DNS name or IP in SAN.
- Root page works but
/app/is broken: likely a subpath/base-path issue; usehandle_pathor configure the upstream base URL. - Admin API refused: verify Caddy admin is enabled locally and not firewalled off from localhost.
- Fingerprint changed unexpectedly: the cert was rotated or replaced; recipients must re-verify.
Cleanup / rollback
- Remove the route from Caddy or restore the previous config snapshot.
- Stop Caddy if this proxy was temporary.
- Securely keep or intentionally destroy
cert.pemandkey.pem; recreating them changes the fingerprint.
Output
Return:
- HTTPS URL
- SHA-256 fingerprint
- local listen address
- route list
- note that the fingerprint changes if the cert is regenerated
- cleanup note if the setup is temporary
Notes
- Do not expose Caddy's admin API to untrusted networks.
- The fingerprint is for that exact certificate only.
- This skill is for no-domain HTTPS, not DNS or ACME setup.
- Prefer explicit route behavior over ambiguous subpath forwarding.
Bundled helper
Use scripts/generate_selfsigned_cert.sh for the deterministic cert/fingerprint step, then keep route wiring in the main instructions.