Skip to content

EdgeRouter X, VPN Konfiguration

EdgeRouter X

SSH Copy ID for Copying SSH Keys to Servers EdgeRouter X – USA EdgeRouter X – DEGH-Repo zum Artikel

Der Artikel ist so aufgebaut, dass wir zuerst das Server-Zertifikat erstellen und dann die Client-Zertifikate.
Du findest einige Code-Snippets, um die erstellten Zertifikate und Keys aufzuräumen bzw. sie organisiert abzulegen.
Unterhalb der Headlines findest du teilweise Links zu relevanten Zusatzinfos oder einfach weiterführenden Links.

Hier die Voraussetzungen für die folgenden Steps:

  • Der Router ist in deinem Netzwerk verfügbar – z.B. unter https://192.168.0.1/ zu erreichen.
  • In weiterer Folge verwenden wir als „passphrase“ 1234 – für die Sicherheit ist das irrelevant, da die
    „passphrase“ in weiterer Folge wieder aus dem Zertifikat entfernt wird.
  • Klonen des GH-Repos in das lokale Verzeichnis ovpn
    git clone https://github.com/MikeMitterer/doku-EdgeRouter.git && \
    mv doku-EdgeRouter/ovpn . && rm -rf doku-EdgeRouter && cd ovpn
  • Wir brauchen die lokal die Directories bin, .template und .backup 
    mkdir -p bin .template .backup
  • Du kannst dich mit ssh ubnt@192.168.0.1 (Public-Key Auth) auf den Router einloggen.
  • Am Router das Directory /home/ubnt/auth
    mkdir -p /home/ubnt/auth
  • Füge im File .template/client.ovpn deine öffentliche IP-Adresse ein.

OpenVPN

OpenVPN Server on the EdgeRouter Lite EdgeRouter – OpenVPN Server OpenVPN on EdgeRouter

Server

Als Erstes holen wir uns das Script CA.pl vom Edge-Router auf den lokalen Rechner.
scp ubnt@192.168.0.1:/usr/lib/ssl/misc/CA.pl bin/

Du kannst das Script CA.pl entsprechend anpassen – hier meine Variante:

# CA.pl

# Gültigkeitsdauer von regulären Zertifikaten 
my $DAYS = "-days 1095"; # 3 years (vorher 365 Tage)
# Gültigkeitsdauer von CA-Zertifikaten (Certificate Authority)
my $CADAYS = "-days 3650";  # 10 years (vorher 3 Jahre)

Anzahl der Tage, für die zertifiziert wird, steht auch in /opt/homebrew/etc/openssl@3/openssl.cnf

# /opt/homebrew/etc/openssl@3/openssl.cnf

default_days = 1095
countryName_default		= AT
stateOrProvinceName_default	= Mein Bundesland
0.organizationName_default = MeineFirma GmbH

Ich habe den Wert von default_days = 1095 auch hier auf 3 Jahre (1095 Tage), angepasst.
Neben den default_days macht es auch Sinn, die Parameter für countryName_default, stateOrProvinceName_default und 0.organizationName_default anzupassen

Erstellen der Diffie-Hellman Parameter

Diffie-Hellman Key Exchange: How to Share a Secret

Der Diffie-Hellman-Algorithmus erlaubt es, einen gemeinsamen geheimen Schlüssel über eine unsichere Verbindung zu generieren, ohne dass dieser Schlüssel jemals direkt über das Netzwerk übertragen wird.

openssl dhparam -out dh.pem -2 1024
Root-CA erstellen

Das Root-CA (Root Certificate Authority) steht an der Spitze der Zertifizierungskette. Betriebssysteme und Browser vertrauen automatisch allen von ihr oder ihren Zwischen-CAs ausgestellten Zertifikaten. Dies bildet die Grundlage für sichere und vertrauenswürdige Kommunikation im Internet.

Bei der Erstellung eines Root-CA-Zertifikats sollte der Common Name (CN) so gewählt werden, dass er die Zertifizierungsstelle eindeutig identifiziert. Der Name sollte klar und spezifisch sein, um die Vertrauenswürdigkeit und Identifizierbarkeit der CA sicherzustellen.

