OpenVPN - Virtual Private Network
Willemers Informatik-Ecke

Virtual Private Networks erstellen eine virtuelle Netzwerkverbindungen. An dieser Stelle wird die Erstellung eines VPN mit der offenen Software openvpn beschrieben.

OpenVPN findet sich im Paket openvpn, das bei Debian und Ubuntu mit dem Befehl apt installiert werden kann. Vor der eigentlichen Installation sollten die Paketversionen auf den aktuellen Stand gebracht werden. Beide Befehle dürfen nur durch den Super-User ausgeführt werden.

sudo apt update
sudo apt install openvpn

Im folgenden sind hier kurz die Schritte zusammengefasst, die im Buch Linux-Server für Einsteiger ein wenig breiter dargestellt sind.

Konfigurationsdateien

Ein Rechner bietet anderen Rechnern einen Netzwerkzugang an. Diesen anbietenden Rechner bezeichnet der folgende Text als OpenVPN-Server.

Im Verzeichnis /etc/openvpn sind die Konfigurationsdateien von OpenVPN untergebracht.

Zertifikat mit Easy-RSA bauen

Für das Erstellen eines Zertifikats muss auch Easy-RSA installiert werden. Ein Zertifikat erlaubt, den Kommunikationspartner eindeutig zu identifizieren und auch gleich den Datenverkehr verschlüsseln.

sudo apt install easy-rsa
Nach der Installation von Easy-RSA befinden sich Beispiel-Konfigurationen im Verzeichnis /usr/share/easy-rsa. Die aktuellste OpenVPN-Datei heißt openssl

Zum Bau des Zertifikats wird eine Datei openssl.cnf benötigt. Diese finden Sie in /usr/share/easy-rsa, allerdings nur mit Versionsnummer. Wir kopieren Sie in ein Verzeichnis /etc/openvpn/easy-rsa unter dem Namen openssl.cnf.

# cd /etc/openvpn
# mkdir easy-rsa
# cd easy-rsa
# cp -rp /usr/share/easy-rsa/* .
# ln -s openssl-1.0.0.cnf openssl.cnf
Zuerst wird die Umgebung initialisiert, dann eventuelle fehlgeschlagene Vorversuche entsorgt. Dann wird zunächst ein Basiszertifikat (ca.crt) für die gesamte OpenVPN-Umgebung generiert. Dies kann entfallen, wenn Sie ein Original-Zertifikat einer Certificate Authority besitzen.

