Zum Inhalt springen

SSL-Zertifikate selbst signieren, Root und Client Zertifikate erstellen!

Du möchtest also lernen, wie man selbst signierte SSL-Zertifikate erstellt und sie sicher im Heimnetzwerk verwendet? Perfekt, denn genau das wird hier Schritt für Schritt erklärt. SSL-Zertifikate sind das Rückgrat der sicheren Kommunikation in deinem Netzwerk. In diesem Artikel wirst du lernen, wie man Root- und Client-Zertifikate erstellt. Mach dich bereit, in die Welt der Verschlüsselung einzutauchen und dein Heimnetzwerk abzusichern.

Ich selbst habe viele, viele Stunden damit zugebracht, mir das Wissen anzueignen, wie man SSL-Zertifikate erstellt und diese einsetzt. Damit du es leichter hast, habe ich diesen Artikel geschrieben. Denn es gibt viele vermeintlich einfache Einzeiler im Internet, doch wenn du die Hintergründe nicht verstehst, wird es schwer bei Fehlern.

Bei mir hat es damit angefangen, dass im Heimnetz eben immer „nicht sicher“ im Browser angezeigt wurde und ich Software auf meinem Proxmox Server installieren wollte, die eine SSL-Verschlüsselung zur korrekten Funktion voraussetzt.

Was wird für SSL-Zertifikate benötigt?

Du benötigst, um den Weg in diesem Artikel gehen zu können eine Linux Version mit OpenSSL, ich benutze auf meiner Installation Ubuntu 22.04.4 LTS. Diese Installation läuft auf einem Proxmox-Server in einem LXC Container, aber das nur am Rande, ist egal, wo die bei dir läuft. Hauptsache du hast SSH Zugriff z. B. durch Putty oder mit WinSCP. Dafür habe ich auch schon jeweils einen Artikel:

Ob OpenSSL installiert ist, kannst du mit diesem Befehl überprüfen: openssl version
Meine Version: OpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023)

Wenn kein OpenSSL vorhanden ist, dann muss es zuerst installiert werden.
Der Befehl sudo apt-get update aktualisiert die Liste der verfügbaren Pakete und deren Versionen in deinem System, installiert aber keine neuen Pakete oder aktualisiert keine vorhandenen Pakete. Zum Installieren von OpenSSL musst du noch die Befehlsfolge sudo apt-get install openssl ausführen.

sudo apt-get update
sudo apt-get install openssl

Das SSL-Root Zertifikat, die Wurzel

Tatsächlich habe ich viele Wege im Internet gefunden, wie ich zum Beispiel bei Pihole einem beliebten Ad-Blocker, ein Zertifikat installieren kann. Allerdings fehlte bei allen der Hinweis, dass eben das Root Zertifikat auf jedem Benutzer-Rechner im Heimnetz importiert werden muss. Sonst kann der Browser auf dem Benutzer-Rechner nicht die Vertrauenswürdigkeit des Client-Serverzertifikates überprüfen und zeigt eine Warnung an. Schon alleine der Umstand, dass mit Client-Zertifikaten eben die für die Server gemeint sind und eben nicht die, die auf dem Benutzer-Rechner installiert werden sollen, hat mich zeitweise fast in den Wahnsinn getrieben. Muss man halt wissen, jetzt ist es mir klar!

Im weiteren Verlauf sind Clients eben Benutzer-Rechner mit dem Browser, der die Website aufrufen soll und Client-Server eben die Server auf der die Website läuft. Wenn ich hier falsche Namen vergebe, darf das gerne in den Kommentaren richtig gestellt werden.

Zurück zum Root Zertifikat:

  • Wenn nur ein Root Zertifikat im Heimnetz vorhanden ist, so muss auch nur dieses auf den Clients importiert werden.
  • Von diesem Root Zertifikat aus habe ich alle Client-Server Zertifikate erzeugt.

Erstellen des privaten (Root) Schlüssels

Zuerst wird ein privater Schlüssel auf unserem Zertifizierungsrechner mit der Linux-Installation erstellt. Tatsächlich ist es allerdings egal, wo der Schlüssel erstellt wird. Ich bin als root Benutzer angemeldet und im root Benutzer Pfad erstelle ich ein /certs Ordner mit mkdir /root/certs Das nur der Ordnung halber. Mit cd /root/certs wird dann in den Ordner gewechselt und folgender Befehl ausgeführt:

openssl genrsa -des3 -out myCA.key 2048