Beispiele für den Common Name einer Root-CA:

  • MyCompany Root CA
  • ExampleCorp Root Certificate Authority
  • SecureVPN Root CA

./bin/CA.pl -newca – Erstellt ein neues Client-Zertifikat

Enter PEM pass phrase: 1234
Verifying - Enter PEM pass phrase: 1234
-----
...
If you enter '.', the field will be left blank.
-----
Organizational Unit Name (eg, section) []:Support
Common Name (e.g. server FQDN or YOUR name) []:MeineFirma Root CA
Email Address []:office@meinefirma.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Das Root-CA wird im Verzeichnis demoCA erstellt.

Du kannst im File demoCA/index.txt.attr den Wert für unique_subject = no auf ‚no‚ anpassen.
Machst du das nicht, bekommst du die Fehlermeldung: ERROR:There is already a certificate for /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=client1 sobald du (z.B. beim Testen) ein Zertifikat für denselben Client öfter als einmal anlegst.

Den private key findest du in ./demoCA/private/cakey.pem

Certificate Signing Request, CSR erstellen

Der Common Name sollte für den VPN-Server den Hostnamen oder die öffentliche IP-Adresse des Servers enthalten, z. B.:

  • vpn.example.com
  • z.B. 93.xxx.216.xxx

./bin/CA.pl -newreq

Enter PEM pass phrase: 1234
Verifying - Enter PEM pass phrase: 1234
-----
...
If you enter '.', the field will be left blank.
-----
Organizational Unit Name (eg, section) []:Support
Common Name (e.g. server FQDN or YOUR name) []: vpn.meinefirma.com
Email Address []: office@meinefirma.at
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Mit dem Befehl CA.pl -newreq wird eine neue Zertifikatsanforderung (Certificate Signing Request, CSR) erstellt. Konkret passiert Folgendes:

1. Private Key: Es wird ein neuer privater Schlüssel (private key) generiert. Dieser Schlüssel bleibt auf dem Server oder Client und sollte gut gesichert werden.

2. CSR-Datei: Die Zertifikatsanforderung enthält Informationen wie den Namen des Servers (oder Clients), die Organisation, den Standort und andere Details, die später im Zertifikat erscheinen. Sie wird in der Datei newreq.pem gespeichert.

3. Passphrase: Der Befehl fragt nach einer Passphrase, die den privaten Schlüssel schützt. Diese Passphrase kann später entfernt werden, um den Schlüssel ohne Eingabe zu verwenden.

Zusammengefasst: Mit CA.pl -newreq erzeugst du die Grundlage für ein neues Zertifikat, das anschließend von einer Certificate Authority (CA) signiert wird.

Der Request: newreq.pem und hier ist der private key newkey.pem

Signieren der Anfrage mit den CA-Schlüsseln

./bin/CA.pl -sign

Mit dem Befehl CA.pl -sign wird die zuvor erstellte Zertifikatsanforderung (CSR) mithilfe der Root-CA (Certificate Authority) signiert. Das bedeutet:

1. Überprüfung der Zertifikatsanforderung: Die CSR-Datei (newreq.pem), die mit dem Befehl CA.pl -newreq erstellt wurde, wird von der Root-CA überprüft und signiert.

2. Erstellung eines Zertifikats: Die Root-CA verwendet ihren privaten Schlüssel, um ein gültiges Zertifikat zu erstellen. Dieses Zertifikat enthält die Informationen aus der CSR und wird mit dem privaten Schlüssel der Root-CA signiert, um dessen Echtheit zu bestätigen.

3. Zertifikatsdatei: Nach der Signierung wird das Zertifikat in der Datei newcert.pem gespeichert. Es kann nun auf dem Server oder Client verwendet werden, um die Identität gegenüber anderen Systemen zu authentifizieren.

Zusammengefasst: CA.pl -sign nimmt die Zertifikatsanforderung und erstellt daraus ein signiertes Zertifikat, das von der Root-CA bestätigt wurde.