. ./vars
./clean-all
Nun wird das Zertifikat für die CA erstellt, die das Zertifikat abstempeln soll. Details dazu, was eine CA ist, finden Sie auf der Webseite zum Thema Zertifikate. Das Skript zum Erstellen des CA-Zertifkats lautet build-ca.
./build-ca
Country Name (2 letter code) [US]:DE
State or Province Name (full name) [CA]:SH
Locality Name (eg, city) [SanFrancisco]:Norgaardholz
Organization Name (eg, company) [Fort-Funston]:Zossenklau
Organizational Unit Name (eg, section) []:Zentrale
Common Name (eg, ... or your server's hostname) [...]:CAname
Name []:
Email Address [me@myhost.mydomain]:
Der relevante Eintrag ist Common Name. Dieser muss mit dem Namen der CA übereinstimmen.

Anschließend wird der Diffie-Hellman-Parameter erzeugt.

./build-dh
Als Ausgabe erscheinen wilde Zeichen, die aber niemandem gefährlich werden.

Anschließend wird für den OpenVPN-Server mit dem Skript build-key-server ein Schlüsselpaar erstellt. Das Skript benötigt als Parameter einen Namen, für den hier phantasieloserweise server verwendet wird.

./build-key-server server
Generating a 1024 bit RSA private key
..........................................++++++
...
Country Name (2 letter code) [US]:DE
State or Province Name (full name) [CA]:SH
..
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
...
The Subject's Distinguished Name is as follows
Certificate is to be certified until Nov 22 19:10:51 2023 GMT (3650 days)
Sign the certificate? [y/n]: 

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Für jeden zugriffsberechtigten Client wird ebenfalls ein Schlüsselpaar gebildet, hier durch den Namen client1 angedeutet.

./build-key client1
Generating a 2048 bit RSA private key
......+++
................................................................+++
writing new private key to 'client1.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:DE
State or Province Name (full name) [CA]:SH
Locality Name (eg, city) [SanFrancisco]:Norgaardholz
Organization Name (eg, company) [Fort-Funston]:Me
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:You
Common Name (eg, your name or your server's hostname) [client1]:
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easyrsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'DE'
stateOrProvinceName   :PRINTABLE:'SH'
localityName          :PRINTABLE:'Norgaardholz'
organizationName      :PRINTABLE:'Me'
organizationalUnitName:PRINTABLE:'You'
commonName            :PRINTABLE:'client1'
name                  :PRINTABLE:'EasyRSA'
emailAddress          :IA5STRING:'me@myhost.mydomain'
Certificate is to be certified until Mar 17 15:04:44 2036 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Der Client-Key wird für jeden benötigten Client mit einem eigenen Namen erneut erzeugt. Mit diesen Zertifikaten an der Hand kann nun die Konfiguration gebaut werden.

Die erzeugten Schlüssel befinden sich im Verzeichnis keys.

# ls keys/
01.pem  ca.key       client1.key  index.txt.attr      serial      server.csr
02.pem  client1.crt  dh2048.pem   index.txt.attr.old  serial.old  server.key
ca.crt  client1.csr  index.txt    index.txt.old       server.crt

Nun zu dem Teil, der im Buch Linux-Server für Einsteiger ein wenig kurz geraten ist.

Server-Einstellungen

Auf dem OpenVPN-Server wird nun eine Konfigurationsdatei erstellt, die eine virtuelle Netzwerkschnittstelle tun0 erstellt und darüber ein lokales Netzwerk 10.0.0.0/24 angelegt.

Die Beispielkonfiguration geht davon aus, dass der OpenVPN-Server in einem lokalen Netzwerk mit der Nummer 192.168.109.0/24 steht, da er das Routing für dieses Netzwerk an die Clients weiterpusht.

Ansonsten sieht man die Pfade auf die Zertifikate des Servers.

# /etc/openvpn/server.conf
dev tun0
proto udp # nicht noetig, da default
port 1194 # nicht noetig, da default
server 10.0.0.0 255.255.255.0
push "route 192.168.109.0 255.255.255.0"
dh   /etc/openvpn/easyrsa/keys/dh1024.pem
ca   /etc/openvpn/easyrsa/keys/ca.crt
cert /etc/openvpn/easyrsa/keys/server.crt
key  /etc/openvpn/easyrsa/keys/server.key
Die Verbindung wird wie üblich, per UDP über Port 1194 eingerichtet. Falls es erforderlich ist, durch eine Firewall zu gehen, die eine Kommunikation auf diesem Weg ausschließt, würde die folgende Einstellung dazu führen, dass der OpenVPN-Server wie ein gewöhnlicher Web-Server aussieht.
proto tcp-server
port 80
Das funktioniert natürlich nur, wenn auf dem Rechner nicht ein anderer Server wie etwa der Apache bereits den Port 80 bedient.

Der Server erzeugt das virtuelle Interface tun0 und verwendet für dieses den freien IP-Nummernkreis 10.0.0.0/24. Es kann eine beliebige Netzwerkadresse verwendet werden. Wichtig ist nur, dass es keine Konflikte mit den Netzwerkadressen der beteiligten Partnern gibt.

Mit dem push wird dem Client eine Route auf das serverseitige Netzwerk 192.168.109.0 zugeschoben. Nur so kann der Client mit den Netzwerkadressen im Zielnetz umgehen.

Damit der Client auch die anderen Rechner im Netzwerk erreichen kann, sind noch ein paar Schritte erforderlich:

Die passende Client-Konfiguration

Der Client nimmt mit dem folgenden Befehl Verbindung mit dem OpenVPN-Server auf:
sudo openvpn --config /etc/openvpn/client.conf
Dazu wird der Client eine Konfigurationsdatei wie die folgende verwenden:
dev tun0
client
proto udp # nicht noetig, da default
port 1194 # nicht noetig, da default
remote meinedyndns.adresseim.net
ca ca.crt
key client1.key
cert client1.crt
Hier wird ebenfalls eine virtuelle Netzwerkschnittstelle tun0 erstellt. Eine Netzwerkadresse des internen Netzwerks gibt der Client nicht an, weil er diese vom Server erfährt. Dafür muss er mit remote die öffentliche Adresse des Servers angeben. Hier wäre es beispielsweise eine dynamische DNS-Adresse. Zuletzt werden über ca, key und cert die Zertifikat-Dateien angegeben. In dieser Konfiguration liegen sie im Aufrufverzeichnis. Normalerweise sollte man den ganzen Pfad angeben.

Soll der Client auf einen OpenVPN-Server zugreifen, der Port 80 unter dem TCP-Protokoll bedient, müsste port und proto entsprechend geändert werden.

port 80
proto tcp-client
Mit den Befehlen netstat -i oder ifconfig tun0 kann man nun das Interface tun0 sehen. Mit netstat -r müsste eine Route im Netzwerk 10.0.0.0/24 auf den OpenVPN-Server zu sehen sein und ein Eintrag in das lokale Netzwerk des Zielrechners, der durch den Push-Befeh eingerichtet wurde.
netstat -r
Kernel-IP-Routentabelle
Ziel            Router          Genmask         Flags   MSS Fenster irtt Iface
default         192.168.99.1    0.0.0.0         UG        0 0          0 eth0
10.0.0.1        10.0.0.5        255.255.255.255 UGH       0 0          0 tun0
10.0.0.5        *               255.255.255.255 UH        0 0          0 tun0
192.168.99.0    *               255.255.255.0   U         0 0          0 eth0
192.168.109.0   10.0.0.5        255.255.255.0   UG        0 0          0 tun0
192.168.99.0/24 ist in diesem Fall das lokale Netzwerk auf der Client-Seite. Nur die Pakete für 10.0.0.0/24 und 192.168.109.0/24 gehen also über das VPN. Alle anderen Routen sind nicht betroffen.