fix(security): harden Redis auth, restrict /metrics, document Gitea port fix
Some checks failed
CI / ruff (push) Successful in 10s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / pytest (push) Has been cancelled

- Add Redis password via REDIS_PASSWORD env var (--requirepass flag)
- Update all REDIS_URL and REDIS_ADDR references to include password
- Restrict /metrics endpoint to localhost and Docker internal networks (403 for external requests)
- Document Gitea port 3000 localhost binding fix (must be applied manually on server)
- Add REDIS_PASSWORD to .env.example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 23:15:15 +01:00
parent a7392de9f6
commit b68d542258
4 changed files with 60 additions and 8 deletions

View File

@@ -1724,6 +1724,22 @@ Docker network segmentation, fail2ban configuration, and automatic security upda
| API | `"127.0.0.1:8001:8000"` | `"8001:8000"` |
| Flower | `"127.0.0.1:5555:5555"` | `"5555:5555"` |
**Gitea stack** (`~/gitea/docker-compose.yml`) also needs this fix:
```yaml
# BEFORE (vulnerable):
ports:
- "3000:3000"
- "2222:22"
# AFTER (secure):
ports:
- "127.0.0.1:3000:3000" # Caddy proxies git.wizard.lu
- "2222:22" # SSH must stay public (Caddy can't proxy SSH)
```
Port 2222 stays public because Caddy cannot proxy SSH — this is acceptable since SSH is designed for internet exposure. Port 3000 (Gitea web UI) must be localhost-only since Caddy reverse proxies `git.wizard.lu` to it.
**After deploying, verify no services are exposed:**
```bash
@@ -1732,8 +1748,31 @@ sudo ss -tlnp | grep -E '0.0.0.0:(5432|6379|6380)'
# Should show 127.0.0.1 only for app services
sudo ss -tlnp | grep -E '(8001|5555|9090|3001)'
# Gitea web UI should be localhost only, SSH stays public
sudo ss -tlnp | grep 3000 # should show 127.0.0.1
sudo ss -tlnp | grep 2222 # will show 0.0.0.0 (expected for SSH)
```
### 20.0b Redis Authentication (Defense-in-Depth)
Redis is isolated on Docker's internal network with no exposed ports, but as defense-in-depth a password is configured via the `REDIS_PASSWORD` environment variable.
Add to `~/apps/orion/.env`:
```bash
# Generate a strong password
openssl rand -hex 16
# Add to .env
REDIS_PASSWORD=<generated-password>
```
The `docker-compose.yml` passes this to `redis-server --requirepass` and includes it in all `REDIS_URL` connection strings automatically.
### 20.0c Prometheus /metrics Endpoint Restriction
The `/metrics` endpoint is restricted to localhost and Docker internal networks at the application level. External requests to `https://api.wizard.lu/metrics` receive a `403 Forbidden` response. Prometheus scrapes from the Docker monitoring network (172.x.x.x) and is unaffected.
### 20.1 Docker Network Segmentation
Three isolated networks replace the default flat network: