Inhalt

3. Verschlüsselungsarten

Das Kapitel 1 Einführung sollte unbedingt gelesen werden, da hier u.a. die Hintergründe erklärt und das in den Beispielen benutzte Netzwerk beschrieben werden. Weiterhin ist die Verzeichnisstruktur und Namensgebung der Schlüssel und Zertifikate die ich hier benutze nicht zwingend vorgeschrieben. Um Fehlern vorzubeugen würde ich jedoch jedem empfehlen diese (zumindest vorläufig) auch zu benutzen. D.h. man kann seine Konfigurationsdateien, Schlüssel und Zertifikate eigentlich ablegen wo man will und muss nur die entsprechenden Pfade anpassen.

Bei OpenVPN werden für die Verschlüsselung OpenSSL-Bibliotheken benutzt. Man unterscheidet bei der Authentisierung zwischen symmetrischer und asymmetrischer Verschlüsselung:
Der VPN-Server übernimmt die Authentifizierung der Gegenstelle und Verschlüsselung der Daten. Am besten eignet sich hierzu das Public-Key-Verfahren mit Zertifikaten. Ich werde jedoch beide beschreiben. Ich möchte auch noch erwähnen, dass die Schlüssel und Zertifikate auch mit OpenVPN generiert werden können. Da diese hierbei auch nur per Skripten mit OpenSSL erstellt werden, beschreibe ich hier nur die OpenSSL-Methoden.

3.1 Statischer Schlüssel - Preshared Key

Wenn man nur Verbindungen zwischen zwei festen Punkten herstellen will und ein sicherer Schlüsselaustausch gewährleistet ist reicht eine Verschlüsselung mit einem statischen Schlüssel. Wenn man jedoch mehreren Clients Zugriff geben will ist von diesem abzuraten. Denn wenn nur ein Client keinen Zugriff mehr erhalten soll, müssen alle einen neuen Schlüssel bekommen. Bei Zertifikaten ist dies anders.
Dieser Schlüssel darf nur Lese- und Schreibzugriff für root erhalten! Er sollte im Config-Verzeichnis von OpenVPN liegen. Der Name ist frei wählbar. Es ist auch sinnvoll diesen Schlüssel für erste Versuche mit OpenVPN zu benutzen, da diese Art der Verschlüsselung einfacher zu konfigurieren ist.

3.1.1 Statischen Schlüssel generieren

openvpn --genkey --secret /etc/openvpn/private/static_key.txt
chmod go-rwx /etc/openvpn/private/static_key.txt
Mein erstellter Schlüssel sieht wie folgt aus:
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
86c9fa44dee190b86849fb1153eacd3d
d95f7bcb2d1c3f7ec76bb8bf7f86c806
7fa447dfb2b9f821609b4972d56d3395
eec0096b3e843fb2b9b73b282922d969
fac037b0fb21440e84f8178aad1ae768
fcf243d0ad1d5b6a51935de3a82b8f2f
88f8054ba7f34a769b67d8d3aa85a927
a0db9e8b76a26efc9cc64a5565763e5d
c3af77c487ba46272a2b8c7438da6c04
bbf4ba26d37bb38cada305fe0ea17eda
e7d5e2b7828cc1fc6c41220eb2c991c0
c770d6453df29ba953993f36708dfa67
eb5ddcb1e1a75d6e88ca7c766fc90990
6d374e1e0bf3eb08631c662fd4fa4f9f
91455ff675b85e60fabcde221c497e14
80b04b22165e5ae2f305f62b6e045c3d
-----END OpenVPN Static key V1-----

Dieser Schlüssel muss nun an alle Rechner, die Zugriff haben sollen verteilt und unter /etc/openvpn/private abgelegt werden. Wie man dies tut, bleibt jedem selbst überlassen (verschlüsselte Mail, Postweg,...). Ein Beispiel für die Konfiguration für OpenVPN mit statischem Schlüssel findet man in Kapitel 4.2.

3.2 Zertifikatbasiert - Public Key