Es gibt jetzt 3 Files:

  • newcert.pem – Das Zertifikat für den Server
  • newkey.pem – Der private Key für den Server
  • newreq.pem – Das Request-File

Rename aller drei Files

mkdir -p .backup && mv newcert.pem server.pem && mv newkey.pem .backup/server-with-pass-phrase.key && mv newreq.pem server.req
Entferne die Passphrase für den erstellten Server-Key
openssl rsa -in .backup/server-with-pass-phrase.key -out server.key
TLS Auth Key generieren

Der TLS-Auth-Key wird bei einer OpenVPN-Verbindung zur Absicherung des TLS-Handshakes verwendet. Er dient dazu, den Datenverkehr zwischen Server und Client zu authentifizieren und zu signieren, wodurch unerwünschte Verbindungsversuche und bestimmte Angriffe, wie z. B. DoS- oder Man-in-the-Middle-Angriffe, verhindert werden. Nur Verbindungen mit dem richtigen TLS-Auth-Key werden akzeptiert, was die Sicherheit der VPN-Verbindung erhöht.

openvpn wird auf der cmdline benötigt. brew install openvpn (am Mac)

# Generieren des TLS Auth Key
openvpn --genkey secret ta.key  
Files in /config/auth

Die folgende Files wurden generiert und werden am EDGE-Router unter /config/auth  benötigt.

  • cacert.pem – Certificate Authority Zertifikat
  • server.pem – Das Zertifikat für den Server
  • server.key – Der private Key für den Server
  • dh.pem – Diffie-Hellman parameters
  • ta.key – Der TLS Auth Key

Hier kopieren wird die Files, die wir später am EDGE-Router benötigen, in das temporäre Directory: _edge/config/auth


mkdir -p ./_edge/config/auth && \
\cp -f demoCA/cacert.pem ./_edge/config/auth && \
\cp -f server.pem ./_edge/config/auth && \
\cp -f server.key ./_edge/config/auth && \
\cp -f dh.pem ./_edge/config/auth && \
\cp -f ta.key ./_edge/config/auth
Erstellen der Client-Zertifikate

Der Common Name (CN) sollte einen eindeutigen Namen enthalten, der den jeweiligen Client identifiziert, z. B.:

  • client1
  • mike-laptop

Der CN wird häufig zur Identifikation während der Verbindung genutzt, insbesondere wenn der Server überprüft, ob der Client ein gültiges Zertifikat vorlegt. In manchen Konfigurationen kann der CN auch verwendet werden, um spezifische Zugriffsbeschränkungen oder Rollen zu definieren.

Für die folgenden Schritte existiert ein Makefile! `make client CLIENT=client5` – du findest es im GH-Repo

Export der Client-Variablen, um die folgenden Snippets zu vereinfachen

export CLIENT="client1" && echo "Client: ${CLIENT}..."

./bin/CA.pl -newreq – Erstellt ein neues CSR für den Client

Enter PEM pass phrase: 1234 
Verifying - Enter PEM pass phrase: 1234
-----
...
If you enter '.', the field will be left blank.
-----
Common Name (e.g. server FQDN or YOUR name) []: client1

./bin/CA.pl -sign – Signieren des neuen Zertifikats
Zum Signieren des neuen Client-Zertifikates wird das File ./demoCA/private/cakey.pem benötigt.
Dieser „private-Key“ wurde bei der Erstellung des Root-CA generiert.

Directory für den Client anlegen

mkdir -p "clients/${CLIENT}"

Passphrase entfernen

mv newkey.pem ".backup/${CLIENT}-with-pass-phrase.key" && \
  openssl rsa -in ".backup/${CLIENT}-with-pass-phrase.key" -out "clients/${CLIENT}/${CLIENT}".key

Umbenennen der Files und kopieren in das Client-Verzeichnis

mv newcert.pem "clients/${CLIENT}/${CLIENT}.pem" && \
cp demoCA/cacert.pem "clients/${CLIENT}" && \
cp ta.key "clients/${CLIENT}"

