Add homelab services stack PRD
Verifies 16 DockerHub images, assigns target nodes per locked policy, defines 3-phase deployment order (Infra → Media → Polish), and captures open questions for Bobby. Services: Traefik, Technitium DNS, AdGuard Home, Prometheus, Grafana, Beszel, Dozzle, Portainer, Homepage, Authelia, Vaultwarden, Jellyfin, Sonarr, Radarr, Prowlarr, Nextcloud Domain: *.ai.home No public internet exposure.
This commit is contained in:
48
plans/07-security-model.md
Normal file
48
plans/07-security-model.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Iron Legion Homelab Services Stack — Security Model
|
||||
|
||||
## Authentication Layers
|
||||
| Layer | Service | Scope | Notes |
|
||||
|-------|---------|-------|-------|
|
||||
| **Edge Auth** | Authelia | Traefik-secured endpoints | MFA portal, session cookies |
|
||||
| **App Auth** | Vaultwarden | Password vault | Master password + 2FA |
|
||||
| **App Auth** | Portainer | Container mgmt | Built-in RBAC, can integrate LDAP |
|
||||
| **App Auth** | Nextcloud | File collaboration | Built-in, can integrate Authelia OIDC |
|
||||
| **OS Auth** | SSH keys | Node access | Tailscale SSH + local keypairs |
|
||||
|
||||
## Authelia Deployment Notes
|
||||
- **Target node:** Mark5 (lightweight, sits beside Traefik)
|
||||
- **Redirection URL:** Set Authelia `redirection_url` to the base domain of services needing auth.
|
||||
- **Backend storage:** Uses SQLite initially. If Bobby wants HA, migrate to PostgreSQL on Bones.
|
||||
- **Notification method:** File-based (writes to `/opt/iron-legion/authelia/notifications/`) until SMTP/Discord is configured.
|
||||
- **Rule granularity:** Per-service `access_control` rules in `configuration.yml`. Default: `one_factor` for internal services, `two_factor` for management interfaces (Portainer, Grafana admin).
|
||||
|
||||
## Traefik ↔ Authelia Integration
|
||||
```yaml
|
||||
# Traefik middleware label (example)
|
||||
traefik.http.routers.portainer.middlewares: authelia@docker
|
||||
traefik.http.middlewares.authelia.forwardauth.address: http://authelia:9091/api/verify?rd=https://auth.labs.internal
|
||||
```
|
||||
- **No nginx.** ForwardAuth middleware talks directly to Authelia over internal Docker network.
|
||||
- **Bypass list:** Prometheus scrape targets, Beszel agents, Technitium DNS queries — these are internal metrics/DNS, no auth required.
|
||||
|
||||
## Secret Handling
|
||||
| Secret Type | Storage Method | Rotation Trigger |
|
||||
|-------------|----------------|------------------|
|
||||
| Authelia session secret | `.env` file, 64-byte random hex | On any Authelia config reload |
|
||||
| Vaultwarden admin token | `.env` file, 48-byte random | Only on compromise |
|
||||
| DB passwords (Nextcloud ↔ PostgreSQL) | `.env` files on both nodes | On any DB migration or rebuild |
|
||||
| Tailscale auth keys | Vaultwarden secure note | On key expiry or node rebuild |
|
||||
| API keys (indexers, Cloudflare) | Vaultwarden secure note | On key rotation by provider |
|
||||
|
||||
## Network Segmentation
|
||||
- **No VLANs.** Tailscale ACLs handle segment isolation.
|
||||
- **ACL policy (draft):**
|
||||
- `tag:admin` nodes (Bobby, Artemis) → all ports on all nodes
|
||||
- `tag:services` (Neo, Bones, Mark44, Mark5) → only their assigned service ports, no cross-node SSH except via Tailscale SSH
|
||||
- `tag:user` (Bobby's phone, laptop) → HTTPS 443 on Mark5 only, Jellyfin 8096 on Mark44 directly
|
||||
- **Default deny.** Any traffic not explicitly allowed in Tailscale ACL is dropped.
|
||||
|
||||
## Monitoring for Security Events
|
||||
- **Dozzle** provides real-time log viewing but is NOT a SIEM.
|
||||
- **Promtail/Loki** not yet in catalog. If Bobby wants log aggregation + alerting, add to Phase 3.
|
||||
- **Beszel** alerts on anomalous CPU/memory — use as coarse intrusion detection proxy.
|
||||
Reference in New Issue
Block a user