Anm.: Wer nur statische Verschlüsselung benutzen will oder vorerst OpenVPN testen will kann dieses Kapitel überspringen und im Kapitel 4 weitermachen.

Das Problem bei einem 'normalen' öffentlichen Schlüssel ist, dass man (manchmal) nicht genau weiß ob der Schlüssel wirklich von demjenigen stammt, dessen Name er trägt. Hier kommen nun die Zertifikate zum Zug. Ein Zertifikat ist ein öffentlicher Schlüssel, bei dem eine Zertifizierungsstelle (Certification Authority - CA) mit ihrer digitalen Unterschrift bestätigt, dass die angegebene Identität korrekt ist. Speziell hierzu haben sich die X.509-Zertifikate etabliert (standardisiert von der International Telecommunications Union (ITU) und der ISO). Ein X.509-Zertifikat beinhaltet die Identität (in Form eines ‘X.500 Distinguished Name’ - DN), den öffentlichen Schlüssel und die digitale Signatur einer X.509 Zertifizierungsstelle.

Beispiel für den Distinguished Name:
Distinguished Name: 'C=DE, O=D.Bender GmbH, OU=Zentrale, CN=zentrale@64-bit.de'
  • enthält das Land 'DE'
  • die Organisation 'D.Bender GmbH
  • ein Abteilungsname (OU) 'Zentrale'
  • und als Common Name (CN) die E-Mail-Adresse 'zentrale@64-bit.de'
  • Optional:  u.a. das Bundesland (ST) oder eine Ortsbezeichnung (L)
der Name sollte so ausführlich wie möglich sein - um Verwechselungen zu vermeiden.

Bei Aufbau einer Verbindung werden zunächst die Zertifikate der Gegenstellen ausgetauscht und anhand des Stammzertifikats der CA überprüft. Ist alles korrekt, kann der VPN-Server sicher sein, dass der jeweils enthaltene öffentliche Schlüssel sicher ist.

3.2.1 Zertifikate generieren - OpenSSL

Anm.: für die folgenden Punkte habe ich verschiedene Skripte erstellt. Die Namen der Skripte stehen hinter den Überschriften. Man sollte die einzelnen Schritte jedoch zumindest einmal von Hand durchgehen um einen Lerneffekt zu erzielen. Die Scripte findet man hier. Weiterhin wird hier die Erstellung der Zertifikate nur 'grob' beschrieben. Weitere Details findet man in Dokumentationen zu OpenSSL.

Die Erstellung eines Zertifikats  läuft in mehreren Schritten ab:
 
X.509-Zertifikate kann man von einer Fremdfirma ausstellen lassen (und diese bezahlen) oder auch mit Hilfe von OpenSSL eine eigene Zertifizierungsstelle (Certification Authority - CA) erstellen und sie dann selbst generieren. Auf Fremdfirmen muss man nur zurückgreifen, wenn die Zertifikate an dritte weitergegeben werden soll. Für den haus- oder firmeninternen Gebrauch reicht eine eigene Zertifizierungsstelle.

3.2.2 Eigene Zertifizierungsstelle (Certification Authority - CA) Script: make_ca

Wir werden nun unsere eigene CA basteln. Vorab sollte man sich jedoch folgende Verzeichnisstruktur erstellen damit in dieser die selbst erstellten Zertifikate abgelegt werden können. Ich benutze als Zielpfad für die CA das Verzeichnis /usr/ssl (siehe auch openssl.cnf):