Zwei der Dateien (cacert.pem und ta.key) sind für alle Clients gleich,
die Dateien ${CLIENT}.key und ${CLIENT}.pem ändern sich für jeden Benutzer.

Erstellen des .ovpn Files

Das Template kann als Grundlage für die Erstellung der OVPN-Files verwendet werden.

Copy/Paste in das Directory in dem die Zertifikate usw. liegen. (cacert.pem, client1.key, client1.pem…)

\cat .template/client.ovpn > \
clients/${CLIENT}/ml-${CLIENT}.ovpn && \
echo -e "# Generated - $(date -u +"%Y-%m-%dT%H:%M:%SZ") -----\n" >> clients/${CLIENT}/ml-${CLIENT}.ovpn && \
echo -e "# Client certificate and key" >> clients/${CLIENT}/ml-${CLIENT}.ovpn && \
echo -e "cert ${CLIENT}.pem" >> clients/${CLIENT}/ml-${CLIENT}.ovpn && \
echo -e "key ${CLIENT}.key" >> clients/${CLIENT}/ml-${CLIENT}.ovpn && \
echo -e "\n# # TLS authentication" >> clients/${CLIENT}/ml-${CLIENT}.ovpn && \
echo -e "tls-auth ta.key 1" >> clients/${CLIENT}/ml-${CLIENT}.ovpn 

Zip des ${CLIENT}-Verzeichnisses

# -r - recursive
# -j - junk the path
zip -rj clients/${CLIENT}.ovpn.zip clients/${CLIENT}

Transfer der Files zum EdgeRouter

