39 KiB
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:
routesagt dem Kernel wohin,iroutesagt OpenVPN wohin. Beide sind erforderlich damit das Routing funktioniert!
Gateway-Seite (mGuard/Linux)
Das Gateway muss als Router fungieren und Traffic weiterleiten:
# 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 Servereth0(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:
# 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
# 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
# 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
- Navigation: VPN → Zertifizierungsstellen
- Neue CA erstellen klicken
- Formular ausfüllen:
- Name: z.B. "Produktion CA"
- Organisation, Land, Stadt
- Schlüsselgröße: 4096 (empfohlen) oder 2048
- Gültigkeit: 3650 Tage (10 Jahre)
- Erstellen - DH-Parameter werden im Hintergrund generiert
Schritt 2: VPN-Server erstellen
- Navigation: VPN → VPN-Server
- Neuer VPN-Server klicken
- 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
- Erstellen - Server-Zertifikat wird automatisch generiert
Schritt 3: Automatischer Start
Der OpenVPN-Container erkennt neue Server automatisch (Polling alle 30s):
# 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:
# 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
- Navigation: Gateways → Neues Gateway
- 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
- Gateway öffnen → VPN-Profile Tab
- Neues Profil klicken
- Formular:
- Name: z.B. "Produktion"
- VPN-Server: Server auswählen
- Priorität: 1 (primär)
- Erstellen - Client-Zertifikat wird generiert
3. Provisioning-Download
- VPN-Profil öffnen
- Konfiguration herunterladen klicken
.ovpnDatei 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.):
- Gateway öffnen → Endpunkte Tab
- Endpunkt hinzufügen
- 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
# 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
# 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
# Via supervisorctl
docker exec mguard-openvpn supervisorctl restart openvpn-1
Backup
# 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
# Container stoppen
docker-compose down
# Neue Version pullen/kopieren
git pull
# Neu bauen und starten
docker-compose up -d --build
Fehlerbehebung
OpenVPN startet nicht
# 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
- Prüfe ob Server in Web-UI als "Bereit" markiert ist
- Warte 30 Sekunden (Polling-Intervall)
- Prüfe Logs:
docker-compose logs -f openvpn
Port bereits belegt
# 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.
# 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
- VPN-Profil für Gateway erstellt?
- Provisioning-Datei heruntergeladen und importiert?
- Firewall-Ports offen?
- 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
.envPasswörter ändern!- HTTPS-Reverse-Proxy (nginx/traefik) vorschalten
- Firewall: Nur VPN-Ports und HTTPS nach außen
- Regelmäßige Datenbank-Backups
- 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
# 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)
# 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)
# 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)
# 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
-
Python installieren:
- Download von https://www.python.org/downloads/
- Bei Installation "Add Python to PATH" aktivieren
-
OpenVPN installieren:
- Download von https://openvpn.net/community-downloads/
- Standard-Installation in
C:\Program Files\OpenVPN
-
Client installieren:
# 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
# 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
# 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:
# Mit sudo starten (für VPN-Verbindungen)
sudo venv/bin/python main.py
Windows
# 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
-
Server konfigurieren:
- Beim ersten Start Server-URL eingeben (z.B.
https://vpn.meinefirma.de:8000)
- Beim ersten Start Server-URL eingeben (z.B.
-
Anmelden:
- Mit Techniker-Zugangsdaten einloggen
-
Gateway wählen:
- Liste der zugewiesenen Gateways wird angezeigt
- Online-Status wird angezeigt (grün = erreichbar)
-
Verbinden:
- Gateway auswählen und "Verbinden" klicken
- VPN-Verbindung wird automatisch hergestellt
-
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:
# 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.pyanpassen
macOS:
# 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:
# Linux/macOS: Mit sudo starten
sudo python main.py
# Windows: Als Administrator ausführen
# Rechtsklick → "Als Administrator ausführen"
PyQt6 Fehler auf Linux
# 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.