/usr/ssl
  |
  |
  |
  +--------- newcerts     -> neue Zertifikate
  |            |
  |            +------- 01.pem            OFFEN
  |                     02.pem
  |                     ZentraleCert.pem  (Zertifikat der Zentrale)
  |                     usw.
  |
  +--------- private      -> Private Schlüssel zu den Zertifikaten
  |            |
  |            +------ cakey.pem          (Schlüssel der Zertifizierungsstelle)
  |                    .rand              (Zufallszahl zum erstellen der Schlüssel)
  |                    ZentraleKey.pem    (Privater Schlüssel der Zentrale)
  |                    usw.
  +--------- crls        
  |            |
  |            +------- crl.pem           (Liste f. gesperrte Zertifikate)
  |
  |
  +-------   openssl.cnf
             cacert.pem                   (Stammzertifikat der Zertifizierungsstelle)  
             dh1024.pem
                  (Diffie-Hellmann-Parameter)
             index.txt                    (Zertifikat-Datenbank)
             serial                       (Seriennummer für Zertifikate)
             ZentraleReq.pem              (Zertifikatsanfrage für die Zentrale

Nach dem Anlegen der Verzeichnisse müssen noch verschiedene Dateien erstellt werden. Zunächst eine Datei mit einer Zufallszahl, anhand derer die Schlüssel erstellt werden. Dann eine index.txt die von der CA als Datenbank genutzt wird. In ihr werden neue Zertifikate und welche die gesperrt werden sollen eingetragen (aber nicht von Hand!). Und zu letzt noch eine Datei in der die Seriennummern der Zertifikate geführt werden.
# Zufallszahl (kann dauern)
genrandom 1024 /usr/ssl/private/.rand

# Inhaltsverzeichnis für die Zertifikate
cp /dev/null /usr/ssl/keys/index.txt

# Seriennummern
echo 01 > /usr/ssl/keys/serial

Vor der Erstellung der eigenen CA muss man noch die Datei openssl.conf in /usr/ssl/ kopieren (falls sie nicht schon dort liegt) und diese ein wenig anpassen. Hier ein Auszug:

[ CA_default ]

dir = /usr/ssl # Zielverzeichnis der CA
.
.
[ policy_match ]
countryName = match
localityName = optional
organizationName = supplied
organizationalUnitName = optional
commonName = supplied
.
.
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = DE
countryName_min = 2
countryName_max = 2
.
.
0.organizationName = Organization Name (eg, company)
0.organizationName_default = D.Bender GmbH
.
.

Die eigene CA benötigt zunächst einen möglichst 2048 Bit langen privaten Schlüssel (cakey.pem), der mit einem Passwort (Passphrase) (-des3) geschützt werden sollte - damit niemand, außer dem der diese Passphrase kennt, Zertifikate erstellen kann. Danach wird mit diesem Key das Stammzertifikat der CA (auch Root-Zertifikat, cacert.pem) erstellt. Mit diesem Zertifikat werden später die Zertifikate 'unterschrieben' bzw. beglaubigt.
Dann kann man im Zielverzeichnis der Zertifikate das CA-Root-Zertifikat erstellen:

# man muss sich im Verzeichnis '/usr/ssl' befinden
cd /usr/ssl

#
2048 Bit langer Private Key:
openssl genrsa -des3 -out private/cakey.pem 2048

# Root CA-Zertifikat mit 4 Jahren Gültigkeit
openssl req -new -x509 -days 1460 -key private/cakey.pem -out cacert.pem

# Überprüfung (zeigt den Schlüssel in lesbarer Form an)
openssl x509 -in cacert.pem -noout -text

# Diffie-Hellman-Parameter wg. Austausch des temporären Schlüssels
openssl dhparam -out dh1024.pem 1024

Das CA-Root-Zertifikat mit dem Namen cacert.pem muss auf jedem Rechner in das Verzeichnis /etc/openvpn/certs kopiert werden.

3.2.3 Eigene Zertifikate Script: make_cert NAME

Nach der Einrichtung einer eigenen CA kann man für die VPN-Server und Roadwarrios eigene Zertifikate erstellen. D.h. für die Verbindung wird ein Zertifikat für die Zentrale und eins für die Zweigstelle erstellt.
Man benötigt auch hier zuerst einen privaten Schlüssel (im Beispiel ZweigstelleKey.pem). Dieser kann auch mit dem Parameter '-des3'  per Passwort geschützt werden. Dann wird mit diesem Schlüssel eine Anfrage auf ein Zertifikat (Certificate Request) erstellt. Diese Anfrage wird dann von der eigenen CA 'unterschrieben' und damit beglaubigt. Bei der Erstellung werden verschiedene Informationen abgefragt. Wichtig sind hierbei der Organization Name (per Default aus der openssl.conf), Organizational Unit Name - z.B. der Name der Abteilung und der Common Name - der Benutzername des Zertifikates. Anhand des Organizational Unit Name und des Common Name werden die Zertifikate unterschieden. Sie sollten also nie zusammen doppelt vorkommen:

# 1024 Bit langer Private Key:
openssl genrsa -des3 -out private/ZweigstelleKey.pem 1024

# Antrag auf ein Zertifikat erstellen
openssl req -new -key private/ZweigstelleKey.pem \
-out ZweigstelleReq.pem

# Zertifikat 'unterschreiben'
openssl ca -keyfile private/cakey.pem \
-in ZweigstelleReq.pem \
-out newcerts/ZweigstelleCert.pem

OFFEN: Eingaben, verschiedene Namen
Die Zertifikate werden doppelt unter /usr/ssl/newcerts abgelegt: einmal mit dem Namen (ZweigstelleCert.pem) und mit einer Laufenden Nummer (01.pem, 02.pem usw.). Gleichzeitig wird ein Eintrag in die index.txt gemacht.
Der private Schlüssel (ZweigstelleKey.pem) eines Zertifikates muss auf dem entsprechenden Rechner unter /etc/openvpn/private/ und das Zertifikat (Public Key - ZweigstelleCert.pem) unter /etc/openvpn/certs abgelegt werden.
Auf das Verzeichnis /etc/openvpn/private/  und auf die darin enthaltenen Dateien darf nur der Benutzer root Zugriffsrechte besitzen!

3.2.4 Zertifikate zusammenfassen (PKCS12)

Unter Punkt 3.2.3 habe ich gezeigt wie man Zertifikate und private Schlüssel erstellt und wo man diese ablegen sollte. Nach dieser Anleitung muss man drei Dateien verwalten und diese auch in der Konfiguration angeben. Diese können jedoch auch in einer Datei zusammengefasst werden. Dazu dient das PKCS12-Format. Es beinhaltet nach der Erstellung das Stammzertifikat, das Zertifikat und den privaten Schlüssel. Falls der private Schlüssel per Passwort geschützt wurde, wird dieses nicht mit übernommen. Die PKCS-Datei wird jedoch standardmäßig selbst per Passwort geschützt. Wenn kein Passwort benutzt werden soll, einfach bei der Abfrage nur Enter drücken.

# ZweigstelleKey.pem, ZweigstelleCert.pem und cacert.pem zusammenfassen
openssl pkcs12 -export \
-inkey private/ZweigstelleKey.pem \
-in newcerts/ZweigstelleCert.pem \
-certfile cacert.pem \
-out newcerts/ZweigstelleP12.pem

3.2.5 Zertifikate widerrufen (Certificate Revocation List - CRL)  Script: make_crl

Die CRL ist eine Widerrufliste in der die ungültigen Zertifikate eingetragen sind und Zugänge aufgehoben werden können (z.B. beim Ausscheiden eines Mitarbeiters). Dazu wird periodisch eine gültige CRL erstellt. Einzelne Zertifikate können manuell gesperrt werden. Die Sperrung erfolgt dann beim nächsten Anlegen der Liste. Daher sollte die Liste entweder sofort nach deaktivieren eines Zertifikats oder, je nach Dringlichkeit, täglich oder wöchentlich per Cronjob erstellt werden.
Die gesperrten Zertifikate werden auch in der Datei index.txt verwaltet. Diese Datei wird dann beim Erstellen der CRL ausgelesen.

# das Zertifikat von 'meier' sperren (durch Neueintrag in index.txt)
openssl ca -revoke meierCert.pem # oder 'openssl ca -revoke ./newcerts/03.pem'

# CRL erstellen
openssl ca -gencrl -out crls/crl.pem

# Nummern der gesperrten Zertifikate anzeigen
openssl crl -in crls/crl.pem -noout -text

# Soll die CRL auf einem Server öffentlich zugänglich gemacht werden,
# muss sie noch ins binäre DER-Format konvertiert werden (ist also Optional)
openssl crl -in crls/crl.pem -outform der -out crls/cert.crl
Die Datei ./crls/crl.pem muss nach /etc/openvpn/certs kopiert werden.

Ein Script zur Erstellung einer CA ist hier zu finden (Script 'make_crl')

Ein Beispiel für die Konfiguration einer Verbindung zwischen zwei Rechnern mit Zertifikaten ist hier zu finden.

3.3 Zusammenfassung

Vorab möchte ich nochmals daran erinnern, dass die Ablageorte und Dateinamen der Keys und Zertifikate nicht vorgeschrieben sind. Für das Root-CA-Zertifikat wird in anderen Dokus auch häufig statt cacert.pem der Name ca.crt benutzt. Dies erfordert jedoch Änderungen an der  openssl.cnf. Ich habe daher die Namen gewählt die Standardmäßig bei OpenSSL benutzt werden. Anfänger sollten sich daher, zumindest vorläufig, ebenfalls daran halten.

3.3.1 Statischer Schlüssel

Da jeder der diesen Schlüssel benutzt Zugriff auf das VPN hat, sollte dieser mit besonderer Vorsicht weitergegeben werden. Je nachdem wie hoch die Sicherheit sein soll reicht es, meiner Meinung nach, aber aus den Schlüssel in ein Passwortgeschütztes Archiv zu packen, per Mail zu versenden und das Passwort telefonisch mitzuteilen.
Abgelegt werden sollte der Schlüssel auf allen Rechnern unter:
# Linux
/etc/openvpn/private

# Windows
C:\OpenVPN\config\private
Das Verzeichnis private sollte weiterhin nur Lese- und Schreibzugriff für root bzw. den Administrator haben.

3.3.2 Zertifikate

Die unter 3.2.3 erstellten Zertifikate sollten auf sichere Art auf das Zielsystem übertragen werden und dort gespeichert werden. Die Ablage der Dateien auf den Rechnern wurde in den obigen Punkten bereits erwähnt. Hier jedoch noch einmal eine Zusammenfassung:

VPN-Server:
CA-Root-Zertertifikat	/etc/openvpn/certs		(Datei 'cacert.pem')
CRL-Liste /etc/openvpn/crls (Datei 'crl.pem')
Private Key /etc/openvpn/private (Datei 'ZentraleKey.pem')
Zertifikat /etc/openvpn/certs (Datei 'ZentraleCert.pem')

VPN-Server/ -Client:
CA-Root-Zertifikat	/etc/openvpn/certs		(Datei 'cacert.pem')
Private Key /etc/openvpn/private (Datei 'ZweigstelleKey.pem)
Zertifikat /etc/openvpn/certs (Datei 'ZweigstelleCert.pem')

VPN-Windows-Client:
CA-Root-Zertifikat	C:\Openvpn\config\certs		(Datei 'cacert.pem')
Private Key C:\Openvpn\config\private (Datei 'RoadwarriorKey.pem)
Zertifikat C:\Openvpn\config\certs (Datei 'RoadwarriorCert.pem')


Oder in einer Tabelle:

Name
Rechner
Info
Geschützt
cacert.pem
Server & alle Clients
Root CA Zertifikat
Nein
cakey.pem
der Rechner, der die Zertifikate erstellt
Root CA Key
Ja
dh1024.pem
Server
Diffie Hellman Parameter Nein
ServerKey.pem
Server
Private Key Server
Ja
ServerCert.pem
Server
Zertifikat Server
Nein
ZweigstelleKey.pem Zweigstelle
Private Key Zweigstelle
Ja
ZweigstelleCert.pem Zweigstelle Zertifikat Zweigstelle Nein
RoadwarriorKey.pem
Roadwarrior Private Key Roadwarrior Ja
RoadwarriorCert.pem
Roadwarrior Zertifikat Roadwarrior Nein


Das Verzeichnis private sollte weiterhin nur Lese- und Schreibzugriff für root bzw. den Administrator haben.


Inhalt