scp -r ./_edge/config/auth/* ubnt@192.168.0.1:/home/ubnt/auth

Am Router werden die Files dann in das Verzeichnis /config/auth kopiert. Rechte müssen noch angepasst werden.

# /config/auth
cd /config/auth
cp /home/ubnt/auth/* .
sudo chown root:root *

# Rechte setzen
# sudo chmod 644 <file> - -rw-r--r--
# sudo chmod 600 <file> - -rw-------

Rechte so wie sie funktionieren [ 2024 09 30]:

-rw-r--r--    1 root     root           253 Sep 30 15:25 cacert.pem
-rw-r--r--    1 root     root           253 Sep 30 15:25 dh.pem
-rw-------    1 root     root          1704 Sep 30 15:25 server.key
-rw-r--r--    1 root     root          4630 Sep 30 15:25 server.pem
-rw-------    1 root     root           636 Sep 30 15:25 ta.key

Konfiguration des OpenVPN-Servers auf dem EdgeRouter

OpenVPN on EdgeRouterOpenVPN Server on the EdgeRouter Lite

Wir werden den OpenVPN-Server in drei Schritten konfigurieren. Dies wird als normaler Benutzer (nicht root) im Konfigurationsmodus durchgeführt. Zuerst müssen wir in diesen Modus wechseln:

configure

Firewall-Regeln

Setze die Firewall-Regeln, um die Verbindung zu erlauben. Der Standardport für OpenVPN ist 1194, aber ich werde den Server in diesem Beispiel auf Port 1195 setzen.

set firewall name WAN_LOCAL rule 30 action accept
set firewall name WAN_LOCAL rule 30 description openvpn

# Default port ist 1194
# set firewall name WAN_LOCAL rule 30 destination port 1195

set firewall name WAN_LOCAL rule 30 protocol udp
set firewall name WAN_LOCAL rule 30 log enabled

VPN-Server: Netzwerkeinstellungen

Nun werden wir die Netzwerkeinstellungen für den OpenVPN-Server definieren. Beachte das Diagramm vom Anfang, um die einzelnen Subnetze zu verdeutlichen und an deine spezifische Konfiguration anzupassen. Hier sind die wichtigen Punkte:

  • 192.168.0.0/24 ist das lokale Subnetz
  • 8.8.8.8 ist die IP-Adresse des Google DNS-Servers.
  • 10.0.0.0/24 ist das VPN-Subnetz. Die VPN-Clients erhalten eine IP-Adresse aus diesem Subnetz. Dieses Subnetz muss sich von deinem lokalen Subnetz unterscheiden (und auch von jedem anderen Subnetz, das du möglicherweise verwendest).
  • 1195 ist der Port, der für den Dienst verwendet wird. Denke daran, dass der Standardport 1194 ist, aber ich ändere ihn gerne, um einige grundlegende automatische Port-Scans zu vermeiden.

Eine persönliche Empfehlung: Tu dir selbst einen Gefallen und verwende NICHT 192.168.1.0/24 für das lokale oder VPN-Subnetz. Dies ist das Standardsubnetz vieler Heimgeräte und kann Probleme verursachen, wenn du versuchst, dich von diesen Geräten zu verbinden.

set interfaces openvpn vtun0 mode server
set interfaces openvpn vtun0 server subnet 10.0.0.0/24
set interfaces openvpn vtun0 server push-route 192.168.0.0/24
set interfaces openvpn vtun0 server name-server 8.8.8.8

# Wenn du den Port auf 1195 ändern möchtest
# set interfaces openvpn vtun0 openvpn-option "--port 1195"

VPN-Server: Zusätzliche und Sicherheitseinstellungen

Jetzt definieren wir einige zusätzliche Einstellungen, darunter auch welche zur Verbesserung der Sicherheit:

# set interfaces openvpn vtun0 openvpn-option --tls-server
set interfaces openvpn vtun0 openvpn-option "--tls-auth /config/auth/ta.key 0"
set interfaces openvpn vtun0 openvpn-option "--tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384"
# set interfaces openvpn vtun0 openvpn-option "--comp-lzo yes"
# set interfaces openvpn vtun0 openvpn-option --persist-key
# set interfaces openvpn vtun0 openvpn-option --persist-tun
# set interfaces openvpn vtun0 openvpn-option "--keepalive 10 120"
# set interfaces openvpn vtun0 openvpn-option "--user nobody"
# set interfaces openvpn vtun0 openvpn-option "--group nogroup"

Speichern der Konfiguration

Sobald alle Einstellungen vorgenommen wurden, committen und speichern wir die Änderungen. Der Server wird sofort starten.

commit
save

Falls nach dem Commit ein Fehler auftritt, gibt es wahrscheinlich einen Tippfehler oder Fehler in den Einstellungen. Überprüfe bitte jeden Befehl doppelt.

Wenn du den Fehler nicht findest, kannst du die Änderungen verwerfen:

 discard

Führe dann jeden „set“-Befehl einzeln aus und führe danach jeweils einen commit durch. Falls ein Fehler auftritt, war der vorherige set-Befehl falsch.

Sobald alle Einstellungen erfolgreich angewendet wurden, verlasse den Konfigurationsmodus mit exit

Die Config des lokalen Routers kann entweder mit https://192.168.0.1/#ConfigTree oder mit show configuration | no-more auf der Kommandozeile, überprüft werden.

openvpn vtun0 {
    mode server
    openvpn-option "--tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384"
    openvpn-option "--tls-auth /config/auth/ta.key 0"
    server {
        name-server 8.8.8.8
        push-route 192.168.0.0/24
        subnet 10.0.0.0/24
    }
    tls {
        ca-cert-file /config/auth/cacert.pem
        cert-file /config/auth/server.pem
        dh-file /config/auth/dh.pem
        key-file /config/auth/server.key
    }
}
# War ziemlich wichtig, ohne dieses Setting kam es zu einem Fehler
#     TunnelBlick 4.0.0 - asking for passphrase with openssl 3.0.13 but no passphrase is required
set interfaces openvpn vtun0 openvpn-option "--tls-auth /config/auth/ta.key 0"

Als Client verwende ich „Tunnelblick„. Wenn du die weiter oben erstellen clientX.zip-Files am Client-Rechner entpackst und in „Tunnelblick“ importierst, sollte deiner VPN-Route nichts mehr im Weg stehen!

An den Anfang scrollen