# 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:

1. **Prometheus** (Port 9090)
   - Aktuell: `http://prometheus.michaelschiemer.de` (öffentlich)
   - Zukünftig: Nur `http://10.8.0.1:9090` über VPN

2. **Grafana** (Port 3000)
   - Aktuell: `https://grafana.michaelschiemer.de` (öffentlich)
   - Zukünftig: Nur `http://10.8.0.1:3000` über VPN

3. **Portainer** (Port 9443)
   - Aktuell: `https://portainer.michaelschiemer.de` (öffentlich)
   - Zukünftig: Nur `https://10.8.0.1:9443` über VPN

## Aktuell implementiert: VPN-only Services

### Traefik-Dashboard
- ✅ Realisiert über Traefik-IP-Whitelist (`vpn-only` Middleware)
- ✅ 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-only` Middleware)
- ✅ Whitelist umfasst standardmäßig ausschließlich das WireGuard-Netz `10.8.0.0/24`
- ✅ Anpassung via Ansible-Extra-Var `monitoring_vpn_ip_whitelist_ranges` möglich (falls weitere Netze freigeschaltet werden sollen)
- ✅ CoreDNS-Override aktiv, damit `grafana.michaelschiemer.de` im VPN auf `10.8.0.1` zeigt

### Rollout-Schritte
1. Neue Stacks auf den Server syncen: \
   `ansible-playbook -i inventory/production.yml playbooks/sync-stacks.yml`
2. Monitoring-Rolle komplett laufen lassen (die `.env` muss generiert werden): \
   `ansible-playbook -i inventory/production.yml playbooks/setup-infrastructure.yml --tags monitoring`
3. Prüfen, dass `monitoring_stack_changed` in der Zusammenfassung `true` ist 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.x` Client): 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`, solange `wireguard_dns_servers` nicht ü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:

```yaml
# 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**

```bash
# Ö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:

```yaml
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`:

```yaml
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

1. ✅ VPN-Verbindung testen
2. ✅ Zugriff auf Dienste über VPN testen (10.8.0.1: term
3. ✅ Öffentliche URLs dokumentieren (für späteren Vergleich)

### Nach der Umsetzung

1. ✅ Öffentliche URLs sollten nicht mehr erreichbar sein (404/Connection refused)
2. ✅ VPN-Zugriff sollte weiterhin funktionieren
3. ✅ SSH-Zugriff über normale IP sollte weiterhin funktionieren
4. ✅ Hauptanwendung (michaelschiemer.de) sollte weiterhin öffentlich erreichbar sein

---

## Rollback-Plan

Falls Probleme auftreten:

1. Traefik-Labels wieder aktivieren
2. Firewall-Regeln zurücksetzen:
   ```bash
   sudo ufw delete deny 9090/tcp
   sudo ufw delete deny 3000/tcp
   sudo ufw delete deny 9443/tcp
   ```
3. Docker-Container neu starten:
   ```bash
   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
4. **Optional**: Monitoring-Alerts für VPN-Verbindungen
5. **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:

```yaml
# 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:

```yaml
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:

1. `WIREGUARD-SETUP.md` - Status aktualisieren
2. `production-deployment-guide.md` - Firewall-Konfiguration dokumentieren
3. `README.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.
