# 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) │ └─────────────────────┘ └─────────────────────┘ ``` --- ## Verbindungsweg: Client → Server → Gateway → Endpunkt Diese Sektion erklärt den vollständigen Datenweg, wenn ein Techniker (Service-PC) auf ein Gerät (z.B. SPS, HMI) hinter einem Gateway zugreift. ### Übersicht ``` Techniker-Netz Internet Kunden-Netz 192.168.178.0/24 192.168.0.0/24 ┌─────────────────┐ ┌──────────────────────────────┐ ┌─────────────────┐ ┌─────────────┐ │ Service-PC │ │ VPN-Server │ │ Gateway │ │ Endpunkt │ │ (Techniker) │ │ (Docker Host) │ │ (mGuard) │ │ (SPS) │ │ │ │ │ │ │ │ │ │ LAN: 192.168. │ │ ┌────────────────────────┐ │ │ VPN: 10.8.0.100 │ │ 192.168.0.3 │ │ 178.100 │ │ │ OpenVPN Server │ │ │ │ │ Port 11740 │ │ GW: 192.168. │◄────►│ │ VPN-Netz: 10.8.0.0/24 │ │◄────►│ LAN: 192.168. │◄────►│ (CoDeSys) │ │ 178.1 │ │ │ Public: 85.16.65.177 │ │ │ 0.100 │ │ │ │ │ │ └────────────────────────┘ │ │ │ │ │ │ VPN: 10.8.0.50 │ │ │ │ │ │ │ └─────────────────┘ └──────────────────────────────┘ └─────────────────┘ └─────────────┘ │ │ │ │ │ VPN-Tunnel │ VPN-Tunnel │ Lokales Netz │ │ (verschlüsselt) │ (verschlüsselt) │ 192.168.0.0/24 │ └──────────────────────────────┴───────────────────────────────┴───────────────────────┘ ``` ### Netzwerk-Adressen im Beispiel | Komponente | Interface | IP-Adresse | Beschreibung | |------------|-----------|------------|--------------| | **Service-PC** | eth0/wlan0 | 192.168.178.100/24 | Lokales Netz des Technikers | | **Service-PC** | (Gateway) | 192.168.178.1 | Fritz!Box/Router ins Internet | | **Service-PC** | tun0 | 10.8.0.50 | VPN-IP (vom Server zugewiesen) | | **VPN-Server** | eth0 | 85.16.65.177 | Öffentliche IP | | **VPN-Server** | tun0 | 10.8.0.1 | VPN-Gateway | | **Gateway** | tun0 | 10.8.0.100 | VPN-IP des Gateways | | **Gateway** | eth0 | 192.168.0.100/24 | LAN-Interface beim Kunden | | **Endpunkt (SPS)** | eth0 | 192.168.0.3 | CoDeSys-SPS im Kunden-LAN | ### Schritt-für-Schritt Verbindungsablauf #### 1. Techniker meldet sich im Desktop-Client an ``` Service-PC VPN-Server (API) │ │ │ POST /api/auth/login │ │ {username, password} │ │ ─────────────────────────────────────► │ │ │ │ JWT Token │ │ ◄───────────────────────────────────── │ ``` #### 2. Techniker wählt Gateway und Endpunkt ``` Service-PC VPN-Server (API) │ │ │ GET /api/gateways │ │ ─────────────────────────────────────► │ │ │ │ Liste der zugewiesenen Gateways │ │ + Online-Status │ │ ◄───────────────────────────────────── │ │ │ │ POST /api/connections/connect │ │ {gateway_id, endpoint_id} │ │ ─────────────────────────────────────► │ │ │ │ VPN-Konfiguration (.ovpn Inhalt) │ │ + Ziel-IP und Port │ │ ◄───────────────────────────────────── │ ``` #### 3. VPN-Tunnel wird aufgebaut ``` Service-PC OpenVPN-Server Gateway (mGuard) │ │ │ │ UDP/TCP Handshake │ │ │ ────────────────────────────►│ │ │ │ │ │ TLS-Authentifizierung │ │ │ (Client-Zertifikat) │ │ │ ◄───────────────────────────►│ │ │ │ │ │ VPN-IP zugewiesen: │ │ │ 10.8.0.50 │ │ │ ◄────────────────────────── │ │ │ │ │ │ Tunnel aktiv │ Tunnel aktiv │ │ ════════════════════════════ │ ═══════════════════════ │ │ │ 10.8.0.100 │ ``` #### 4. Routing zum Endpunkt ``` Service-PC (10.8.0.50) OpenVPN-Server Gateway (10.8.0.100) SPS (192.168.0.3) │ │ │ │ │ Paket an 192.168.0.3:11740 │ │ │ │ ══════════════════════════════►│ │ │ │ (durch VPN-Tunnel) │ │ │ │ │ │ │ │ │ Routing-Entscheidung: │ │ │ │ 192.168.0.0/24→10.8.0.100 │ │ │ │ (via iroute im CCD) │ │ │ │ ══════════════════════════►│ │ │ │ (durch VPN-Tunnel) │ │ │ │ │ │ │ │ │ IP-Forwarding + NAT │ │ │ │ ────────────────────────►│ │ │ │ (eth0: 192.168.0.100) │ │ │ │ │ │ │ │ Antwort │ │ │ │ ◄────────────────────────│ │ │ │ │ │ │ ◄══════════════════════════│ │ │ ◄══════════════════════════════│ │ │ │ │ │ │ ``` ### Routing-Konfiguration im Detail #### Server-Seite (OpenVPN-Server) Der VPN-Server muss wissen, welche Subnetze über welchen Client (Gateway) erreichbar sind: **server.conf (automatisch generiert):** ``` # VPN-Netzwerk für alle Clients server 10.8.0.0 255.255.255.0 # Route für Kunden-Subnetz 192.168.0.0/24 → Gateway route 192.168.0.0 255.255.255.0 # Kernel-Route # Client-Config-Directory für iroute-Direktiven client-config-dir /etc/openvpn/ccd ``` **CCD-Datei für Gateway (z.B. `/etc/openvpn/ccd/gw-kunde-abc-1`):** ``` # Traffic für Kunden-Subnetz 192.168.0.0/24 geht durch diesen Client iroute 192.168.0.0 255.255.255.0 ``` > **Wichtig:** `route` sagt dem Kernel wohin, `iroute` sagt OpenVPN wohin. > Beide sind erforderlich damit das Routing funktioniert! #### Gateway-Seite (mGuard/Linux) Das Gateway muss als Router fungieren und Traffic weiterleiten: ```bash # IP-Forwarding aktivieren echo 1 > /proc/sys/net/ipv4/ip_forward # NAT/Masquerading für VPN-Traffic ins Kunden-LAN (192.168.0.0/24) iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE # Forwarding erlauben: VPN (tun0) ↔ Kunden-LAN (eth0) iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT iptables -A FORWARD -i eth0 -o tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT ``` **Wichtig:** Das Gateway hat zwei Interfaces: - `tun0` (10.8.0.100) - VPN-Tunnel zum Server - `eth0` (192.168.0.100) - Kunden-LAN mit der SPS ### Split Tunneling (Client-Seite) Der Desktop-Client verwendet **Split Tunneling**, damit: - VPN-Traffic (Gateways, Endpunkte) durch den Tunnel geht - Internet-Traffic **nicht** durch den Tunnel geht **Client-Konfiguration (.ovpn):** ``` # Redirect-Gateway vom Server ignorieren pull-filter ignore "redirect-gateway" # Nur VPN-Netzwerk routen route 10.8.0.0 255.255.255.0 # Nur Kunden-Subnetze routen (automatisch hinzugefügt basierend auf Gateway-Zugriff) route 192.168.0.0 255.255.255.0 # Kunde mit SPS ``` **Resultat auf dem Service-PC:** ``` ┌──────────────────────┐ │ Service-PC │ │ LAN: 192.168.178.100 │ │ VPN: 10.8.0.50 │ └──────────┬───────────┘ │ ┌──────────────┴──────────────┐ │ │ Ziel: 10.8.0.x Ziel: 8.8.8.8 Ziel: 192.168.0.x (Internet) │ │ ▼ ▼ ┌───────────────┐ ┌───────────────┐ │ VPN-Tunnel │ │ Fritz!Box │ │ (tun0) │ │ 192.168.178.1 │ └───────────────┘ └───────────────┘ ``` **Routing-Tabelle auf dem Service-PC (nach VPN-Verbindung):** ``` $ ip route default via 192.168.178.1 dev eth0 # Internet → Fritz!Box 10.8.0.0/24 via 10.8.0.1 dev tun0 # VPN-Netz → Tunnel 192.168.0.0/24 via 10.8.0.1 dev tun0 # Kunden-Netz → Tunnel 192.168.178.0/24 dev eth0 src 192.168.178.100 # Lokales Netz ``` ### Beispiel: Kompletter Verbindungsweg **Szenario:** Techniker will auf CoDeSys (Port 11740) auf einer SPS zugreifen. | Komponente | Lokale IP | VPN-IP | Rolle | |------------|-----------|--------|-------| | Service-PC | 192.168.178.100 | 10.8.0.50 | Techniker-Laptop mit Desktop-Client | | Fritz!Box | 192.168.178.1 | - | Internet-Gateway des Technikers | | VPN-Server | 85.16.65.177:1199 | 10.8.0.1 | Docker-Host mit OpenVPN | | Gateway | 192.168.0.100 | 10.8.0.100 | mGuard/Linux beim Kunden | | SPS (Endpunkt) | 192.168.0.3:11740 | - | CoDeSys-SPS im Kunden-LAN | **Paketweg (Hinrichtung):** ``` 1. Techniker öffnet CoDeSys, verbindet zu 192.168.0.3:11740 2. Service-PC prüft Routing-Tabelle: 192.168.0.0/24 → tun0 (VPN-Tunnel) ✓ Ziel 192.168.0.3 matcht → geht durch Tunnel 3. Paket wird verschlüsselt und durch VPN-Tunnel gesendet: Inner: Src: 10.8.0.50 Dst: 192.168.0.3:11740 Outer: Src: 192.168.178.100 Dst: 85.16.65.177:1199 (UDP) 4. Paket geht über Fritz!Box (192.168.178.1) ins Internet 5. VPN-Server (85.16.65.177) empfängt, entschlüsselt, prüft Routing: - route 192.168.0.0/24 → existiert (Kernel weiß Bescheid) - iroute 192.168.0.0/24 → OpenVPN weiß: geht an Client "gw-xxx" 6. Server verschlüsselt und leitet an Gateway weiter (durch dessen Tunnel): Src: 10.8.0.50 Dst: 192.168.0.3 7. Gateway (10.8.0.100) empfängt auf tun0, leitet weiter: - IP-Forwarding aktiv - NAT/Masquerade: Src-IP wird zu 192.168.0.100 (Gateway's LAN-IP) - Paket geht raus auf eth0 (192.168.0.100) ins Kunden-LAN 8. SPS (192.168.0.3) empfängt Anfrage von 192.168.0.100, antwortet 9. Rückweg: - SPS antwortet an 192.168.0.100 (Gateway) - Gateway's NAT übersetzt zurück zu 10.8.0.50 - Paket geht durch VPN-Tunnel zurück zum Server - Server leitet an Service-PC weiter - CoDeSys empfängt Antwort ``` **Zusammenfassung der IP-Adressen im Paket:** ``` Service-PC VPN-Server Gateway SPS 192.168.178.100 85.16.65.177 192.168.0.100 192.168.0.3 │ │ │ │ │ Outer: 192.168.178.100 │ │ │ │ → 85.16.65.177 │ │ │ │ Inner: 10.8.0.50 │ │ │ │ → 192.168.0.3 │ │ │ │═════════════════════════│ │ │ │ (verschlüsselt) │ Inner: 10.8.0.50 │ │ │ │ → 192.168.0.3 │ │ │ │════════════════════════│ │ │ │ (verschlüsselt) │ NAT: 192.168.0.100 │ │ │ │ → 192.168.0.3 │ │ │ │───────────────────────│ │ │ │ (unverschlüsselt) │ ``` ### Firewall-Regeln (automatisch) Der VPN-Server kann dynamisch Firewall-Regeln erstellen, um Zugriffe zu kontrollieren: ```bash # Wenn Techniker sich verbindet und Endpunkt anfordert: iptables -A MGUARD_VPN -s 10.8.0.50 -d 192.168.0.3 -p tcp --dport 11740 -j ACCEPT iptables -A MGUARD_VPN -s 192.168.0.3 -d 10.8.0.50 -p tcp --sport 11740 -j ACCEPT # Wenn Techniker trennt: iptables -D MGUARD_VPN ... (Regeln entfernen) ``` ### Zusammenfassung der Netzwerk-Komponenten | Schicht | Komponente | Funktion | |---------|------------|----------| | **Client** | Desktop-Client | Login, Gateway-Auswahl, OpenVPN starten | | **Client** | OpenVPN (Client) | VPN-Tunnel aufbauen, Split-Tunneling | | **Server** | OpenVPN (Server) | Tunnel-Endpunkt, Routing zwischen Clients | | **Server** | CCD-Dateien | iroute-Direktiven für Gateway-Subnetze | | **Gateway** | OpenVPN (Client) | Permanenter VPN-Tunnel zum Server | | **Gateway** | IP-Forwarding | Pakete zwischen tun0 und eth0 weiterleiten | | **Gateway** | NAT/Masquerade | Source-IP umschreiben für Rückweg | | **Endpunkt** | Zielgerät | SPS, HMI, oder anderes Gerät im Kunden-LAN | --- ### 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.