docs/deployment: record security hardening pass + webapp + APNs
Mark roadmap items done (network policies, Traefik middleware, CF Full strict, CF IP UFW restriction, webapp deploy, APNs wired up, admin URL-baking fix, admin probe bug). Update Chapter 4 (firewall rule inventory now shows CF-only :443, no :80), Chapter 6 (request flow walks through TLS on :443 and middleware hops), Chapter 13 (CF SSL mode is Full strict, not Flexible; documents the origin cert install), Chapter 7 (adds the web service section — proxy pattern, 3 replicas, PostHog build-args), and Appendix C (web manifests, CF origin cert paths on disk, APNs .p8 path, updated network-policies applied status). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,23 +27,27 @@ that every legitimate port be enumerated in a rule.
|
||||
Run `sudo ufw status verbose` on any node to see the live ruleset. The
|
||||
canonical ruleset below, grouped by purpose.
|
||||
|
||||
### Public-facing (anywhere)
|
||||
### Public-facing
|
||||
|
||||
| Port | Protocol | From | Purpose | Comment |
|
||||
|---|---|---|---|---|
|
||||
| 22 | TCP | Anywhere | SSH | |
|
||||
| 80 | TCP | Anywhere | HTTP (Cloudflare → Traefik) | |
|
||||
| 443 | TCP | Anywhere | HTTPS (future, currently unused at origin) | |
|
||||
| Port | Protocol | From | Purpose |
|
||||
|---|---|---|---|
|
||||
| 22 | TCP | Anywhere | SSH (key-only) |
|
||||
| 443 | TCP | Cloudflare ranges (15 IPv4 + 7 IPv6) | HTTPS (CF → Traefik, TLS-terminated at Traefik) |
|
||||
|
||||
**Why 443 is open but unused**: We're on Cloudflare SSL=Flexible, so
|
||||
Cloudflare talks to origin over plain HTTP:80. Port 443 on origin is
|
||||
only hit by misconfigured clients (who bypass CF DNS and hit node IPs
|
||||
directly). Traefik's config accepts it but we don't require it. Keeping
|
||||
it open smooths a future switch to Full (strict) SSL mode.
|
||||
**Port :80 is closed** on all three nodes. CF is in Full (strict) mode
|
||||
and initiates every request on :443 to the origin. Cloudflare's
|
||||
"Always Use HTTPS" turns any plaintext client request into HTTPS at
|
||||
the edge, so the origin never needs to accept :80.
|
||||
|
||||
**Future hardening**: Restrict 80 and 443 to Cloudflare's published IP
|
||||
ranges (15 IPv4 CIDRs, 7 IPv6 CIDRs). See [Chapter 13](./13-cloudflare.md)
|
||||
for the ranges and the UFW rule format. Today they're open to anyone.
|
||||
**Port :443 is restricted to Cloudflare** via 22 UFW allow rules per
|
||||
node (one per CF CIDR). Direct-connect from any non-CF IP is dropped
|
||||
at the kernel. This closes the "node IP leak = bypass CF WAF/DDoS"
|
||||
hole entirely. See [Chapter 13](./13-cloudflare.md#cloudflare-ip-ranges-used-in-traefik-trustedips)
|
||||
for the exact ranges and UFW rule format.
|
||||
|
||||
**Refresh cadence**: CF updates its IP ranges rarely. A monthly
|
||||
`curl https://www.cloudflare.com/ips-v4` diff and UFW re-apply is
|
||||
enough. Automation TODO (Chapter 20).
|
||||
|
||||
### SSH (operator access)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user