openvpn-endpoint-server/README.md

779 lines
22 KiB
Markdown

# mGuard VPN Endpoint Server
VPN-Management-System für Phoenix Contact mGuard Router mit Web-Oberfläche.
## Übersicht
Dieses System ermöglicht die zentrale Verwaltung von mGuard VPN-Gateways und den sicheren Fernzugriff auf Endpunkte (SPS, HMI, etc.) hinter diesen Gateways.
### Komponenten
| Komponente | Beschreibung |
|------------|--------------|
| **Server + Web-UI** | Docker-basiert mit FastAPI, MariaDB, OpenVPN und Web-Dashboard |
| **Desktop Client** | PyQt6 GUI-Anwendung für Techniker (Windows/Linux) |
| **Provisioning Tool** | CLI-Tool für Gateway-Provisionierung |
### Unterstützte Router
| Router | Firmware | Provisionierung |
|--------|----------|-----------------|
| FL MGUARD 2000/4000 | 10.5.x | REST API |
| FL MGUARD RS4000 | 8.9 | SSH / ATV-Datei |
| FL MGUARD 1000 | 1.x | REST API |
---
## Architektur
```
┌────────────────────────────────────────────────────────────────────────────┐
│ DOCKER COMPOSE STACK │
│ │
│ ┌──────────────────────┐ ┌───────────────────────┐ │
│ │ FastAPI Server │ │ MariaDB │ │
│ │ :8000 │ │ :3306 │ │
│ │ ├── REST API │ │ │ │
│ │ ├── Web UI (HTMX) │ │ ├── CAs │ │
│ │ └── PKI-Verwaltung │ │ ├── VPN Servers │ │
│ └──────────┬───────────┘ │ ├── VPN Profiles │ │
│ │ │ ├── Gateways │ │
│ └──────────────┴──┴── Users │ │
└─────────────────────────────────────────────────────────────────────────────┘
Interne API (localhost)
┌─────────────────────────────────────────────────────────────────────────────┐
│ OpenVPN Container (Host-Netzwerk) │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ supervisord │ │
│ │ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ │
│ │ │ openvpn-1 │ │ openvpn-2 │ │ openvpn-N │ │ │
│ │ │ UDP:1194 │ │ TCP:443 │ │ UDP:1195 │ │ │
│ │ │ (Produktion) │ │ (Firewall) │ │ (Backup) │ │ │
│ │ └────────────────┘ └────────────────┘ └────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ Polling alle 30s: Neue Server automatisch starten/stoppen │
└─────────────────────────────────────────────────────────────────────────────┘
Host-Ports direkt (kein Docker NAT)
┌─────────────┴─────────────┐
▼ ▼
┌───────────────────┐ ┌─────────────────┐
│ mGuard Gateway │ │ Web Browser │
│ (beim Kunden) │ │ (Admin) │
└───────────────────┘ └─────────────────┘
```
### Multi-Server Architektur
Der OpenVPN-Container verwaltet **automatisch mehrere VPN-Server-Instanzen**:
- Läuft im **Host-Netzwerk-Modus** für direkte Port-Bindung
- Verwendet **supervisord** für Prozess-Management
- **Pollt alle 30 Sekunden** die API für neue/geänderte Server
- **Keine docker-compose.yml Änderungen** nötig beim Hinzufügen neuer VPN-Server!
```
Datenbank OpenVPN Container
┌─────────────────────┐ ┌─────────────────────┐
│ VPN-Server │ │ supervisord │
│ ├── ID: 1 (aktiv) │ ──Poll──▶ │ ├── openvpn-1 │
│ ├── ID: 2 (aktiv) │ │ ├── openvpn-2 │
│ └── ID: 3 (inaktiv)│ │ └── (kein 3) │
└─────────────────────┘ └─────────────────────┘
```
### PKI-Verwaltung über Web-UI
Die gesamte PKI (Zertifizierungsstellen, Zertifikate, VPN-Server) wird über die Web-Oberfläche verwaltet:
| Bereich | Beschreibung |
|---------|--------------
| **Zertifizierungsstellen (CA)** | Eigene CA erstellen oder importieren |
| **VPN-Server** | Mehrere Server mit unterschiedlichen Ports/Protokollen |
| **VPN-Profile** | Pro Gateway mehrere Profile für Failover/Migration |
---
## Schnellstart
### Voraussetzungen
- Docker & Docker Compose
- Mindestens 2 GB RAM für die Container
- Port 8000 (Web/API) und gewünschte VPN-Ports frei
### 1. Installation
```bash
# Repository klonen oder Dateien kopieren
cd endpoint-server-openvpn
# Konfiguration erstellen
cp .env.example .env
# .env bearbeiten und Passwörter anpassen!
nano .env
```
### 2. Container starten
```bash
# Container bauen und starten
docker-compose up -d
# Logs prüfen
docker-compose logs -f
```
### 3. Ersteinrichtung (Web-UI)
Nach dem Start unter **http://localhost:8000/** einloggen.
Standard-Login:
- **Benutzername:** `admin`
- **Passwort:** `changeme` (in .env ändern!)
#### Schritt 1: CA erstellen
1. Navigation: **VPN → Zertifizierungsstellen**
2. **Neue CA erstellen** klicken
3. Formular ausfüllen:
- Name: z.B. "Produktion CA"
- Organisation, Land, Stadt
- Schlüsselgröße: 4096 (empfohlen) oder 2048
- Gültigkeit: 3650 Tage (10 Jahre)
4. **Erstellen** - DH-Parameter werden im Hintergrund generiert
#### Schritt 2: VPN-Server erstellen
1. Navigation: **VPN → VPN-Server**
2. **Neuer VPN-Server** klicken
3. Formular ausfüllen:
- Name: z.B. "Produktion UDP"
- CA auswählen (aus Schritt 1)
- Hostname: Öffentliche IP oder Domain
- Port: 1194
- Protokoll: UDP (empfohlen) oder TCP
4. **Erstellen** - Server-Zertifikat wird automatisch generiert
#### Schritt 3: Automatischer Start
Der OpenVPN-Container erkennt neue Server automatisch (Polling alle 30s):
```bash
# Logs prüfen - Server sollte automatisch starten
docker-compose logs -f openvpn
# Ausgabe sollte zeigen:
# [2024-01-15 10:30:00] New server detected: 1
# [2024-01-15 10:30:00] Setting up server 1 (Produktion UDP) on port 1194/udp
# [2024-01-15 10:30:01] Server 1 configured successfully
```
**Kein Container-Neustart nötig!**
---
## Mehrere VPN-Server betreiben
### Automatische Verwaltung
Einfach weitere VPN-Server über die Web-UI erstellen:
| Server | Port | Protokoll | Verwendung |
|--------|------|-----------|------------|
| Produktion UDP | 1194 | UDP | Standard, schnell |
| Produktion TCP | 443 | TCP | Firewall-Bypass |
| Backup | 1195 | UDP | Fallback-Server |
Der Container startet diese automatisch - **keine Konfigurationsänderungen nötig!**
### Firewall-Regeln
Da der Container im Host-Netzwerk läuft, müssen die VPN-Ports auf dem Host freigegeben sein:
```bash
# Beispiel für iptables
sudo iptables -A INPUT -p udp --dport 1194 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 1195 -j ACCEPT
# Oder via ufw
sudo ufw allow 1194/udp
sudo ufw allow 443/tcp
sudo ufw allow 1195/udp
```
---
## Gateway einrichten
### 1. Gateway anlegen
1. Navigation: **Gateways → Neues Gateway**
2. Formular ausfüllen:
- Name: z.B. "Kunde ABC - Türsteuerung Halle 1"
- Router-Typ: FL MGUARD 2000
- Standort: Halle 1, Raum 102
### 2. VPN-Profil erstellen
1. Gateway öffnen → **VPN-Profile** Tab
2. **Neues Profil** klicken
3. Formular:
- Name: z.B. "Produktion"
- VPN-Server: Server auswählen
- Priorität: 1 (primär)
4. **Erstellen** - Client-Zertifikat wird generiert
### 3. Provisioning-Download
1. VPN-Profil öffnen
2. **Konfiguration herunterladen** klicken
3. `.ovpn` Datei auf mGuard Router übertragen
### Failover mit mehreren Profilen
Für Ausfallsicherheit mehrere Profile mit unterschiedlichen Prioritäten:
| Profil | VPN-Server | Priorität | Verwendung |
|--------|------------|-----------|------------|
| Produktion | Server 1 (UDP) | 1 | Primärer Server |
| Fallback | Server 2 (TCP) | 2 | Bei Ausfall von Server 1 |
---
## Endpunkte definieren
Endpunkte sind Geräte hinter dem Gateway (SPS, HMI, etc.):
1. Gateway öffnen → **Endpunkte** Tab
2. **Endpunkt hinzufügen**
3. Ausfüllen:
- Name: HMI Türsteuerung
- IP-Adresse: 10.0.0.3
- Port: 11740
- Protokoll: TCP
- Anwendung: CoDeSys
---
## Web-Oberfläche
### Navigation
| Bereich | Beschreibung |
|---------|--------------
| **Dashboard** | Gateway-Status, aktive Verbindungen, Statistiken |
| **Gateways** | Gateway-Verwaltung, Endpunkte, VPN-Profile |
| **VPN → VPN-Server** | VPN-Instanzen verwalten, Status, Clients |
| **VPN → Zertifizierungsstellen** | CA erstellen/importieren, Zertifikate |
| **Benutzer** | Techniker anlegen, Rollen zuweisen |
| **Verbindungen** | Live-Anzeige aktiver Verbindungen, Historie |
---
## Benutzer & Berechtigungen
### Rollen
| Rolle | Rechte |
|-------|--------|
| **super_admin** | Alle Mandanten, alle Gateways, CAs, VPN-Server |
| **admin** | Eigener Mandant: Gateways, Benutzer, Endpunkte |
| **technician** | Nur zugewiesene Gateways sehen und verbinden |
| **viewer** | Nur lesen, keine Verbindungen |
---
## Wartung & Betrieb
### Logs ansehen
```bash
# Alle Logs
docker-compose logs -f
# Nur API-Server
docker-compose logs -f api
# Nur OpenVPN (alle Server)
docker-compose logs -f openvpn
# Einzelner VPN-Server im Container
docker exec mguard-openvpn cat /var/log/openvpn/server-1.log
```
### Server-Status prüfen
```bash
# Alle laufenden OpenVPN-Prozesse
docker exec mguard-openvpn supervisorctl status
# Ausgabe:
# openvpn-1 RUNNING pid 123, uptime 0:05:30
# openvpn-2 RUNNING pid 456, uptime 0:05:28
```
### Einzelnen Server neustarten
```bash
# Via supervisorctl
docker exec mguard-openvpn supervisorctl restart openvpn-1
```
### Backup
```bash
# Datenbank-Backup (enthält CAs, Zertifikate, Konfiguration)
docker-compose exec db mysqldump -u root -p mguard_vpn > backup.sql
# Volumes auflisten
docker volume ls | grep mguard
```
**Wichtig:** Die PKI (CAs, Zertifikate, Private Keys) ist in der Datenbank gespeichert. Ein Datenbank-Backup sichert alles.
### Update
```bash
# Container stoppen
docker-compose down
# Neue Version pullen/kopieren
git pull
# Neu bauen und starten
docker-compose up -d --build
```
---
## Fehlerbehebung
### OpenVPN startet nicht
```bash
# Logs prüfen
docker-compose logs openvpn
```
Mögliche Ursachen:
- **"API not ready"**: API-Container noch nicht gestartet
- **"No active VPN servers found"**: VPN-Server in Web-UI erstellen
- **"Failed to fetch server config"**: Server nicht bereit (CA/Zertifikat fehlt)
### Neuer VPN-Server wird nicht gestartet
1. Prüfe ob Server in Web-UI als "Bereit" markiert ist
2. Warte 30 Sekunden (Polling-Intervall)
3. Prüfe Logs: `docker-compose logs -f openvpn`
### Port bereits belegt
```bash
# Prüfen welcher Prozess den Port nutzt
sudo netstat -tlnp | grep 1194
sudo lsof -i :1194
# Falls nötig: Prozess beenden oder anderen Port in Web-UI wählen
```
### VPN-Server zeigt "Ausstehend"
DH-Parameter werden noch generiert. Status in der VPN-Server-Übersicht prüfen.
```bash
# CA-Status in Datenbank prüfen
docker-compose exec db mysql -u mguard -p -e \
"SELECT name, status FROM mguard_vpn.certificate_authorities"
```
### Gateway verbindet nicht
1. VPN-Profil für Gateway erstellt?
2. Provisioning-Datei heruntergeladen und importiert?
3. Firewall-Ports offen?
4. VPN-Server Status prüfen: **VPN → VPN-Server → Details**
---
## Verzeichnisstruktur
```
endpoint-server-openvpn/
├── docker-compose.yml # Container-Orchestrierung
├── .env.example # Konfigurationsvorlage
├── README.md # Diese Datei
├── server/ # FastAPI Backend + Web-UI
│ ├── Dockerfile
│ ├── requirements.txt
│ └── app/
│ ├── main.py # Einstiegspunkt
│ ├── api/ # REST API Routes
│ │ └── internal.py # Interne API für OpenVPN
│ ├── web/ # Web-UI Routes
│ │ ├── ca.py # CA-Verwaltung
│ │ ├── vpn_servers.py # VPN-Server
│ │ └── vpn_profiles.py # VPN-Profile
│ ├── templates/ # Jinja2 HTML-Templates
│ ├── models/ # Datenbank-Modelle
│ │ ├── certificate_authority.py
│ │ ├── vpn_server.py
│ │ └── vpn_profile.py
│ └── services/ # Business-Logik
│ ├── certificate_service.py
│ ├── vpn_server_service.py
│ └── vpn_profile_service.py
├── openvpn/ # OpenVPN Multi-Server Container
│ ├── Dockerfile
│ ├── entrypoint.sh # Multi-Server Management Script
│ └── supervisord.conf # Prozess-Manager Konfiguration
├── client/ # PyQt Desktop-Client
│ └── ...
└── provisioning-tool/ # CLI Provisioning
└── ...
```
---
## Sicherheit
- **TLS 1.2+** für VPN-Verbindungen
- **AES-256-GCM** Verschlüsselung (konfigurierbar)
- **JWT-Token** für API-Authentifizierung
- **Session-Cookies** für Web-UI
- **bcrypt** Password-Hashing
- **Multi-Tenant** Datenisolation
- **CRL** für Zertifikatswiderruf
### Produktiv-Empfehlungen
1. `.env` Passwörter ändern!
2. HTTPS-Reverse-Proxy (nginx/traefik) vorschalten
3. Firewall: Nur VPN-Ports und HTTPS nach außen
4. Regelmäßige Datenbank-Backups
5. Schlüsselgröße 4096-bit für CAs
### Host-Netzwerk Hinweis
Der OpenVPN-Container läuft im Host-Netzwerk-Modus. Das bedeutet:
- Direkte Port-Bindung (kein Docker NAT)
- Weniger Netzwerk-Overhead
- Container kann auf localhost:8000 zugreifen
- Firewall-Regeln auf Host-Ebene erforderlich
---
## REST API
Die API ist dokumentiert unter: **http://localhost:8000/api/docs**
### Wichtige Endpoints
| Methode | Endpoint | Beschreibung |
|---------|----------|--------------|
| POST | `/api/auth/login` | Login |
| GET | `/api/gateways` | Gateway-Liste |
| GET | `/api/gateways/{id}/profiles` | VPN-Profile eines Gateways |
| GET | `/api/gateways/{id}/profiles/{pid}/provision` | Provisioning-Download |
### Interne API (für OpenVPN-Container)
| Endpoint | Beschreibung |
|----------|--------------|
| `/api/internal/health` | Health Check |
| `/api/internal/vpn-servers/active` | Liste aller aktiven Server |
| `/api/internal/vpn-servers/{id}/config` | Server-Konfiguration |
| `/api/internal/vpn-servers/{id}/ca` | CA-Zertifikat |
| `/api/internal/vpn-servers/{id}/cert` | Server-Zertifikat |
| `/api/internal/vpn-servers/{id}/key` | Server Private Key |
| `/api/internal/vpn-servers/{id}/dh` | DH-Parameter |
| `/api/internal/vpn-servers/{id}/crl` | Revocation List |
| `/api/internal/vpn-servers/{id}/started` | Server-Start melden |
| `/api/internal/vpn-servers/{id}/stopped` | Server-Stop melden |
---
## Umgebungsvariablen
### OpenVPN Container
| Variable | Standard | Beschreibung |
|----------|----------|--------------|
| `API_URL` | `http://127.0.0.1:8000/api/internal` | API-Endpunkt |
| `API_TIMEOUT` | `120` | Timeout beim Warten auf API (Sekunden) |
| `API_RETRY_INTERVAL` | `5` | Wiederholungsintervall (Sekunden) |
| `POLL_INTERVAL` | `30` | Polling-Intervall für neue Server (Sekunden) |
---
## Container neu bauen
```bash
# Stoppen
docker-compose down
# Komplett neu bauen
docker-compose build --no-cache
# Starten
docker-compose up -d
```
---
## Desktop Client (Techniker-Anwendung)
Der Desktop Client ist eine PyQt6-Anwendung für Techniker, um sich zu VPN-Gateways zu verbinden.
### Voraussetzungen
- **Python 3.10+**
- **OpenVPN** (muss installiert sein)
- Zugang zum mGuard VPN Server
---
### Installation
#### Linux (Debian/Ubuntu)
```bash
# System-Abhängigkeiten installieren
sudo apt update
sudo apt install python3 python3-pip python3-venv openvpn
# In das Client-Verzeichnis wechseln
cd client/
# Virtuelle Umgebung erstellen (empfohlen)
python3 -m venv venv
source venv/bin/activate
# Abhängigkeiten installieren
pip install -r requirements.txt
```
#### Linux (Fedora/RHEL)
```bash
# System-Abhängigkeiten installieren
sudo dnf install python3 python3-pip openvpn
# In das Client-Verzeichnis wechseln
cd client/
# Virtuelle Umgebung erstellen (empfohlen)
python3 -m venv venv
source venv/bin/activate
# Abhängigkeiten installieren
pip install -r requirements.txt
```
#### Linux (Arch)
```bash
# System-Abhängigkeiten installieren
sudo pacman -S python python-pip openvpn
# In das Client-Verzeichnis wechseln
cd client/
# Virtuelle Umgebung erstellen (empfohlen)
python -m venv venv
source venv/bin/activate
# Abhängigkeiten installieren
pip install -r requirements.txt
```
#### Windows
1. **Python installieren:**
- Download von https://www.python.org/downloads/
- Bei Installation "Add Python to PATH" aktivieren
2. **OpenVPN installieren:**
- Download von https://openvpn.net/community-downloads/
- Standard-Installation in `C:\Program Files\OpenVPN`
3. **Client installieren:**
```powershell
# PowerShell oder CMD
cd client
# Virtuelle Umgebung erstellen (empfohlen)
python -m venv venv
venv\Scripts\activate
# Abhängigkeiten installieren
pip install -r requirements.txt
```
#### macOS
```bash
# Homebrew installieren (falls nicht vorhanden)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Python und OpenVPN installieren
brew install python openvpn
# In das Client-Verzeichnis wechseln
cd client/
# Virtuelle Umgebung erstellen (empfohlen)
python3 -m venv venv
source venv/bin/activate
# Abhängigkeiten installieren
pip install -r requirements.txt
```
---
### Client starten
#### Linux / macOS
```bash
# In das Client-Verzeichnis wechseln
cd client/
# Virtuelle Umgebung aktivieren (falls verwendet)
source venv/bin/activate
# Client starten
python main.py
```
**Hinweis:** Für VPN-Verbindungen sind Root-Rechte erforderlich:
```bash
# Mit sudo starten (für VPN-Verbindungen)
sudo venv/bin/python main.py
```
#### Windows
```powershell
# In das Client-Verzeichnis wechseln
cd client
# Virtuelle Umgebung aktivieren (falls verwendet)
venv\Scripts\activate
# Client starten
python main.py
```
**Hinweis:** Als Administrator ausführen für VPN-Verbindungen.
---
### Erste Schritte im Client
1. **Server konfigurieren:**
- Beim ersten Start Server-URL eingeben (z.B. `https://vpn.meinefirma.de:8000`)
2. **Anmelden:**
- Mit Techniker-Zugangsdaten einloggen
3. **Gateway wählen:**
- Liste der zugewiesenen Gateways wird angezeigt
- Online-Status wird angezeigt (grün = erreichbar)
4. **Verbinden:**
- Gateway auswählen und "Verbinden" klicken
- VPN-Verbindung wird automatisch hergestellt
5. **Endpunkte nutzen:**
- Nach Verbindung sind die Endpunkte (SPS, HMI, etc.) erreichbar
- IP-Adressen und Ports werden angezeigt
---
### Konfiguration
Der Client speichert Einstellungen in:
| OS | Pfad |
|----|------|
| Linux/macOS | `~/.mguard-vpn/settings.json` |
| Windows | `C:\Users\<User>\.mguard-vpn\settings.json` |
OpenVPN-Konfigurationen werden gespeichert in:
| OS | Pfad |
|----|------|
| Linux/macOS | `~/.openvpn/` |
| Windows | `C:\Users\<User>\OpenVPN\config\` |
---
### Fehlerbehebung Client
#### "OpenVPN nicht gefunden"
**Linux:**
```bash
# OpenVPN Pfad prüfen
which openvpn
# Sollte /usr/sbin/openvpn ausgeben
# Falls woanders installiert, symlink erstellen
sudo ln -s /pfad/zu/openvpn /usr/sbin/openvpn
```
**Windows:**
- Prüfen ob OpenVPN in `C:\Program Files\OpenVPN\bin\` installiert ist
- Falls anderer Pfad: `client/config.py` anpassen
**macOS:**
```bash
# OpenVPN Pfad prüfen
which openvpn
# Meist /opt/homebrew/bin/openvpn oder /usr/local/bin/openvpn
# Symlink erstellen falls nötig
sudo ln -s $(which openvpn) /usr/sbin/openvpn
```
#### "Permission denied" bei VPN-Verbindung
VPN-Verbindungen erfordern erhöhte Rechte:
```bash
# Linux/macOS: Mit sudo starten
sudo python main.py
# Windows: Als Administrator ausführen
# Rechtsklick → "Als Administrator ausführen"
```
#### PyQt6 Fehler auf Linux
```bash
# Fehlende Qt-Bibliotheken installieren
sudo apt install libxcb-xinerama0 libxkbcommon-x11-0
# Oder für Wayland
sudo apt install qtwayland5
```
---
## Lizenz
Proprietär - Nur für internen Gebrauch.