# 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\\.mguard-vpn\settings.json` | OpenVPN-Konfigurationen werden gespeichert in: | OS | Pfad | |----|------| | Linux/macOS | `~/.openvpn/` | | Windows | `C:\Users\\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.