Traefik Reverse Proxy¶
Traefik handles all HTTP/HTTPS traffic, TLS termination, and routing to backend services.
Configuration¶
Static Config (traefik.yml)¶
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: admin@clsxx.de
storage: /acme.json
httpChallenge:
entryPoint: web
providers:
docker:
exposedByDefault: false
file:
directory: /dynamic
watch: true
api:
dashboard: true
Dynamic Config (middlewares.yml)¶
http:
middlewares:
auth:
basicAuth:
users:
- "admin:$apr1$..."
vpn-only:
ipAllowList:
sourceRange:
- "10.0.0.0/24"
- "10.0.1.0/24"
- "192.168.10.0/24"
Routes¶
Static Routes (Docker labels)¶
| Domain | Service | Auth |
|---|---|---|
traefik.clsxx.de |
Traefik Dashboard | BasicAuth + VPN |
pihole.clsxx.de |
Pi-hole Dashboard | BasicAuth + VPN |
fail2ban.clsxx.de |
Fail2ban Dashboard | BasicAuth + VPN |
firewall.clsxx.de |
Control Center | BasicAuth + VPN |
docs.clsxx.de |
Documentation | BasicAuth + VPN |
Dynamic Routes (vm-services.yml)¶
VM web services managed by the Control Center. These are written to /dynamic/vm-services.yml and auto-detected by Traefik's file watcher.
| Domain | Service | Middleware | Access |
|---|---|---|---|
trading.clsxx.de |
Trading UI (:5173) | secure-admin |
VPN + BasicAuth |
trading-api.clsxx.de |
Trading API (:8000) | secure-admin |
VPN + BasicAuth |
trading-flower.clsxx.de |
Celery Flower (:5555) | secure-admin |
VPN + BasicAuth |
cloud.clsxx.de |
Nextcloud (:8880) | secure-admin |
VPN + BasicAuth |
git.clsxx.de |
Gitea (:3000) | secure-admin |
VPN + BasicAuth |
mail.clsxx.de |
Webmail / Rainloop (:8888) | secure-admin |
VPN + BasicAuth |
portainer.clsxx.de |
Portainer (:9000) | secure-admin |
VPN + BasicAuth |
parts.clsxx.de |
Part Finder (:8090) | secure-admin |
VPN + BasicAuth |
dashboard.clsxx.de |
CLSXX Dashboard (:8091) | secure-admin |
VPN + BasicAuth |
dashboard.clsxx.de/api/* |
Dashboard API (:8091) | secure-api |
VPN-only (no auth) |
tickets.clsxx.de/api/* |
Tickets API (:8091) | secure-api |
VPN-only (no auth) |
TLS¶
All HTTPS uses Let's Encrypt certificates via the HTTP-01 challenge:
- Traefik requests a certificate for the domain
- Let's Encrypt sends an HTTP challenge to port 80
- Traefik responds automatically
- Certificate is stored in
acme.json - Auto-renewal before expiry
Access Control¶
Admin dashboards use a multi-layer access control via named middleware chains:
| Middleware | Components | Used For |
|---|---|---|
secure-admin |
VPN whitelist + rate limit + security headers + BasicAuth | VPN-only services (default) |
secure-api |
VPN whitelist + rate limit + security headers (no BasicAuth) | API paths for programmatic access (AI agents) |
auth |
BasicAuth only | Public services requiring login |
vpn-whitelist |
VPN IP whitelist only | VPN-only services without BasicAuth |
The secure-admin chain provides the highest security:
- VPN IP Whitelist — Only VPN subnets (10.0.0.0/24, 10.0.1.0/24, 10.0.3.0/24, 192.168.10.0/24, 172.20.10.0/24) can reach the service
- Rate Limiting — 50 req/s with burst of 100
- Security Headers — HSTS, XSS protection, frame-deny, referrer policy
- BasicAuth — Username/password required
This means even if someone discovers the domain, they cannot access it without both VPN and credentials.