Mit dem Befehl openssl genrsa -des3 -out myCA.key 2048 erstellst du ein RSA-Schlüsselpaar und sicherst es in einer Datei.
Hier die Erklärung, was jeder Teil des Befehls bewirkt:

  • openssl: Das ist das Hauptprogramm des OpenSSL-Pakets.
  • genrsa: Ein Unterbefehl von OpenSSL, mit dem du ein RSA-Schlüsselpaar generierst.
  • -des3: Eine Option, die festlegt, dass der private Schlüssel mit DES3 verschlüsselt wird, einer Methode der symmetrischen Verschlüsselung. Du wirst gebeten, ein Passwort einzugeben, das für die Verschlüsselung des privaten Schlüssels verwendet wird. Da dies der Schlüssel ist, mit dem alle Client-Server SSL-Zertifikate erstellt werden, sollte dieser schon verschlüsselt sein. Dieses Passwort ist dann erforderlich, wenn du den privaten Schlüssel verwenden möchtest.
  • -out myCA.key: Diese Option gibt an, dass der erzeugte private Schlüssel in die Datei myCA.key geschrieben wird.
  • 2048: Die Länge des Schlüssels in Bits. Ein 2048-Bit-Schlüssel wird erzeugt, was aktuell als sicher angesehen wird.

Insgesamt erzeugt dieser Befehl also ein 2048-Bit RSA-Schlüsselpaar, verschlüsselt den privaten Schlüssel mit DES3 und speichert ihn in der Datei myCA.key. Mit dem Befehl ls sollte die neue Datei myCA.key angezeigt werden. „CA“ steht im Übrigen für „Certificate authority“.

Erstellen einer Root Konfiguration

Bei der Erstellung von Root SSL-Zertifikate werden verschiedene Parameter abgefragt. Das kann, wenn man noch am Ausprobieren ist, sehr nervig sein. Viele Parameter sind für ein Zertifikat im Heimnetzwerk nicht nötig, doch wenn du gerade am Experimentieren bist muss immer jeder Parameter mit Enter bestätigt werden, einmal zu viel Enter gedrückt und nichts eingegeben und du fängst von vorne an.

Du erstellst also eine root.cnf mit

nano /root/certs/root.cnf

Und das ist der Inhalt:

