openvpn-endpoint-server/README.md

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

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

# 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

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

# 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

  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

# 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

  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

# 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

  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

# 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

  1. Python installieren:

  2. OpenVPN installieren:

  3. 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

  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:

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

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