OpenVPN Site-to-Site Server für Phoenix-Contact-Router: zwei sichere Serverprofile
OpenVPN Site-to-Site Server für Phoenix-Contact-Router: zwei sichere Serverprofile
Stand: 27. Mai 2026
Ziel dieses Dokuments: Es beschreibt zwei getrennte OpenVPN-Serverinstanzen auf einem Linux-Server.
- modern.conf: maximal gehärtet für aktuelle OpenVPN-Clients.
- compat.conf: weiterhin sehr sicher, aber bewusst kompatibler für ältere Industrie-/Phoenix-Contact-Geräte.
Beide Varianten sind für geroutete Site-to-Site-Tunnel gedacht. Das ist für dein Szenario richtig: Ein Phoenix-Contact-Router verbindet sich als OpenVPN-Client, teilt sein lokales LAN über den Tunnel und erreicht umgekehrt das zentrale LAN.
1. Quellen und Grundannahmen
Dieses Dokument orientiert sich vor allem an der offiziellen OpenVPN-2.6-Dokumentation, der OpenVPN-Hardening-Dokumentation, der OpenVPN-Dokumentation zu client-spezifischen Regeln und Easy-RSA. Wikipedia wird nur für die allgemeine Einordnung von OpenVPN als TLS-basiertes VPN über UDP/TCP erwähnt. Produktiv relevante Optionen werden aus der OpenVPN-Dokumentation abgeleitet, weil Wikipedia nicht deine Firewall administriert. Zum Glück.
| Quelle | Wofür sie hier verwendet wird |
|---|---|
| OpenVPN 2.6 Manual | Direktiven wie server, data-ciphers, tls-groups, tls-crypt-v2, ccd-exclusive, iroute, keepalive, explicit-exit-notify. |
| OpenVPN Hardening Wiki | Begründung für tls-version-min 1.2 und allgemeine TLS-Härtung. |
| OpenVPN Client-Specific Rules | Nutzung von client-config-dir, festen Client-IP-Adressen und Firewall-Policy je Client. |
| OpenVPN Compression Wiki | Begründung, warum Kompression deaktiviert bleibt. |
| Easy-RSA Dokumentation | PKI-, CA-, Zertifikats- und CRL-Erstellung. |
| Wikipedia: OpenVPN | Allgemeine Einordnung: OpenVPN ist ein freies VPN über verschlüsselte TLS-Verbindungen und kann UDP oder TCP verwenden. |
2. Zielbild
Wir bauen kein Layer-2-Bridging mit TAP. Wir bauen geroutete Layer-3-Tunnel mit TUN. Das ist stabiler, besser kontrollierbar und für Site-to-Site-Netze sauberer.
Zentrales LAN:
10.10.0.0/24
OpenVPN modern:
Instanz: modern.conf
Port: UDP/1194
TUN-Interface: tun0
VPN-Netz: 10.255.0.0/24
Beispielclient: phoenix-modern-werk1
Client-VPN-IP: 10.255.0.10
LAN hinter Client:192.168.101.0/24
OpenVPN kompatibel:
Instanz: compat.conf
Port: UDP/1195
TUN-Interface: tun1
VPN-Netz: 10.254.0.0/24
Beispielclient: phoenix-legacy-werk1
Client-VPN-IP: 10.254.0.10
LAN hinter Client:192.168.201.0/24
Wichtig: Die LAN-Netze hinter den Phoenix-Geräten müssen eindeutig sein. Zwei Standorte mit demselben Netz, etwa zweimal 192.168.0.0/24, machen sauberes Routing unmöglich. Dann brauchst du 1:1-NAT oder eine Umnummerierung. Umnummerierung ist meistens die bessere Lösung, auch wenn Menschen dabei gern so tun, als wäre ein IP-Plan eine Naturkatastrophe.
3. Warum zwei getrennte OpenVPN-Instanzen?
Eine einzelne OpenVPN-Instanz kann theoretisch moderne und ältere Clients bedienen. Praktisch verwässerst du damit die starke Konfiguration, weil du Legacy-Fallbacks zulässt. Besser ist die Trennung:
| Instanz | Ziel | Sicherheitsentscheidung |
|---|---|---|
modern.conf |
Neue Clients mit aktueller OpenVPN-/TLS-Unterstützung. | Starke Kurvengruppen, AEAD-Cipher, tls-crypt-v2, keine CBC-Fallbacks. |
compat.conf |
Ältere Phoenix-/Industrieclients, die moderne Optionen nicht zuverlässig können. | Weiterhin TLS 1.2+, Zertifikate, CRL, tls-auth, keine Kompression, aber zusätzlicher CBC-Fallback. |
Wenn du zwei öffentliche IP-Adressen hast, kannst du beide Instanzen auf Port 1194 betreiben und jeweils an eine andere IP binden. Wenn du nur eine öffentliche IP hast, müssen die Ports verschieden sein. Dieses Dokument nutzt daher 1194 für modern und 1195 für kompatibel.
4. Sicherheitsprinzipien
- Ein Zertifikat pro Standort. Kein Zertifikat wird mehrfach verwendet.
- Ein Common Name pro Standort. Der Dateiname in
ccdentspricht genau dem Common Name des Zertifikats. - Ein Standortnetz pro Zertifikat. Das wird mit
iroutegebunden. ccd-exclusive. Clients ohne CCD-Datei werden abgewiesen.- Keine Kompression. Kompression in verschlüsselten Tunneln ist ein historischer Fußtritt in Richtung Sicherheitsproblem.
- CRL aktiv. Verlorene Geräte werden über Zertifikatssperrlisten entfernt.
- Keine überlappenden Netze. Routing braucht Eindeutigkeit. Überraschend, ich weiß.
- Firewall erzwingt die Policy. OpenVPN routet, die Firewall entscheidet.
- CA-Key nicht dauerhaft auf dem VPN-Server. Idealerweise liegt die CA auf einer separaten Admin-Maschine.
5. Installation auf Debian/Ubuntu
Die folgenden Befehle sind für Debian/Ubuntu-artige Systeme geschrieben. Bei RHEL/Rocky/Alma sind Paketmanager und Gruppennamen anders. Das Konzept bleibt gleich.
sudo apt update
sudo apt install -y openvpn easy-rsa nftables
sudo systemctl enable --now nftables
5.1 Befehl-für-Befehl-Erklärung
| Befehl | Was macht er? | Warum so? | Alternativen |
|---|---|---|---|
sudo apt update |
Aktualisiert die lokale Paketliste des Systems. | Ohne aktuelle Paketliste installiert apt eventuell alte oder nicht auffindbare Pakete. |
apt-get update ist die ältere, skriptfreundliche Variante. Auf RHEL-Systemen wäre es z. B. dnf makecache. |
sudo apt install -y openvpn easy-rsa nftables |
Installiert OpenVPN, Easy-RSA und nftables. | openvpn ist der VPN-Dienst, easy-rsa erzeugt Zertifikate und CRLs, nftables stellt die Firewall. |
Statt nftables könntest du iptables, ufw oder eine externe Firewall verwenden. Für Server ist nftables heute die sauberere Wahl. |
sudo systemctl enable --now nftables |
Aktiviert nftables dauerhaft und startet es sofort. | enable sorgt für Start beim Booten, --now startet den Dienst direkt. |
Man kann Firewallregeln auch über ein zentrales Firewall-System setzen. Lokal ist trotzdem sinnvoll, weil ein VPN-Server niemals blind vertrauen sollte. |
6. Verzeichnisstruktur anlegen
sudo install -d -m 750 /etc/openvpn/server/modern
sudo install -d -m 750 /etc/openvpn/server/modern/ccd
sudo install -d -m 750 /etc/openvpn/server/compat
sudo install -d -m 750 /etc/openvpn/server/compat/ccd
| Befehl | Was macht er? | Warum so? | Alternativen |
|---|---|---|---|
sudo install -d -m 750 /etc/openvpn/server/modern |
Legt das Verzeichnis für die moderne Instanz an. | install -d erstellt ein Verzeichnis. -m 750 setzt Rechte: Besitzer darf alles, Gruppe darf lesen/betreten, andere dürfen nichts. |
mkdir -p plus chmod geht auch, ist aber ein Befehl mehr. Weil wir hier angeblich Ordnung wollen, nutzen wir install. |
sudo install -d -m 750 /etc/openvpn/server/modern/ccd |
Legt das CCD-Verzeichnis der modernen Instanz an. | Hier liegen später Dateien wie phoenix-modern-werk1. OpenVPN liest daraus feste IPs und iroute-Einträge. |
Man könnte ccd auch woanders speichern, aber unterhalb der Instanz bleibt es verständlich. |
sudo install -d -m 750 /etc/openvpn/server/compat |
Legt das Verzeichnis für die kompatible Instanz an. | Trennung verhindert, dass Schlüssel, CRLs oder CCD-Dateien versehentlich zwischen modern und legacy vermischt werden. | Eine gemeinsame Struktur wäre möglich, aber schlechter auditierbar. |
sudo install -d -m 750 /etc/openvpn/server/compat/ccd |
Legt das CCD-Verzeichnis der kompatiblen Instanz an. | Auch ältere Geräte bekommen feste Zuordnungen über CN, feste VPN-IP und entferntes LAN. | Keine gute Alternative, wenn du pro Zertifikat ein Netz sauber binden willst. |
7. PKI-Strategie
Für die sauberste Trennung nutzt jede Instanz ihre eigene PKI:
~/easy-rsa-modernfür moderne Clients.~/easy-rsa-compatfür ältere Clients.
Das ist administrativ etwas mehr Arbeit, aber sicherer. Wenn ein Legacy-Bereich kompromittiert wird, ist der moderne Bereich nicht automatisch dieselbe Vertrauensdomäne. Man könnte eine gemeinsame Root-CA mit getrennten Intermediate-CAs bauen. Für viele kleinere Betriebsumgebungen sind zwei getrennte Easy-RSA-PKIs einfacher.
8. Moderne PKI erstellen
make-cadir ~/easy-rsa-modern
cd ~/easy-rsa-modern
./easyrsa init-pki
./easyrsa build-ca
./easyrsa build-server-full modern-server nopass
./easyrsa build-client-full phoenix-modern-werk1 nopass
./easyrsa gen-crl
8.1 Erklärung der Befehle
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
make-cadir ~/easy-rsa-modern |
Erstellt ein Arbeitsverzeichnis mit Easy-RSA-Dateien. | Die PKI wird getrennt von der Systemkonfiguration vorbereitet. Das ist übersichtlicher und reduziert versehentliches Überschreiben. | Du kannst auch ein anderes Verzeichnis nehmen, z. B. /root/easy-rsa-modern. Idealerweise liegt die CA aber nicht dauerhaft auf dem VPN-Server. |
cd ~/easy-rsa-modern |
Wechselt in das neue Easy-RSA-Verzeichnis. | Die nächsten Befehle müssen im Easy-RSA-Verzeichnis ausgeführt werden. | Mit absoluten Pfaden geht es auch, ist aber unleserlicher. |
./easyrsa init-pki |
Initialisiert die PKI-Struktur unter pki/. |
Erzeugt Verzeichnisse und Datenbanken für Zertifikate, Schlüssel und Seriennummern. | init-pki löscht/initialisiert die PKI. Auf produktiven CAs also nicht gedankenlos wiederholen. Menschen lieben destruktive Befehle mit harmlosen Namen. |
./easyrsa build-ca |
Erzeugt die Certificate Authority. | Die CA signiert später Server- und Client-Zertifikate. Der private CA-Key ist das wichtigste Geheimnis. | build-ca nopass wäre möglich, ist aber für eine CA nicht empfehlenswert. Eine CA sollte mit Passwort geschützt sein. |
./easyrsa build-server-full modern-server nopass |
Erzeugt und signiert ein Serverzertifikat mit Namen modern-server. |
nopass sorgt dafür, dass OpenVPN beim Dienststart kein Passwort interaktiv abfragen muss. |
Ohne nopass wird der private Schlüssel verschlüsselt. Das ist sicherer, aber für automatischen Serverstart unpraktisch. Alternativ kann man mit askpass arbeiten. |
./easyrsa build-client-full phoenix-modern-werk1 nopass |
Erzeugt ein Clientzertifikat für den Standort phoenix-modern-werk1. |
Der Name wird zum Common Name und muss später exakt als CCD-Dateiname verwendet werden. | Für Benutzerlaptops wäre ein passwortgeschützter Key besser. Für Phoenix-Router ist nopass oft nötig, weil das Gerät beim Booten kein Passwort eintippen kann. |
./easyrsa gen-crl |
Erzeugt die Zertifikatssperrliste crl.pem. |
OpenVPN prüft damit, ob ein Clientzertifikat gesperrt wurde. | Nach jedem revoke musst du gen-crl erneut ausführen und die neue CRL auf den Server kopieren. |
9. Moderne PKI-Dateien auf den Server kopieren
sudo install -m 644 pki/ca.crt /etc/openvpn/server/modern/pki-ca.crt
sudo install -m 644 pki/issued/modern-server.crt /etc/openvpn/server/modern/modern-server.crt
sudo install -m 600 pki/private/modern-server.key /etc/openvpn/server/modern/modern-server.key
sudo install -m 644 pki/crl.pem /etc/openvpn/server/modern/crl.pem
sudo install -d -m 750 /etc/openvpn/server/modern/pki
sudo install -d -m 750 /etc/openvpn/server/modern/pki/issued
sudo install -d -m 700 /etc/openvpn/server/modern/pki/private
sudo cp pki/ca.crt /etc/openvpn/server/modern/pki/ca.crt
sudo cp pki/issued/modern-server.crt /etc/openvpn/server/modern/pki/issued/modern-server.crt
sudo cp pki/private/modern-server.key /etc/openvpn/server/modern/pki/private/modern-server.key
sudo cp pki/crl.pem /etc/openvpn/server/modern/crl.pem
sudo chown -R root:root /etc/openvpn/server/modern
sudo chmod 600 /etc/openvpn/server/modern/pki/private/modern-server.key
sudo chmod 644 /etc/openvpn/server/modern/crl.pem
Hinweis: In der Praxis brauchst du die ersten vier install-Zeilen nicht, wenn du direkt die strukturierte Variante darunter verwendest. Ich zeige sie trotzdem, weil install -m verständlich macht, dass Dateirechte kein Deko-Element sind. Für die eigentliche Dokumentation ist die strukturierte Variante mit pki/ca.crt, pki/issued und pki/private die relevante.
9.1 Erklärung der wichtigsten Kopierbefehle
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
sudo install -d -m 750 .../pki |
Erstellt ein PKI-Unterverzeichnis für die Instanz. | Die Pfade in modern.conf sind dadurch klar und getrennt. |
Du könntest die Dateien direkt unter /etc/openvpn/server/modern ablegen, aber Unterordner sind sauberer. |
sudo install -d -m 700 .../pki/private |
Erstellt das private Schlüsselverzeichnis mit strengeren Rechten. | Private Schlüssel sollen nicht von normalen Benutzern lesbar sein. | 750 wäre möglich, aber 700 ist konservativer. |
sudo cp pki/ca.crt ... |
Kopiert das öffentliche CA-Zertifikat. | Der Server braucht die CA, um Clientzertifikate zu prüfen. | Die CA-Datei ist öffentlich. Sie ist nicht geheim. Der CA-Key ist geheim und gehört nicht hierher. |
sudo cp pki/issued/modern-server.crt ... |
Kopiert das Serverzertifikat. | OpenVPN präsentiert dieses Zertifikat den Clients. | Der Name ist frei wählbar, muss aber zur Config passen. |
sudo cp pki/private/modern-server.key ... |
Kopiert den privaten Server-Key. | Ohne privaten Schlüssel kann der Server sein Zertifikat nicht nutzen. | Der Key muss geschützt werden. Verlust oder Diebstahl bedeutet: Serverzertifikat neu erzeugen und altes sperren. |
sudo cp pki/crl.pem ... |
Kopiert die CRL. | OpenVPN kann gesperrte Clientzertifikate ablehnen. | Die CRL muss erneuert werden, nachdem Zertifikate widerrufen wurden. |
sudo chown -R root:root ... |
Setzt root als Besitzer. | Systemkonfiguration soll nicht normalen Benutzern gehören. | Je nach Distribution kann eine OpenVPN-Gruppe genutzt werden. Das sollte bewusst passieren, nicht zufällig. |
sudo chmod 600 ...modern-server.key |
Nur root darf den privaten Schlüssel lesen/schreiben. | Minimiert Risiko durch lokale Benutzer. | Wenn OpenVPN nach dem Start Rechte abgibt, liest es den Key vorher. 600 ist daher meistens korrekt. |
sudo chmod 644 ...crl.pem |
Macht die CRL für den OpenVPN-Prozess lesbar. | Nach Rechteabgabe an nobody muss OpenVPN die CRL weiterhin lesen können. |
640 root:nogroup ist restriktiver, setzt aber korrekte Gruppe voraus. |
10. Moderne TLS-Crypt-v2-Schlüssel erzeugen
sudo openvpn --genkey tls-crypt-v2-server /etc/openvpn/server/modern/tc2-server.key
sudo openvpn --tls-crypt-v2 /etc/openvpn/server/modern/tc2-server.key --genkey tls-crypt-v2-client /etc/openvpn/server/modern/phoenix-modern-werk1-tc2.key
sudo chmod 600 /etc/openvpn/server/modern/tc2-server.key
sudo chmod 600 /etc/openvpn/server/modern/phoenix-modern-werk1-tc2.key
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
openvpn --genkey tls-crypt-v2-server ... |
Erzeugt den serverseitigen Schlüssel für tls-crypt-v2. |
tls-crypt-v2 schützt den TLS-Kontrollkanal und erlaubt client-spezifische Schlüssel. |
tls-crypt ist kompatibler, nutzt aber einen gemeinsamen statischen Schlüssel. tls-auth ist noch kompatibler, schützt aber nicht die Vertraulichkeit des Kontrollkanals. |
openvpn --tls-crypt-v2 ... --genkey tls-crypt-v2-client ... |
Erzeugt einen client-spezifischen tls-crypt-v2-Schlüssel. |
Jeder Client bekommt einen eigenen Zusatzschlüssel. Das passt zur Idee: ein Zertifikat, ein Standort, ein Schlüssel. | Du kannst optionale Metadaten in Clientkeys einbetten. Für eine klare Betriebsdokumentation reicht der einfache Weg. |
chmod 600 ... |
Schränkt den Zugriff auf die Schlüsseldateien ein. | TLS-Crypt-Schlüssel sind geheim. Wer sie hat, kommt zwar ohne Zertifikat nicht rein, aber er reduziert deine Schutzschicht. | 640 mit dedizierter Gruppe ist möglich, wenn du sauber mit Gruppenrechten arbeitest. |
11. Moderne OpenVPN-Serverkonfiguration
Datei:
/etc/openvpn/server/modern.conf
port 1194
proto udp4
dev tun0
topology subnet
server 10.255.0.0 255.255.255.0
client-config-dir /etc/openvpn/server/modern/ccd
ccd-exclusive
route 192.168.101.0 255.255.255.0
ca /etc/openvpn/server/modern/pki/ca.crt
cert /etc/openvpn/server/modern/pki/issued/modern-server.crt
key /etc/openvpn/server/modern/pki/private/modern-server.key
dh none
tls-groups X25519:secp256r1:X448:secp384r1
tls-server
remote-cert-tls client
verify-client-cert require
tls-version-min 1.2
data-ciphers AES-256-GCM:CHACHA20-POLY1305:AES-128-GCM
auth SHA256
tls-cert-profile preferred
tls-crypt-v2 /etc/openvpn/server/modern/tc2-server.key
allow-compression no
crl-verify /etc/openvpn/server/modern/crl.pem
keepalive 10 60
explicit-exit-notify 1
persist-key
persist-tun
user nobody
group nogroup
verb 3
11.1 Jede Zeile der modernen Konfiguration erklärt
| Zeile | Was macht sie? | Warum diese Wahl? | Alternativen / Hinweise |
|---|---|---|---|
port 1194 |
OpenVPN lauscht auf UDP-Port 1194. | 1194 ist der offiziell/typisch verwendete OpenVPN-Port. Im betrieblichen Umfeld ist der Default sinnvoll, weil Firewalls, Doku und Monitoring dadurch klar bleiben. | Du könntest den Port ändern, etwa auf 443 oder 11940, um den Dienst etwas zu verschleiern. Das ist aber keine echte Sicherheit und führt im Betrieb gern zu Verwirrung. |
proto udp4 |
Nutzt UDP über IPv4 als Transportprotokoll. | UDP ist für VPN-Tunnel meist besser als TCP, weil TCP-over-TCP bei Paketverlust schlecht performt. udp4 erzwingt IPv4. |
Alternativen: udp für IPv4/IPv6 je nach System, tcp-server für TCP, tcp4-server für TCP nur IPv4. TCP nur verwenden, wenn UDP nicht möglich ist. |
dev tun0 |
Erstellt oder nutzt das TUN-Interface tun0. |
TUN ist Layer 3 und ideal für Routing zwischen Netzen. Der feste Name erleichtert Firewallregeln. | Alternative: dev tun lässt OpenVPN automatisch wählen. dev tap wäre Layer-2-Bridging und für dieses Site-to-Site-Konzept nicht empfehlenswert. |
topology subnet |
Vergibt Client-IP-Adressen wie in einem normalen Subnetz. | Damit kann ein Client z. B. 10.255.0.10/24 bekommen. Das ist verständlicher als alte /30-Paarungen. |
Alternative: topology net30 für sehr alte Clients. Für moderne und die meisten industriellen Geräte ist subnet sinnvoller. |
server 10.255.0.0 255.255.255.0 |
Aktiviert Servermodus und definiert das VPN-Transfernetz. | Der Server bekommt üblicherweise 10.255.0.1, Clients erhalten Adressen aus 10.255.0.0/24. Dieses Netz ist nur für den Tunnel. |
Du kannst jedes private, nicht überlappende Netz verwenden, z. B. 10.8.0.0/24. Wichtig ist: keine Überschneidung mit LANs. |
client-config-dir /etc/openvpn/server/modern/ccd |
Aktiviert client-spezifische Konfigurationsdateien. | Jeder Standort bekommt eine Datei mit seinem Common Name. Darin stehen feste VPN-IP und iroute. |
Der Pfad ist frei wählbar. Trennung je Instanz verhindert Fehlzuordnungen. |
ccd-exclusive |
Nur Clients mit vorhandener CCD-Datei dürfen verbinden. | Das ist für Site-to-Site wichtig: Kein Zertifikat soll ohne explizite Netzzuordnung online gehen. | Ohne diese Option könnten gültige Zertifikate ohne definierte Policy verbinden. Das ist für Betriebsnetze unsauber. |
route 192.168.101.0 255.255.255.0 |
Fügt auf Serverseite eine Route zum entfernten Standortnetz hinzu. | Der Linux-Kernel gibt Pakete zu diesem Netz an OpenVPN. OpenVPN braucht zusätzlich das passende iroute in der CCD-Datei. |
Für jeden Standort kommt eine weitere route-Zeile dazu. Bei vielen Standorten kann Routenmanagement über Scripts oder Konfigurationsmanagement erfolgen. |
ca .../ca.crt |
Pfad zum CA-Zertifikat. | Damit prüft der Server, ob Clientzertifikate von der richtigen CA signiert wurden. | Die CA-Datei ist öffentlich. Der private CA-Key darf nicht auf den VPN-Server. |
cert .../modern-server.crt |
Pfad zum Serverzertifikat. | Der Server weist sich damit gegenüber Clients aus. | Der Name ist frei, muss aber mit der Datei existieren. |
key .../modern-server.key |
Pfad zum privaten Server-Schlüssel. | Der private Schlüssel gehört zum Serverzertifikat und muss geheim bleiben. | Rechte: üblicherweise 600 root:root. |
dh none |
Deaktiviert klassische statische DH-Parameter. | Wir nutzen moderne elliptische Gruppen über tls-groups. Das ist für neue Clients zeitgemäßer. |
Für Legacy-Clients kann stattdessen dh /pfad/dh.pem nötig sein. Genau darum gibt es die zweite Instanz. |
tls-groups X25519:secp256r1:X448:secp384r1 |
Legt erlaubte TLS-Gruppen/Kurven in Prioritätsreihenfolge fest. | X25519 ist eine moderne Standardwahl. secp256r1 ist sehr kompatibel. X448 und secp384r1 bieten weitere starke Optionen. | Alternative: Option weglassen und Bibliotheksdefaults nutzen. Oder ecdh-curve prime256v1 für ältere Clients, aber das ist weniger modern. |
tls-server |
Setzt diese Instanz explizit in die TLS-Serverrolle. | Im Servermodus meist implizit, aber lesbar und eindeutig. | Normalerweise reicht server .... Explizit schadet hier nicht. |
remote-cert-tls client |
Prüft, ob die Gegenstelle ein Client-Zertifikat verwendet. | Verhindert, dass Zertifikate mit falscher Rolle akzeptiert werden. | Nicht weglassen. Alternativ gibt es spezifischere Prüfungen über verify-x509-name, die zusätzlich genutzt werden können. |
verify-client-cert require |
Erzwingt ein gültiges Clientzertifikat. | Ohne gültiges Zertifikat keine Verbindung. Das ist zentral für Site-to-Site. | Der Default ist in vielen Fällen bereits require, aber explizit dokumentiert ist besser. |
tls-version-min 1.2 |
Erlaubt nur TLS 1.2 oder höher. | TLS 1.0/1.1 gehören nicht mehr in ein neues betriebliches VPN. | Noch härter wäre TLS 1.3-only, aber das bricht viele Clients. Für OpenVPN-Umgebungen ist TLS 1.2+ der realistische harte Mindeststandard. |
data-ciphers AES-256-GCM:CHACHA20-POLY1305:AES-128-GCM |
Liste erlaubter Datenkanal-Cipher. | Nur moderne AEAD-Cipher. Kein CBC-Fallback in der modernen Instanz. | Du könntest AES-128-GCM vor CHACHA20-POLY1305 setzen, wenn AES-Hardwarebeschleunigung erwartet wird. Wichtig: kein BF-CBC. |
auth SHA256 |
Setzt SHA-256 als HMAC-Digest für relevante Kontroll-/Nicht-AEAD-Fälle. | SHA-256 ist ein robuster Standard. Bei AEAD-Ciphers ist der Datenkanal bereits integriert authentifiziert. | Alternativen: SHA384 oder SHA512. SHA1 nicht neu verwenden. |
tls-cert-profile preferred |
Verlangt brauchbare Zertifikats-/Signaturalgorithmen. | Schiebt alte SHA1-/zu schwache Zertifikate aus dem Weg. | Bei sehr alten Geräten kann legacy nötig sein. In diesem Dokument bleiben auch ältere Geräte bei neu erzeugten Zertifikaten, daher preferred. |
tls-crypt-v2 .../tc2-server.key |
Aktiviert TLS-Crypt-v2 für den Kontrollkanal. | Beste Wahl für moderne Setups: client-spezifische Zusatzschlüssel, Schutz vor Scans und Müllpaketen. | Alternativen: tls-crypt oder tls-auth. Für Legacy nutzen wir bewusst tls-auth. |
allow-compression no |
Verbietet Kompression. | Kompression in verschlüsselten Tunneln erhöht Angriffsfläche und ist für Site-to-Site meist unnötig. | Nicht compress setzen. Auch nicht „nur testweise“, diese berühmten letzten Worte der IT. |
crl-verify .../crl.pem |
Aktiviert Prüfung der Zertifikatssperrliste. | Verlorene oder kompromittierte Clients können gesperrt werden. | Ohne CRL musst du im Ernstfall CA oder Serverpolicy gröber ändern. CRL ist Pflicht für sauberen Betrieb. |
keepalive 10 60 |
Sendet Keepalive-Pings und erkennt tote Verbindungen. | Gerade Mobilfunk-/Industrieverbindungen profitieren davon. | Alternative: manuell ping und ping-restart setzen. keepalive ist die einfache Form. |
explicit-exit-notify 1 |
Informiert UDP-Clients beim Serverstopp/Restart. | Clients reconnecten sauberer und schneller. | Nur für UDP sinnvoll. Bei TCP nicht verwenden. |
persist-key |
Liest Schlüssel bei internen Restarts nicht neu. | Hilft, wenn OpenVPN nach Start Rechte reduziert. | Weglassen ist möglich, aber weniger robust. |
persist-tun |
Hält das TUN-Interface bei Restarts offen. | Verhindert unnötiges Interface-Flapping und reduziert Routingstörungen. | Weglassen führt zu mehr Bewegung im Netzwerkstack. Betrieb mag keine Bewegung. |
user nobody |
OpenVPN läuft nach Initialisierung als Benutzer nobody. |
Reduziert Schaden bei Prozesskompromittierung. | Manche Distributionen nutzen einen dedizierten Benutzer wie openvpn. Das ist sogar besser, wenn vorhanden. |
group nogroup |
OpenVPN wechselt in die Gruppe nogroup. |
Passend zu nobody auf Debian/Ubuntu. |
Auf RHEL heißt die Gruppe oft nobody. Mit getent group nogroup prüfen. |
verb 3 |
Setzt das Log-Level auf normalen Betriebswert. | Genug Informationen für Betrieb, nicht zu viel Rauschen. | Für Fehlersuche kurzzeitig verb 4 oder verb 5. Nicht dauerhaft extrem hoch loggen. |
12. Moderne CCD-Datei für einen Phoenix-Standort
Datei:
/etc/openvpn/server/modern/ccd/phoenix-modern-werk1
ifconfig-push 10.255.0.10 255.255.255.0
iroute 192.168.101.0 255.255.255.0
push "route 10.10.0.0 255.255.255.0"
| Zeile | Was macht sie? | Warum diese Wahl? | Alternativen / Hinweise |
|---|---|---|---|
ifconfig-push 10.255.0.10 255.255.255.0 |
Weist diesem Client immer die feste VPN-IP 10.255.0.10 zu. |
Feste Tunnel-IP macht Firewallregeln, Logs und Betrieb nachvollziehbar. | Bei topology net30 wäre die Syntax anders: dann braucht man ein IP-Paar. Mit topology subnet ist diese Form korrekt. |
iroute 192.168.101.0 255.255.255.0 |
Sagt OpenVPN intern: Dieses entfernte LAN gehört zu genau diesem Client. | Das ist der Kern deines „ein Zertifikat = ein Netzwerk“-Modells. | Ohne iroute kennt der Linux-Kernel vielleicht die Route, aber OpenVPN weiß nicht, zu welchem Client das Paket soll. |
push "route 10.10.0.0 255.255.255.0" |
Sendet dem Client eine Route zum zentralen LAN. | Der Phoenix-Router weiß dadurch, dass 10.10.0.0/24 über den VPN-Tunnel erreichbar ist. |
Viele Industrieclients ignorieren Push-Routen oder konfigurieren Remote Networks im Webinterface. Dann diese Route dort manuell eintragen. |
13. Moderne Instanz aktivieren
sudo install -m 640 modern.conf /etc/openvpn/server/modern.conf
sudo openvpn --config /etc/openvpn/server/modern.conf --test-crypto
sudo systemctl enable --now openvpn-server@modern
sudo systemctl status openvpn-server@modern
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
sudo install -m 640 modern.conf /etc/openvpn/server/modern.conf |
Kopiert die Konfigurationsdatei an den OpenVPN-Serverpfad. | 640 verhindert unnötige Lesbarkeit durch normale Benutzer. |
Du kannst auch direkt mit einem Editor in /etc/openvpn/server/modern.conf schreiben. |
sudo openvpn --config ... --test-crypto |
Testet kryptografische Optionen der Konfiguration. | Findet Fehler bei Ciphers, TLS-Gruppen oder Pfaden früher. | Zusätzlich sudo openvpn --config ... im Vordergrund starten, wenn du detaillierte Fehlermeldungen brauchst. |
sudo systemctl enable --now openvpn-server@modern |
Aktiviert und startet die systemd-Instanz modern. |
OpenVPN lädt dabei /etc/openvpn/server/modern.conf. |
Nur starten: systemctl start .... Nur Boot-Aktivierung: systemctl enable .... |
sudo systemctl status openvpn-server@modern |
Zeigt Dienststatus und letzte Logs. | Erste Prüfung, ob der Dienst läuft. | Detaillierter: journalctl -u openvpn-server@modern -f. |
14. Kompatible PKI erstellen
make-cadir ~/easy-rsa-compat
cd ~/easy-rsa-compat
./easyrsa init-pki
./easyrsa build-ca
./easyrsa build-server-full compat-server nopass
./easyrsa build-client-full phoenix-legacy-werk1 nopass
./easyrsa gen-crl
Die Befehle entsprechen der modernen PKI. Der wichtige Unterschied ist nicht Easy-RSA selbst, sondern die spätere OpenVPN-Konfiguration. Auch ältere Geräte sollen neue, saubere Zertifikate bekommen. Altgerät heißt nicht: altes SHA1-Zertifikat aus irgendeinem Export von 2014 behalten, nur weil es noch blinkt.
15. Kompatible PKI-Dateien kopieren
sudo install -d -m 750 /etc/openvpn/server/compat/pki
sudo install -d -m 750 /etc/openvpn/server/compat/pki/issued
sudo install -d -m 700 /etc/openvpn/server/compat/pki/private
sudo cp pki/ca.crt /etc/openvpn/server/compat/pki/ca.crt
sudo cp pki/issued/compat-server.crt /etc/openvpn/server/compat/pki/issued/compat-server.crt
sudo cp pki/private/compat-server.key /etc/openvpn/server/compat/pki/private/compat-server.key
sudo cp pki/crl.pem /etc/openvpn/server/compat/crl.pem
sudo chown -R root:root /etc/openvpn/server/compat
sudo chmod 600 /etc/openvpn/server/compat/pki/private/compat-server.key
sudo chmod 644 /etc/openvpn/server/compat/crl.pem
16. Kompatible TLS-Auth- und DH-Dateien erzeugen
sudo openvpn --genkey secret /etc/openvpn/server/compat/ta.key
sudo chmod 600 /etc/openvpn/server/compat/ta.key
sudo openssl dhparam -out /etc/openvpn/server/compat/dh.pem 3072
sudo chmod 644 /etc/openvpn/server/compat/dh.pem
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
sudo openvpn --genkey secret .../ta.key |
Erzeugt einen statischen Schlüssel für tls-auth. |
tls-auth ist älter und breiter unterstützt als tls-crypt-v2. Es schützt den Kontrollkanal per HMAC gegen fremde Pakete. |
tls-crypt wäre besser, wenn das Altgerät es unterstützt. tls-crypt-v2 ist modern, aber auf älteren Appliances oft nicht verfügbar. |
sudo chmod 600 .../ta.key |
Beschränkt Zugriff auf den statischen Schlüssel. | Der Key ist geheim und wird auch auf dem Client gebraucht. | Bei Verteilung an Phoenix-Geräte sicher übertragen, z. B. per SFTP, nicht per E-Mail im Klartext, weil wir keine Museumsführung durch Sicherheitsfehler brauchen. |
sudo openssl dhparam -out .../dh.pem 3072 |
Erzeugt klassische Diffie-Hellman-Parameter mit 3072 Bit. | Das ist kompatibler als moderne ECDH-only-Konfigurationen und bleibt trotzdem stark genug für eine Legacy-Instanz. | 4096 ist möglich, aber langsamer. 2048 ist kompatibler/schneller, aber weniger großzügig bei der Sicherheitsmarge. |
sudo chmod 644 .../dh.pem |
Macht die DH-Parameter lesbar. | DH-Parameter sind nicht geheim; OpenVPN muss sie lesen können. | 640 mit passender Gruppe ist möglich. |
17. Kompatible OpenVPN-Serverkonfiguration
Datei:
/etc/openvpn/server/compat.conf
port 1195
proto udp4
dev tun1
topology subnet
server 10.254.0.0 255.255.255.0
client-config-dir /etc/openvpn/server/compat/ccd
ccd-exclusive
route 192.168.201.0 255.255.255.0
ca /etc/openvpn/server/compat/pki/ca.crt
cert /etc/openvpn/server/compat/pki/issued/compat-server.crt
key /etc/openvpn/server/compat/pki/private/compat-server.key
dh /etc/openvpn/server/compat/dh.pem
tls-server
remote-cert-tls client
verify-client-cert require
tls-version-min 1.2
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC
data-ciphers-fallback AES-256-CBC
cipher AES-256-CBC
auth SHA256
tls-cert-profile preferred
tls-auth /etc/openvpn/server/compat/ta.key 0
allow-compression no
crl-verify /etc/openvpn/server/compat/crl.pem
keepalive 10 60
explicit-exit-notify 1
persist-key
persist-tun
user nobody
group nogroup
verb 3
17.1 Jede Zeile der kompatiblen Konfiguration erklärt
| Zeile | Was macht sie? | Warum diese Wahl? | Alternativen / Hinweise |
|---|---|---|---|
port 1195 |
OpenVPN lauscht für die kompatible Instanz auf UDP-Port 1195. | Da 1194 bereits von modern.conf genutzt wird, braucht diese Instanz einen zweiten Port. |
Mit zwei öffentlichen IPs könnte auch diese Instanz Port 1194 nutzen, gebunden an eine andere IP. Auf einer IP müssen Ports verschieden sein. |
proto udp4 |
Nutzt UDP über IPv4. | Auch für Altgeräte ist UDP normalerweise zuverlässiger für VPN als TCP. | TCP ist möglich, wenn Firewalls UDP blockieren. Dann proto tcp4-server, aber nur als Notlösung. |
dev tun1 |
Nutzt ein eigenes TUN-Interface für die kompatible Instanz. | Getrennt von tun0, damit Firewallregeln klar zwischen modern und legacy unterscheiden können. |
Automatische Benennung mit dev tun ist bequemer, aber schlechter für eindeutige Firewallregeln. |
topology subnet |
Verwendet normales Subnetzmodell für Client-IP-Zuweisung. | Auch viele ältere Geräte kommen damit klar. Es macht CCDs lesbarer. | Wenn ein sehr alter Client Probleme macht, kann topology net30 nötig sein. Dann müssen ifconfig-push-Zeilen angepasst werden. |
server 10.254.0.0 255.255.255.0 |
Definiert das VPN-Transfernetz der kompatiblen Instanz. | Getrennt vom modernen Netz, damit Logs, Routen und Firewallregeln eindeutig bleiben. | Jedes private, nicht überlappende Netz ist möglich. Nicht dasselbe Netz wie bei modern verwenden. |
client-config-dir /etc/openvpn/server/compat/ccd |
Aktiviert CCD-Dateien für Legacy-Clients. | Auch ältere Geräte werden pro Common Name fest gebunden. | Pfad frei wählbar, aber pro Instanz getrennt halten. |
ccd-exclusive |
Nur Clients mit CCD-Datei dürfen verbinden. | Gerade im Legacy-Bereich willst du keine Überraschungsclients. | Weglassen wäre bequemer und schlechter. Bequemlichkeit ist der natürliche Feind des Audits. |
route 192.168.201.0 255.255.255.0 |
Serverroute zum Legacy-Standortnetz. | Der Kernel gibt Pakete zu diesem Netz an die OpenVPN-Instanz. | Für jeden Legacy-Standort eigene Route hinzufügen. |
ca .../ca.crt |
CA der kompatiblen PKI. | Getrennte Vertrauensdomäne für Legacy-Clients. | Du könntest eine gemeinsame CA nutzen, aber getrennt ist sauberer. |
cert .../compat-server.crt |
Serverzertifikat der kompatiblen Instanz. | Separates Zertifikat verhindert Vermischung mit modern. | Name frei wählbar, Datei muss existieren. |
key .../compat-server.key |
Privater Serverkey der kompatiblen Instanz. | Muss geheim bleiben. | Rechte restriktiv setzen. |
dh /etc/openvpn/server/compat/dh.pem |
Nutzt klassische Diffie-Hellman-Parameter. | Das ist für ältere Clients zuverlässiger als ECDH-only mit dh none. |
Moderner wäre dh none plus ecdh-curve oder tls-groups. Für Legacy ist klassische DH robuster. |
tls-server |
Setzt TLS-Serverrolle. | Eindeutige Rollenverteilung. | Meist durch server implizit. |
remote-cert-tls client |
Prüft Client-Zertifikatrolle. | Auch alte Geräte sollen korrekte Clientzertifikate nutzen. | Nicht weglassen. |
verify-client-cert require |
Erzwingt Clientzertifikate. | Ohne Zertifikat keine Verbindung. | Benutzer/Passwort zusätzlich möglich, aber für Router-Site-to-Site normalerweise nicht nötig. |
tls-version-min 1.2 |
Erlaubt TLS 1.2 oder höher. | Das ist die harte Untergrenze. TLS 1.0/1.1 wird nicht zugelassen. | Wenn ein Gerät nur TLS 1.0 kann, sollte es ersetzt oder isoliert werden. Eine produktive Betriebsverbindung mit TLS 1.0 ist keine „Kompatibilität“, sondern eine Altlast mit Netzwerkkabel. |
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC |
Erlaubt moderne GCM-Cipher und als letzten Fallback AES-256-CBC. | GCM bleibt bevorzugt. CBC wird nur zugelassen, damit ältere Clients ohne moderne Cipher-Aushandlung funktionieren. | Härter wäre ohne CBC. Genau das macht modern.conf. Schwächer wäre Blowfish/Camellia/3DES. Nicht verwenden. |
data-ciphers-fallback AES-256-CBC |
Fallback für Clients ohne moderne Data-Cipher-Negotiation. | Manche ältere OpenVPN-Clients können die neue Cipher-Aushandlung nicht sauber. Dieser Fallback hält sie kompatibel. | Nur setzen, wenn du solche Geräte wirklich brauchst. Nicht in der modernen Instanz verwenden. |
cipher AES-256-CBC |
Legacy-Hinweis für ältere Clients/Kompatibilität. | Ältere Clientkonfigurationen erwarten oft explizit cipher AES-256-CBC. In neueren OpenVPN-Versionen ist data-ciphers maßgeblich. |
Auf modernen Clients besser GCM nutzen. Diese Zeile ist bewusst Legacy-Futter. |
auth SHA256 |
HMAC-Digest SHA-256. | Für CBC und tls-auth relevant und sicherer als SHA1. |
SHA384/SHA512 möglich, aber SHA256 ist breit kompatibel und sicher. |
tls-cert-profile preferred |
Erzwingt moderne Zertifikatsqualität. | Wir erzeugen neue Zertifikate, also gibt es keinen Grund für schwache Zertifikate. | Falls ein Altgerät alte SHA1-Zertifikate zwingend braucht, wäre legacy möglich. Das ist hier bewusst nicht empfohlen. |
tls-auth .../ta.key 0 |
Aktiviert HMAC-Schutz für den TLS-Kontrollkanal. 0 ist die Server-Key-Direction. |
Sehr kompatibel und trotzdem nützlich gegen fremde Pakete/Scans. | Besser wäre tls-crypt, falls der Client es kann. tls-crypt-v2 ist die moderne Variante, aber weniger kompatibel. |
allow-compression no |
Verbietet Kompression. | Auch für Legacy bleibt Kompression aus. Kompatibilität ist kein Freifahrtschein für bekannte Angriffsflächen. | Nicht compress setzen. Wenn ein Altclient Kompression erzwingt, muss dessen Konfig angepasst werden. |
crl-verify .../crl.pem |
Prüft gesperrte Zertifikate. | Geräte können verloren gehen oder ausgemustert werden. CRL macht Sperrung sauber möglich. | CRL regelmäßig nach Widerruf erneuern. |
keepalive 10 60 |
Prüft Tunnel-Lebendigkeit. | Gerade Mobilfunkrouter brauchen robuste Reconnect-Erkennung. | Werte können erhöht werden, wenn instabile Mobilfunkstrecken sonst zu hektisch reconnecten. |
explicit-exit-notify 1 |
Informiert UDP-Clients beim Serverstopp. | Sauberere Reconnects. | Bei TCP nicht verwenden. |
persist-key |
Hält Key-Material über interne Restarts. | Hilft bei Dienste-Reconnects nach Rechteabgabe. | Weglassen selten sinnvoll. |
persist-tun |
Hält TUN-Interface offen. | Stabilere Routen und weniger Flapping. | Weglassen erzeugt mehr Interface-Bewegung. |
user nobody |
Reduziert Prozessrechte. | Besser als dauerhaft root. | Dedizierter OpenVPN-Benutzer ist noch sauberer, wenn Distribution ihn anbietet. |
group nogroup |
Reduziert Gruppenzugehörigkeit. | Debian/Ubuntu-kompatibel. | Auf anderen Distributionen prüfen. |
verb 3 |
Normales Log-Level. | Geeignet für Dauerbetrieb. | verb 4 zur Fehlersuche, danach zurück. |
18. Kompatible CCD-Datei für einen Phoenix-Standort
Datei:
/etc/openvpn/server/compat/ccd/phoenix-legacy-werk1
ifconfig-push 10.254.0.10 255.255.255.0
iroute 192.168.201.0 255.255.255.0
push "route 10.10.0.0 255.255.255.0"
| Zeile | Was macht sie? | Warum diese Wahl? | Alternativen / Hinweise |
|---|---|---|---|
ifconfig-push 10.254.0.10 255.255.255.0 |
Feste VPN-IP für den Legacy-Phoenix. | Logs und Firewallregeln bleiben eindeutig. | Bei net30 andere Syntax nötig. |
iroute 192.168.201.0 255.255.255.0 |
Bindet das entfernte Legacy-LAN an genau diesen Client. | Kern des Site-to-Site-Routings. | Pro Client nur die Netze eintragen, die wirklich hinter diesem Router liegen. |
push "route 10.10.0.0 255.255.255.0" |
Teilt dem Client die Route zum zentralen LAN mit. | Damit Rückverkehr sauber über den Tunnel geht. | Wenn das Phoenix-Gerät Push-Routen ignoriert, Route im Phoenix-Webinterface als Remote Network setzen. |
19. Kompatible Instanz aktivieren
sudo install -m 640 compat.conf /etc/openvpn/server/compat.conf
sudo openvpn --config /etc/openvpn/server/compat.conf --test-crypto
sudo systemctl enable --now openvpn-server@compat
sudo systemctl status openvpn-server@compat
20. IP-Forwarding aktivieren
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-openvpn-routing.conf
sudo sysctl --system
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
echo ... | sudo tee ... |
Schreibt die Kernel-Option für IPv4-Forwarding in eine persistente sysctl-Datei. | Der Server muss Pakete zwischen LAN und VPN weiterleiten dürfen. | Temporär ginge sudo sysctl -w net.ipv4.ip_forward=1, ist aber nach Reboot weg. |
sudo sysctl --system |
Lädt alle sysctl-Konfigurationen neu. | Die Änderung wird sofort aktiv, ohne Reboot. | sudo sysctl -p /etc/sysctl.d/99-openvpn-routing.conf lädt nur diese Datei. |
21. Firewall mit nftables
Datei:
/etc/nftables.conf
table inet filter {
chain input {
type filter hook input priority filter;
policy drop;
iif lo accept
ct state established,related accept
udp dport 1194 accept
udp dport 1195 accept
ip saddr 10.10.0.0/24 tcp dport 22 accept
}
chain forward {
type filter hook forward priority filter;
policy drop;
ct state established,related accept
iif "tun0" ip saddr 192.168.101.0/24 ip daddr 10.10.0.0/24 accept
oif "tun0" ip saddr 10.10.0.0/24 ip daddr 192.168.101.0/24 accept
iif "tun1" ip saddr 192.168.201.0/24 ip daddr 10.10.0.0/24 accept
oif "tun1" ip saddr 10.10.0.0/24 ip daddr 192.168.201.0/24 accept
}
}
21.1 Erklärung der Firewall-Regeln
| Regel | Was macht sie? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
table inet filter |
Erstellt eine Tabelle für IPv4 und IPv6. | Auch wenn wir hier IPv4 routen, ist inet ein moderner Standard. |
table ip filter nur für IPv4 wäre auch möglich. |
chain input |
Regeln für Verkehr zum VPN-Server selbst. | Schützt den Serverdienst und Adminzugänge. | Input ist nicht Forwarding. Das wird gern verwechselt, weil Netzwerkbegriffe offenbar absichtlich Menschen ärgern. |
policy drop |
Standard: alles verwerfen, was nicht erlaubt ist. | Whitelist-Prinzip. Sicherer als nachträglich Dinge zu verbieten. | Für Testbetrieb kann accept helfen, produktiv ist drop besser. |
iif lo accept |
Erlaubt Loopback-Verkehr. | Lokale Prozesse brauchen Loopback. | Nicht entfernen. Viele Dienste erwarten das. |
ct state established,related accept |
Erlaubt Antworten zu bestehenden Verbindungen. | Ohne diese Regel würde selbst erlaubter Verkehr keine Rückantwort bekommen. | Connection Tracking ist Standard bei zustandsbehafteten Firewalls. |
udp dport 1194 accept |
Erlaubt moderne OpenVPN-Instanz. | Notwendig für modern.conf. |
Wenn du Port änderst, hier mitändern. |
udp dport 1195 accept |
Erlaubt kompatible OpenVPN-Instanz. | Notwendig für compat.conf. |
Bei zwei öffentlichen IPs und gleichem Port anders lösen. |
ip saddr 10.10.0.0/24 tcp dport 22 accept |
Erlaubt SSH nur aus dem zentralen LAN. | Adminzugang sollte nicht aus dem Internet offen sein. | Besser: dediziertes Adminnetz, Jump Host oder Out-of-band-Management. |
chain forward |
Regeln für weitergeleitete Pakete zwischen VPN und LAN. | Site-to-Site-Verkehr läuft durch Forwarding, nicht Input. | Hier liegt die eigentliche Zugriffskontrolle. |
iif "tun0" ip saddr 192.168.101.0/24 ip daddr 10.10.0.0/24 accept |
Erlaubt Verkehr vom modernen Phoenix-LAN ins zentrale LAN. | Nur das erwartete Quellnetz darf über tun0 kommen. |
Noch restriktiver: nur einzelne Zielhosts und Ports erlauben. |
oif "tun0" ip saddr 10.10.0.0/24 ip daddr 192.168.101.0/24 accept |
Erlaubt Rück-/Hinverkehr vom zentralen LAN zum modernen Phoenix-LAN. | Bidirektionaler Site-to-Site-Zugriff. | Für reine Fernwartung kann man Richtung und Ports stärker einschränken. |
iif "tun1" ... 192.168.201.0/24 ... |
Erlaubt Verkehr vom kompatiblen Phoenix-LAN ins zentrale LAN. | Legacy-Clients werden getrennt von modern behandelt. | Bei höherem Risiko Legacy nur zu einzelnen Wartungsservern zulassen. |
oif "tun1" ... 192.168.201.0/24 ... |
Erlaubt Verkehr vom zentralen LAN zum kompatiblen Phoenix-LAN. | Notwendig für bidirektionale Kommunikation. | Ports einschränken, wenn möglich. |
Regeln laden:
sudo nft -c -f /etc/nftables.conf
sudo systemctl reload nftables
sudo nft list ruleset
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
sudo nft -c -f /etc/nftables.conf |
Prüft die Syntax, ohne Regeln zu laden. | Verhindert, dass du dich mit einer kaputten Firewall selbst aussperrst. | Immer vor Reload ausführen. Wirklich. |
sudo systemctl reload nftables |
Lädt die Firewallregeln neu. | Aktiviert die neue Policy. | restart geht auch, reload ist meist sauberer. |
sudo nft list ruleset |
Zeigt aktive nftables-Regeln. | Kontrolle, ob wirklich geladen wurde, was dokumentiert ist. | Für gezielte Analyse: nft list table inet filter. |
22. Rückrouten im zentralen LAN
Alle Systeme im zentralen LAN müssen wissen, wie sie die Phoenix-Netze erreichen. Am besten setzt du die Routen auf dem zentralen LAN-Gateway.
ip route add 192.168.101.0/24 via 10.10.0.5
ip route add 192.168.201.0/24 via 10.10.0.5
10.10.0.5 ist hier die LAN-IP des OpenVPN-Servers.
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
ip route add 192.168.101.0/24 via 10.10.0.5 |
Sagt dem LAN-Gateway: Das moderne Phoenix-LAN erreichst du über den OpenVPN-Server. | Ohne Rückroute gehen Antworten ins Default-Gateway und verschwinden. | Wenn der OpenVPN-Server selbst das Default-Gateway des LANs ist, brauchst du diese Zusatzroute eventuell nicht. |
ip route add 192.168.201.0/24 via 10.10.0.5 |
Dasselbe für das kompatible Phoenix-LAN. | Jedes entfernte LAN braucht eine Route. | Bei vielen Standorten statische Routen zentral dokumentieren oder per Routingprotokoll lösen. |
23. Clientdateien für Phoenix-Geräte
23.1 Moderne Variante
Auf das Phoenix-Gerät bzw. in dessen OpenVPN-Client-Konfiguration gehören:
ca.crtphoenix-modern-werk1.crtphoenix-modern-werk1.keyphoenix-modern-werk1-tc2.keyfürtls-crypt-v2- Serveradresse/FQDN
- Port
1194 - UDP
- TUN/routed mode
- lokales Netz
192.168.101.0/24 - Remote-Netz
10.10.0.0/24
23.2 Kompatible Variante
ca.crtphoenix-legacy-werk1.crtphoenix-legacy-werk1.keyta.keyfürtls-auth- Key direction beim Client:
1 - Serveradresse/FQDN
- Port
1195 - UDP
- TUN/routed mode
- lokales Netz
192.168.201.0/24 - Remote-Netz
10.10.0.0/24
Kein NAT auf dem Phoenix aktivieren, wenn echte bidirektionale Site-to-Site-Kommunikation gewünscht ist. NAT nur verwenden, wenn Netze überlappen oder ein Gerät technisch nicht sauber routen kann. NAT macht Fehler nicht weg, es zieht ihnen nur eine Jacke an.
24. Zertifikat widerrufen
Wenn ein Gerät verloren geht, ausgetauscht oder kompromittiert wird:
cd ~/easy-rsa-modern
./easyrsa revoke phoenix-modern-werk1
./easyrsa gen-crl
sudo cp pki/crl.pem /etc/openvpn/server/modern/crl.pem
sudo systemctl reload openvpn-server@modern
Für die kompatible Instanz entsprechend:
cd ~/easy-rsa-compat
./easyrsa revoke phoenix-legacy-werk1
./easyrsa gen-crl
sudo cp pki/crl.pem /etc/openvpn/server/compat/crl.pem
sudo systemctl reload openvpn-server@compat
| Befehl | Was macht er? | Warum so? | Optionen / Alternativen |
|---|---|---|---|
./easyrsa revoke NAME |
Markiert das Zertifikat als widerrufen. | Das Zertifikat soll nicht mehr verbinden dürfen. | Name muss dem Zertifikatsnamen/Common Name entsprechen. |
./easyrsa gen-crl |
Erzeugt eine aktualisierte CRL. | OpenVPN liest nicht die Easy-RSA-Datenbank, sondern die CRL-Datei. | Nach jedem Widerruf erforderlich. |
sudo cp pki/crl.pem ... |
Kopiert die neue CRL in den OpenVPN-Pfad. | Nur dann nutzt der Server den neuen Sperrstand. | Mit Konfigurationsmanagement automatisieren, wenn viele Standorte existieren. |
sudo systemctl reload ... |
Lädt den OpenVPN-Dienst neu. | Damit die neue CRL verwendet wird. | Wenn Reload nicht reicht, restart. Kurze Unterbrechung beachten. |
25. Wichtige Tests
sudo openvpn --version
sudo openvpn --show-groups
sudo openvpn --show-ciphers
sudo openvpn --show-digests
journalctl -u openvpn-server@modern -f
journalctl -u openvpn-server@compat -f
ip addr show tun0
ip addr show tun1
ip route
ping 10.255.0.10
ping 192.168.101.1
ping 10.254.0.10
ping 192.168.201.1
| Befehl | Was prüft er? | Warum wichtig? |
|---|---|---|
openvpn --version |
OpenVPN-Version und verwendete Crypto-Bibliothek. | Optionen wie tls-groups hängen von Version und Bibliothek ab. |
openvpn --show-groups |
Verfügbare TLS-Gruppen/Kurven. | Wichtig für die moderne Instanz. |
openvpn --show-ciphers |
Verfügbare Datenkanal-Cipher. | Prüft, ob GCM/ChaCha20/CBC verfügbar sind. |
openvpn --show-digests |
Verfügbare HMAC-Digests. | Prüft SHA256-Unterstützung. |
journalctl -u ... -f |
Live-Logs der Instanz. | Beste erste Diagnose bei Verbindungsproblemen. |
ip addr show tun0/tun1 |
Existenz und IPs der Tunnelinterfaces. | Zeigt, ob OpenVPN Interface und Server-IP gesetzt hat. |
ip route |
Kernel-Routingtabelle. | Prüft, ob Routen zu entfernten LANs existieren. |
ping ... |
Basis-Erreichbarkeit. | Ping ist kein vollständiger Test, aber ein guter Anfang. Danach Porttests machen. |
26. Typische Fehlerbilder
| Symptom | Wahrscheinliche Ursache | Prüfung | Lösung |
|---|---|---|---|
| Client verbindet, LAN dahinter ist nicht erreichbar. | iroute fehlt oder falscher CCD-Dateiname. |
journalctl, CCD-Datei, Common Name prüfen. |
CCD-Datei exakt nach CN benennen und iroute setzen. |
| Server-LAN erreicht Phoenix, aber Antwort kommt nicht zurück. | Rückroute im zentralen Gateway oder Phoenix-LAN fehlt. | ip route auf Gateway/Phoenix prüfen. |
Route zum Gegennetz über OpenVPN/Phoenix setzen. |
| TLS-Handshake schlägt bei modern fehl. | Client unterstützt tls-crypt-v2, tls-groups oder Cipher nicht. |
Logs mit verb 4, Clientfähigkeiten prüfen. |
Gerät in kompatible Instanz verschieben. |
| Kompatibler Client verbindet nicht wegen Cipher. | Client nutzt anderen Legacy-Cipher. | Clientconfig prüfen: cipher. |
Client auf AES-256-CBC stellen. Keine Blowfish-Fallbacks neu einführen. |
| Clientzertifikat wird abgelehnt. | Falsche CA, CRL, Zertifikatsrolle oder Ablaufdatum. | openssl x509 -in client.crt -text -noout. |
Neues Zertifikat erzeugen und korrekt verteilen. |
OpenVPN startet nicht nach user nobody. |
Dateien nach Rechteabgabe nicht lesbar, oft CRL. | journalctl prüfen. |
CRL lesbar machen, z. B. chmod 644 crl.pem oder passende Gruppe setzen. |
27. Optionen, die bewusst nicht verwendet werden
| Option | Warum nicht? |
|---|---|
duplicate-cn |
Würde erlauben, dass mehrere Clients dasselbe Zertifikat nutzen. Das zerstört dein Modell „ein Zertifikat = ein Netzwerk“. Nicht verwenden. |
client-to-client |
Würde VPN-Clients untereinander sprechen lassen. Für zentrale Fernwartung meist unnötig und riskant. Nur aktivieren, wenn Standort-zu-Standort-Kommunikation ausdrücklich benötigt wird. |
push "redirect-gateway def1" |
Würde gesamten Internetverkehr des Clients über den VPN-Server schicken. Für Site-to-Site-Fernwartung unnötig. |
compress |
Kompression bleibt aus Sicherheitsgründen deaktiviert. |
compat-mode |
OpenVPN warnt, dass diese Option Defaults auf weniger empfohlene Werte zurücksetzen kann. Besser einzelne Kompatibilitätsoptionen bewusst setzen. |
cipher BF-CBC |
Blowfish/CBC ist historischer Altbestand und gehört nicht in neue Konfigurationen. |
tls-version-min 1.0 |
Für neue betriebliche Setups nicht mehr akzeptabel. Wenn ein Gerät das braucht, gehört es in ein stark isoliertes Migrationsprojekt, nicht in normale Produktion. |
28. Wann welche Instanz?
| Gerät/Client | Instanz | Begründung |
|---|---|---|
| Aktueller OpenVPN-Client 2.5/2.6, aktueller Linux-/Windows-Client, moderne Appliance. | modern.conf |
AEAD-Cipher, tls-crypt-v2, moderne Gruppen, keine Legacy-Fallbacks. |
| Phoenix-/Industriegerät mit Unterstützung für AES-GCM und tls-crypt-v2. | modern.conf |
Wenn getestet stabil: modern verwenden. |
| Phoenix-/Industriegerät mit älterem OpenVPN-Stack, kein tls-crypt-v2, eventuell nur AES-256-CBC. | compat.conf |
Weiterhin TLS 1.2+, Zertifikate, CRL und Firewall, aber mit Legacy-Fallback. |
| Gerät kann nur TLS 1.0, Blowfish oder Kompression. | Keine der beiden Instanzen ohne Sonderfreigabe. | Das ist nicht „älter“, das ist ein Sicherheitsproblem mit Gehäuse. Ersatz oder isolierte Übergangslösung planen. |
29. Betriebs-Checkliste
- Für jeden Standort eindeutiges LAN-Netz vergeben.
- Pro Standort eigenes Zertifikat erzeugen.
- Common Name exakt dokumentieren.
- CCD-Datei mit exakt gleichem Namen erstellen.
- Feste VPN-IP vergeben.
iroutefür das entfernte Standortnetz setzen.routein der Serverinstanz ergänzen.- Firewallregel für genau dieses Standortnetz ergänzen.
- Rückroute im zentralen LAN setzen.
- Phoenix-Firewall für VPN ↔ LAN konfigurieren.
- Keine Kompression.
- Kein
duplicate-cn. - CRL nach jedem Widerruf neu erzeugen und verteilen.
- Logs prüfen und Zertifikatsablauf überwachen.
30. Kurzfazit
modern.conf ist die Zielkonfiguration: stark, sauber und ohne Legacy-Ballast. compat.conf ist die pragmatische Betriebsvariante für ältere Phoenix-/Industrieclients: weiterhin kontrolliert, getrennt, mit Zertifikaten, CRL, Firewall und TLS 1.2+, aber mit bewusstem AES-256-CBC-Fallback und tls-auth.
Der entscheidende Sicherheitsgewinn entsteht nicht durch eine einzelne magische Zeile. Er entsteht durch die Kombination aus getrennter Instanz, eindeutiger PKI, ccd-exclusive, iroute, festen IPs, restriktiver Firewall, deaktivierter Kompression und sauberer Zertifikatssperrung. Kryptografie ist wichtig, aber Routingfehler und Copy-Paste-Zertifikate ruinieren dir den Tag meist schneller. Menschen nennen das dann „gewachsene Infrastruktur“.