[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[ dn ]
C=DE
ST=Rheinland-Pfalz
L=Speyer
O=Mojo Company
OU=SSL-Cert-Department
emailAddress=mustermann@mustermail.de
CN = ssl-cert.fritz.box

Die root.cnf Datei enthält Konfigurationseinstellungen für das Zertifikat. In diesem Fall enthält es Informationen wie die Anzahl der Bits im Schlüssel (default_bits) diese sollten der Anzahl Bits des privaten Schlüssels entsprechen, ob eine Eingabeaufforderung angezeigt werden soll (prompt), den zu verwendenden Nachrichtendigest-Algorithmus (default_md), und die zu verwendenden Distinguished Name Felder ([dn] Abschnitt). Diese Felder enthalten Informationen wie Land (C), Bundesland (ST), Ort (L), Organisation (O), Organisationsabteilung (OU), E-Mail-Adresse (emailAddress) und Common Name (CN).

Im Bereich unter [dn] kannst du natürlich deine Werte eintragen. Werte bei „O“ (Organisation) und „OU“ (Organisation Unit) sind nicht zwingend, helfen aber das Zertifikat später über die Suche zu finden.

Beim Common Name wird es interessant, denn ich habe eine Fritz!Box und mein Zertifizierungsserver den Hostnamen ssl-cert somit ist der „Fully Qualified Domain Name“ (FQDN): ssl-cert.fritz.box
Der FQDN ist in unserem Fall beim Root Zertifikat noch nicht so wichtig, aber später bei den Client-Serverzertifikaten, um so mehr.

Erstellen des Root-Zertifikates

Um nun das Root Zertifikat zu erstellen, folgenden Befehl eingeben:

openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem -config root.cnf

Bei der Erstellung wird das passwort des myCA.key abgefragt.
Der openssl req Befehl wird verwendet, um eine Zertifikatsanforderung oder ein selbst signiertes Zertifikat zu erstellen. Hier ist, was jeder Teil des Befehls bedeutet:

  • openssl req: Dieser Befehl wird verwendet, um eine Zertifikatsanforderung zu erstellen.
  • -x509: Dieser Schalter sagt OpenSSL, dass wir ein selbst signiertes Zertifikat erstellen möchten, anstatt eine Zertifikatsanforderung zu erstellen.
  • -new: Dieser Schalter sagt OpenSSL, dass wir eine neue Zertifikatsanforderung oder ein neues Zertifikat erstellen möchten.
  • -nodes: Dieser Schalter verhindert, dass das private Schlüsselzertifikat verschlüsselt wird. Wenn du das Zertifikat verschlüsselst, müsste bei jeder Benutzung das Passwort eingegeben werden, was unpraktisch wäre.
  • -key myCA.key: Dies gibt den Pfad und den Namen der Datei an, die den privaten Schlüssel enthält.
  • -sha256: Dies gibt den Hash-Algorithmus an, der zur Signierung des Zertifikats verwendet wird.
  • -days 1825: Dies gibt die Gültigkeitsdauer des Zertifikats in Tagen an. Hier könnte auch 3650 stehen für ca. 10 Jahre, muss jeder selbst wissen, wie lange die SSL-Zertifikate gültig sein sollen.
  • -out myCA.pem: Dies gibt den Pfad und den Namen der Datei an, in die das Zertifikat oder die Zertifikatsanforderung geschrieben werden soll.
  • -config root.cnf: Dies gibt den Pfad und den Namen der Konfigurationsdatei an, die beim Erstellen des Zertifikats oder der Zertifikatsanforderung verwendet werden soll.

Mit dem Befehl ls sollte auch die neue Datei myCA.pem angezeigt werden.

Schon ein ganzes Stück auf dem Weg zum Ziel geschafft!

Erstellen eines SSL Client-Server Zertifikats

Jetzt haben wir ein Root Zertifikat, mit dem die Client-Server SSL-Zertifikate erstellt werden können. Vorher wird aber vom Client-Server noch ein Request, eine sogenannte „Certificate Signing Request“ Datei benötigt. Der normale Vorgang ist der, dass auf dem Client-Server auch ein Privater Schlüssel erstellt wird, mit dem Schlüssel und den Konfigurationsdaten des Client-Servers wird dann die .csr Datei erstellt und an den Zertifizierungsserver gesendet. Das wird gemacht, damit keine Schlüssel durch das Internet geschickt werden müssen, sondern eben nur der Request. Da wir aber im Heimnetz sind und es im Grunde egal ist, wo wir den privaten Schlüssel des Client-Servers erstellen, machen wir das auch auf unserem Zertifizierungsserver im Heimnetz.

Erstellen des privaten Client-Serverschlüssels

Um die Zertifikatsdateien für die einzelnen Client-Server auseinander zu halten, habe ich mir angewöhnt den „Common Name“ als Dateinamen zu verwenden. Wenn ich nun bei meinem Beispiel von Pihole bleibe, ist der Dateiname pihole.fritz.box der Dateiname der .key Datei also pihole.fritz.box.key . Um einen privaten Client-Serverschlüssel zu erzeugen, gebe folgenden Befehl ein:

openssl genrsa -out pihole.fritz.box.key 2048

Der Befehl setzt sich genauso zusammen wie beim privaten Schlüssel für das Root Zertifikat, nur ohne Verschlüsselung und Passwort. Die Option -des3 fehlt. Wird auch in unserem Fall nicht benötigt, ansonsten müsste bei jedem benutzen des später erzeugten Client-Server Zertifikates das Passwort des privaten Schlüssels des Client-Servers eingegeben werden, sehr unpraktisch.

Erstellen einer Client-Server Konfiguration

Beim erstellen des Client-Server Zertifikats aus dem Root Zertifikat werden wieder einige Parameter abgefragt. Schon alleine um irgendwann später nachvollziehen zu können wie der Prozess funktioniert hat, habe ich auch hier eine client.cnf erstellt. Du erstellst also eine client.cnf mit:

nano /root/certs/client.cnf

Diese Unterscheidet sich bei mir nur durch den Common Name [CN] bei dem nun der Client-Server mit seiner FQDN eingetragen wird:

[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[ dn ]
C=DE
ST=Rheinland-Pfalz
L=Speyer
O=Mojo Company
OU=SSL-Cert-Department
emailAddress=mustermann@mustermail.de
CN = pihole.fritz.box

Erstellen der .csr Datei

Jetzt haben wir alles um die Request Datei zu erstellen. Ich gebe der .csr Datei wieder den Common Name des Client-Servers. Der folgende Befehl erzeugt nun zusammen mit dem privaten Client-Serverschlüssel die .csr :

openssl req -new -key pihole.fritz.box.key -out pihole.fritz.box.csr -config client.cnf

Hier ist, was jeder Teil des Befehls bedeutet:

  • openssl req: Dieser Befehl wird verwendet, um eine Zertifikatsignaturanforderung zu erstellen.
  • -new: Dieser Schalter sagt OpenSSL, dass wir eine neue Zertifikatsignaturanforderung erstellen möchten.
  • -key pihole.fritz.box.key: Dies gibt den Pfad und den Namen der Datei an, die den privaten Schlüssel enthält, der zur Erstellung der Zertifikatsignaturanforderung verwendet wird.
  • -out pihole.fritz.box.csr: Dies gibt den Pfad und den Namen der Datei an, in die die Zertifikatsignaturanforderung geschrieben werden soll.
  • -config client.cnf: Dies gibt den Pfad und den Namen der Konfigurationsdatei an, die beim Erstellen der Zertifikatsignaturanforderung verwendet werden soll.

Der Vorletzte Schritt ist geschafft, nun haben wir fast alles zusammen um ein Client-Server Zertifikat zu erstellen.

Erstellen des Client-Serverzertifikats

Wer jetzt gehofft hat das unser begehrtes SSL-Zertifikat nur noch einen Befehl entfernt ist, muss ich leider enttäuschen. Wir müssen noch eine .ext Datei erzeugen die Einstellungen und Alternative DNS bzw. IP Adressen für unser Client-Serverzertifikat enthält.

Konfigurationsdatei zum erstellen des Client-Serverzertifikats

Also wie nun schon gewohnt:

nano /root/certs/v3.ext

Und hier der Inhalt der Datei

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = pihole.fritz.box
DNS.2 = pihole.smart
DNS.3 = pihole
IP.1 = 192.168.178.64

Die angegebene Konfigurationsdatei wird verwendet, um die Eigenschaften eines Client-Zertifikats zu definieren. Hier ist, was jeder Teil der Konfigurationsdatei bedeutet:

  • authorityKeyIdentifier=keyid,issuer: Dies definiert den Authority Key Identifier, der verwendet wird, um das Zertifikat der ausstellenden Zertifizierungsstelle (CA) in einer Kette von SSL-Zertifikaten zu identifizieren.
    • keyid: Dies bezieht sich auf den Identifier des öffentlichen Schlüssels im Zertifikat. Es wird automatisch aus dem öffentlichen Schlüssel generiert.
    • issuer: Dies bezieht sich auf den Aussteller des Zertifikats, d.h., die Zertifizierungsstelle (CA), die das Zertifikat signiert hat.
  • basicConstraints=CA:FALSE: Dies legt fest, dass das Zertifikat nicht als CA-Zertifikat verwendet werden kann. Das bedeutet, dass es nicht verwendet werden kann, um andere SSL-Zertifikate oder CRLs zu signieren.
  • keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment: Dies definiert die Verwendungszwecke des Schlüssels. In diesem Fall ist der Schlüssel für digitale Signaturen, Nichtabstreitbarkeit, Schlüsselverschlüsselung und Datenverschlüsselung vorgesehen.
  • subjectAltName = @alt_names: Dies definiert alternative Namen für das Subjekt des Zertifikats. Dies ist nützlich, wenn das Zertifikat für mehrere verschiedene Domains oder IPs gültig sein soll.
  • [alt_names]: Dieser Abschnitt listet die alternativen Namen auf, die im Zertifikat verwendet werden sollen. In diesem Fall sind das drei DNS-Namen (pihole.fritz.boxpihole.smartpihole) und eine IP-Adresse (192.168.178.64).

Es ist wichtig das bei den [alt_names] auch der Common Name [CN] des Client-Serverzertifikates aufgeführt wird, damit es später bei der Benutzung keine Probleme gibt. Mit der Angabe der IP-Adresse funktioniert dann auch diese mit https:// .

Das eigentliche erstellen des Client-Serverzertifikats

Um aus den vorherigen Dateien ein Client-Serverzertifikat zu erstellen diesen Befehl eingeben:

openssl x509 -req -in pihole.fritz.box.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out pihole.fritz.box.crt -days 825 -sha256 -extfile v3.ext

Bei der Erstellung wird natürlich wieder das passwort des myCA.key abgefragt.
Hier ist, was jeder Teil des Befehls bedeutet:

  • openssl x509: Dieser Befehl wird verwendet, um X.509-Zertifikate zu verwalten.
  • -req: Dieser Schalter sagt OpenSSL, dass wir eine CSR verarbeiten möchten.
  • -in pihole.fritz.box.csr: Dies gibt den Pfad und den Namen der Datei an, die die CSR enthält.
  • -CA myCA.pem: Dies gibt den Pfad und den Namen der Datei an, die das CA-Zertifikat enthält.
  • -CAkey myCA.key: Dies gibt den Pfad und den Namen der Datei an, die den privaten Schlüssel des CA enthält.
  • -CAcreateserial: Dieser Schalter sagt OpenSSL, dass es eine Seriennummer für das Zertifikat erstellen soll, wenn es nicht bereits eine gibt.
  • -out pihole.fritz.box.crt: Dies gibt den Pfad und den Namen der Datei an, in die das erstellte Zertifikat geschrieben werden soll.
  • -days 825: Dies gibt die Gültigkeitsdauer des Zertifikats in Tagen an. Wie beim Root Zertifikat schon erwähnt kann hier auch ein wesentlich längerer Zeitraum eingegeben werden.
  • -sha256: Dies gibt den Hash-Algorithmus an, der zur Signierung des Zertifikats verwendet wird.
  • -extfile v3.ext: Dies gibt den Pfad und den Namen der Datei an, die die Erweiterungen enthält, die in das Zertifikat aufgenommen werden sollen.

Jetzt sollte in unserem Verzeichnis die Datei pihole.fritz.box.crt erzeugt worden sein. Nach diesem ganzen Prozess haben wir ein Zertifikat für den Client-Server erstellt. Dieses Client-Serverzertifikat muss nun bei eurem Server eingebunden werden. Das myCA.pem Root Zertifikat muss auf euren Client-Rechner mit dem du die Website des Client-Servers aufrufen willst, damit dein Browser das Zertifikat des Servers als Vertrauenswürdig identifiziert.

Kombinieren von SSL-Zertifkat und Schlüssel

Für manche Anwendungsfälle wird eine kombinierte .pem Datei benötigt, die aus Client-Server Zertifikat und dem privaten Client-Server Zertifikatsschlüssel besteht. Diese kannst du mit folgendem Befel erstellen:

Cat pihole.fritz.box.crt pihole.fritz.box.key > pihole.fritz.box.combined.pem

Erneuern der SSL- Zertifikate

Wenn schon eine .csr Datei vorhanden ist, dann kann diese wiederverwendet werden um ein aktualisiertes Client-Server Zertifikat auszustellen. Deswegen ist eine gewisse Ordnung im Zertifikatsordner hilfreich.

Importieren des Root Zertifikats in Windows

In diesem Artikel erkläre ich nur wie man sein Root-Zertifikat in Windows importiert, alles andere sprengt den Rahmen und wird evtl. in einem weiteren Artikel beschrieben.
Um dein Root-Zertifikat unter Windows zu importieren, solltest du folgende Schritte befolgen:

  1. Speichere die Zertifikatsdatei (in diesem Fall myCA.pem) auf deinem Desktop oder in einem anderen zugänglichen Verzeichnis.
  2. Drücke die Windows-Taste + R, geben mmc ein und drücke Enter, um die Microsoft Management Console zu öffnen.
  3. Klicke im Menü „Datei“ auf „Snap-In hinzufügen/entfernen“.
  4. Wähle im linken Fenster „Zertifikate“ aus und klicke auf „Hinzufügen“.
  5. Wähle „Computerkonto“ und klicke auf „Weiter“.
  6. Wähle „Lokaler Computer“ und klicke auf „Fertigstellen“.
  7. Klicke auf „OK“, um das Fenster „Snap-In hinzufügen/entfernen“ zu schließen.
  8. Erweitern Sie im Hauptfenster der Konsole „Zertifikate (Lokaler Computer)“¹.
  9. Klicke mit der rechten Maustaste auf „Vertrauenswürdige Stammzertifizierungsstellen“, wähle „Alle Aufgaben“ und dann „Importieren“.
  10. Klicke im Zertifikatimport-Assistenten auf „Weiter“.
  11. Klicke auf „Durchsuchen“, navigiere zu der Zertifikatsdatei myCA.pem, die du importieren möchtest, und klicke auf „Öffnen“.
  12. Klicke auf „Weiter“, wähle „Zertifikatspeicher automatisch auswählen“ und klicke auf „Weiter“.
  13. Klicke auf „Fertig stellen“, um den Import abzuschließen.

Jetzt hast du dein Root-Zertifikat erfolgreich in den Windows-Zertifikatespeicher importiert. Bitte beachte, dass du möglicherweise Administratorrechte benötigst, um Zertifikate zu importieren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert