- Add PHP ini management classes (Access, IniDirective, IniKey, PhpIni) - Update deployment configurations (Wireguard, Traefik, Monitoring) - Add DNS stack and Ansible role - Add deployment debugging playbooks - Update framework components (FilePath, RedisConnectionPool) - Update .gitignore and documentation
7.4 KiB
WireGuard - Zukünftige Sicherheitshärtung
Status: 📋 Geplant
Aktueller Status: Alle Dienste öffentlich erreichbar
Ziel: Backend-Dienste nur noch über VPN erreichbar
Übersicht
Dieses Dokument beschreibt die geplante Sicherheitshärtung für Backend-Dienste, sodass diese nur noch über WireGuard VPN erreichbar sind.
Aktueller Zustand:
- ✅ WireGuard VPN ist installiert und funktionsfähig
- ✅ Traefik-Dashboard ist jetzt VPN-only (nur über WireGuard erreichbar)
- ✅ Grafana ist VPN-only (nur über WireGuard erreichbar)
- ✅ Andere Backend-Dienste sind noch öffentlich über Traefik erreichbar
- ✅ VPN-Zugriff funktioniert parallel
Zielzustand:
- 🔒 Backend-Dienste nur noch über VPN erreichbar
- 🔒 Öffentlicher Zugriff auf Prometheus, Grafana, Portainer blockiert
- 🔒 SSH-Zugriff weiterhin über normale IP möglich
Betroffene Dienste
Folgende Dienste sollen später nur noch über VPN erreichbar sein:
-
Prometheus (Port 9090)
- Aktuell:
http://prometheus.michaelschiemer.de(öffentlich) - Zukünftig: Nur
http://10.8.0.1:9090über VPN
- Aktuell:
-
Grafana (Port 3000)
- Aktuell:
https://grafana.michaelschiemer.de(öffentlich) - Zukünftig: Nur
http://10.8.0.1:3000über VPN
- Aktuell:
-
Portainer (Port 9443)
- Aktuell:
https://portainer.michaelschiemer.de(öffentlich) - Zukünftig: Nur
https://10.8.0.1:9443über VPN
- Aktuell:
Aktuell implementiert: VPN-only Services
Traefik-Dashboard
- ✅ Realisiert über Traefik-IP-Whitelist (
vpn-onlyMiddleware) - ✅ Zusätzlich durch BasicAuth geschützt
- ✅ Whitelist umfasst standardmäßig ausschließlich das WireGuard-Netz
10.8.0.0/24 - ✅ Öffentlicher Zugriff ist blockiert (403 Forbidden)
Grafana
- ✅ Realisiert über Traefik-IP-Whitelist (
grafana-vpn-onlyMiddleware) - ✅ Whitelist umfasst standardmäßig ausschließlich das WireGuard-Netz
10.8.0.0/24 - ✅ Anpassung via Ansible-Extra-Var
monitoring_vpn_ip_whitelist_rangesmöglich (falls weitere Netze freigeschaltet werden sollen) - ✅ CoreDNS-Override aktiv, damit
grafana.michaelschiemer.deim VPN auf10.8.0.1zeigt
Rollout-Schritte
- Neue Stacks auf den Server syncen:
ansible-playbook -i inventory/production.yml playbooks/sync-stacks.yml - Monitoring-Rolle komplett laufen lassen (die
.envmuss generiert werden):
ansible-playbook -i inventory/production.yml playbooks/setup-infrastructure.yml --tags monitoring - Prüfen, dass
monitoring_stack_changedin der Zusammenfassungtrueist oder der Grafana-Container neu gestartet wurde
Verifikation
- Ohne VPN (öffentliche IP):
curl -I https://grafana.michaelschiemer.de→403 Forbidden - Mit WireGuard (
10.8.0.xClient): Grafana im Browser laden, Login funktioniert - Optional: Traefik-Logs prüfen (
docker compose -f ~/deployment/stacks/traefik/docker-compose.yml logs -f traefik) für geblockte IPs - DNS-Check im VPN:
dig grafana.michaelschiemer.de @10.8.0.1→10.8.0.1 - WireGuard-Client bekommt automatisch
DNS = 10.8.0.1, solangewireguard_dns_serversnicht überschrieben wird (ansonsten manuell auf internen Resolver setzen)
Geplante Implementierungsschritte
Schritt 1: Traefik-Labels anpassen
Datei: deployment/stacks/monitoring/docker-compose.yml
Traefik-Router für interne Dienste entfernen oder anpassen:
# Entfernen/Anpassen der öffentlichen Traefik-Labels:
labels:
# - "traefik.enable=true"
# - Orchestra: "traefik.http.routers.prometheus.rule=Host(`prometheus.${DOMAIN}`)"
# - Orchestra: "traefik.http.routers.grafana.rule=Host(`grafana.${DOMAIN}`)"
# - Orchestra: "traefik.http.routers.portainer.rule=Host(`portainer.${DOMAIN}`)"
Schritt 2: Firewall-Regeln anpassen
Option A: UFW-Regeln
# Öffentliche Ports für Monitoring blockieren
sudo ufw deny 9090/tcp # Prometheus
sudo ufw deny 3000/tcp # Grafana
sudo ufw deny 9443/tcp # Portainer
# VPN-Zugriff explizit erlauben (falls notwendig)
sudo ufw allow from 10.8.0.0/24 to any port 9090
sudo ufw allow from 10.8.0.0/24 to any port 3000
sudo ufw allow from 10.8.0.0/24 to any port 9443
Option B: Traefik Middleware
Traefik-Middleware erstellen, die nur VPN-IPs erlaubt:
labels:
- "traefik.http.middlewares.vpn-only.ipwhitelist.sourcerange=10.8.0.0/24"
- "traefik.http.routers.prometheus.middlewares=vpn-only"
Schritt 3: Docker-Netzwerk-Konfiguration
Datei: deployment/stacks/monitoring/docker-compose.yml
Dienste nur auf app-internal Netzwerk belassen, nicht auf traefik-public:
services:
prometheus:
networks:
- app-internal # Nur internes Netzwerk
# - traefik-public # Entfernen
grafana:
networks:
- app-internal
# - traefik-public
portainer:
networks:
- app-internal
# - traefik-public
Schritt 4: Nginx/Traefik-Konfiguration
Traefik-Router entfernen, sodass die Dienste nicht mehr öffentlich erreichbar sind.
Testplan
Vor der Umsetzung
- ✅ VPN-Verbindung testen
- ✅ Zugriff auf Dienste über VPN testen (10.8.0.1: term
- ✅ Öffentliche URLs dokumentieren (für späteren Vergleich)
Nach der Umsetzung
- ✅ Öffentliche URLs sollten nicht mehr erreichbar sein (404/Connection refused)
- ✅ VPN-Zugriff sollte weiterhin funktionieren
- ✅ SSH-Zugriff über normale IP sollte weiterhin funktionieren
- ✅ Hauptanwendung (michaelschiemer.de) sollte weiterhin öffentlich erreichbar sein
Rollback-Plan
Falls Probleme auftreten:
- Traefik-Labels wieder aktivieren
- Firewall-Regeln zurücksetzen:
sudo ufw delete deny 9090/tcp sudo ufw delete deny 3000/tcp sudo ufw delete deny 9443/tcp - Docker-Container neu starten:
cd deployment/stacks/monitoring docker compose up -d
Zeitplan
Nicht geplant für sofortige Umsetzung
Die Härtung kann durchgeführt werden, wenn:
- ✅ WireGuard-VPN stabil läuft
- ✅ Alle notwendigen Clients push
- Optional: Monitoring-Alerts für VPN-Verbindungen
- Optional: Automatische Firewall-Regeln via Ansible
Weitere Überlegungen
Alternative: Traefik mit VPN-IP-Whitelist
Statt die Dienste komplett aus Traefik zu entfernen, könnte eine Middleware verwendet werden:
# Traefik-Middleware für VPN-only
- "traefik.http.middlewares.vpn-only.ipwhitelist.sourcerange=10.8.0.0/24"
- "traefik.http.routers.prometheus.middlewares=vpn-only"
Vorteil: Konfiguration bleibt in Traefik, einfaches Toggle
Nachteil: Traefik muss weiterhin die Requests verarbeiten
Alternative: Separates Traefik-Instance für VPN
Ein separater Traefik-Container nur für VPN-Dienste:
services:
traefik-vpn:
image: traefik:v3.0
networks:
- app-internal
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
- "--api.insecure=false"
- "--providers.docker.network=app-internal"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
Vorteil: Komplette Trennung von öffentlichen und VPN-Diensten
Nachteil: Zusätzliche Ressourcen, komplexere Konfiguration
Dokumentation
Nach der Umsetzung sollte aktualisiert werden:
WIREGUARD-SETUP.md- Status aktualisierenproduction-deployment-guide.md- Firewall-Konfiguration dokumentierenREADME.md- Hinweise auf VPN-only-Zugriff
Hinweis: Diese Härtung wird erst durchgeführt, wenn das VPN stabil läuft und alle notwendigen Clients konfiguriert sind.