Files
jbergner 7c69432097
release-tag / release-image (push) Successful in 2m3s
release-main / release-images (push) Failing after 3m9s
RC-2 0.5.2
2026-08-24 05:46:42 +02:00

75 lines
2.9 KiB
Markdown

# SessionGuard Public VPS: Caddy + NetBird + EdgeGuard
This stack keeps public TLS termination and Guacamole load balancing on Caddy,
uses NetBird only as the encrypted backend transport, and inserts SessionGuard
EdgeGuard as a localhost-only request pre-check.
## Data path
```text
Internet
-> Caddy :443 (TLS, SNI, security headers, sticky load balancing)
-> EdgeGuard 127.0.0.1:9081 /check
-> SessionGuard Access Auth over NetBird
-> Guacamole worker over NetBird
```
EdgeGuard is not in the Guacamole tunnel after the WebSocket connection has
been established. It evaluates normal HTTP requests and the WebSocket handshake.
## What EdgeGuard enforces
- static IPv4/IPv6 IP/CIDR blacklist;
- global request rate limit to protect backends during distributed HTTP floods;
- high per-IP request rate limit (NAT-friendly defaults);
- tighter, configurable limits for OIDC/login/callback paths;
- scanner-path blocking (`/.env`, `/.git`, WordPress/phpMyAdmin probes, etc.);
- blocks CONNECT/TRACE/TRACK;
- temporary persistent bans for clearly hostile scanner/method behavior;
- host allowlist and URI-length validation;
- localhost-only health and Prometheus-style metrics endpoints;
- automatic config/list reload (15 seconds by default);
- bounded per-IP state (100,000 entries by default) to avoid memory exhaustion from rotating source addresses.
The default `rate_limit_weight` for auto-ban is zero on purpose: legitimate
users behind a shared NAT should receive 429 during extreme bursts, but should
not cause the whole NAT address to be banned. Scanner probes are weighted much
more strongly and are auto-banned after repeated hits.
## Caddy hardening
The supplied Caddyfile additionally enables:
- strict SNI/Host matching;
- 10 second request-header timeout;
- 64 KiB maximum request headers;
- HTTP/1.1 + HTTP/2 only (HTTP/3 disabled to reduce exposed protocol surface);
- HSTS and conservative security headers;
- public blocking of SessionGuard `/metrics` and `/api/v1/broker/*`;
- rotated JSON access logs with sampling during request floods;
- Caddy admin API disabled (`admin off`); configuration changes use a container restart.
## Installation
1. Copy `.env.example` to `.env` and set all values.
2. Adjust `edgeguard.json` host names if needed.
3. Add permanent abusive IPs/CIDRs to `blacklist.txt`.
4. Keep `rate-exempt.txt` empty unless you have a known large NAT that really
needs exemption from per-IP limits.
5. Start with `docker compose up -d`.
6. Verify:
```bash
curl -fsS http://127.0.0.1:9081/healthz -o /dev/null
curl -fsS http://127.0.0.1:9081/metrics
curl -I https://ts.hilden.info/
```
## Important DDoS boundary
EdgeGuard protects the application/backends against HTTP request floods and
common low-cost scanners. It cannot protect a single VPS if the Internet link
or provider edge is saturated. Keep the VPS provider's network firewall and
DDoS protection enabled. For a volumetric attack, filtering must happen before
traffic reaches the VPS.