Erstellung eigener vertrauenswürdiger SSL-Zertifikate
Für öffentliche (Web)Server ist die Erstellung von kostenlosen SSL-Zertifikaten dank Let's Encrypt mittlerweile sehr einfach möglich. Benötigt man aber ein Zertifikat für Server im Intranet, z.B. für Testsysteme oder weil eine Software SSL voraussetzt, ist ein Abruf von Zertifikaten von Let's Encrypt nicht mehr möglich. Denn dazu müsste der Server über das Internet erreichbar sein und der Domainname im DNS des Providers registriert sein.
Für private Server bleibt daher nur die Verwendung von Zertifikaten, die man selbst erstellt und zertifiziert hat. Allerdings lassen sich diese Zertifikate nicht (mehr) so einfach verwenden, da sie insbesondere aus Sicht der Web Browser ein Sicherheitsrisiko darstellen. Aber auch andere Tools müssen häufig erst "überredet" werden, solche Zertifikate zu akzeptieren.
Die Ursache des Problems ist, dass die selbst-zertifizierten SSL-Zertifikaten nicht von einer vertrauenswürdigen Stammzertifizierungstelle (Certificate Authority, kurz "CA") gegenzertifiziert wurden. Die vertrauenswürdigen CAs (bzw. deren öffentliche Schlüssel) sind im Betriebssystem (bzw. Browser) fest hinterlegt und werden z.B. bei Betriebssystemupdates aktualisiert.
Die Lösung des Problems ist daher ganz einfach: wir machen uns selbst zu einer CA. Dazu müssen wir ein Stammzertifikat erstellen und dieses dann auf allen Geräten (und teilweise auch Browsern), die unsere selbst erstellten Zertifikate benötigen, importieren.
Das Verfahren benötigt zwar nur einzige Werkzeug ("OpenSSL"), aber die Verwendung ist nicht ganz trivial und ich habe auch einige Versuche und viel "Googlerei" benötigt, bis alles wie gewünscht funktionierte. Ich beschreibe daher im Folgenden ein Verfahren, mit dem sich die diversen Zertifikate unter verschiedenen Betriebssystemen und Browsern verwenden lassen.
Voraussetzung
Für die Arbeit mit Zertifikaten benötigt man nur ein Command Line Werkzeug: openssl
. Auf Linux-Systemen ist OpenSSL i.d.R. bereits installiert oder kann einfach über die jeweilige Paketverwaltung installiert werden. Für Windows-Systeme kann es von der Website des OpenSSL Installation Projects heruntergeladen werden.
Ich habe die Windows-Variante nicht getestet, sondern das Ganze lieber unter Linux (bzw. in der WSL) gemacht.
openssl
in der WSL (mit Ubuntu) von Windows 11 ausgeführt. Damit die Befehle besser lesbar sind, habe ich sie umgebrochen. In der Windows Command Line müssen die Befehle entweder in eine Zeile geschrieben werden oder der \
am Zeilenende muss durch ^
ersetzt werden.Stammzertifikat (ROOT)-Zertifikat erstellen
Im ersten Schritt muss ein Stammzertifikat mit zugehörigem privatem Schlüssel erstellt werden.
Zunächst wird ein privater Schlüssel erzeugt, der in der Datei myRoot.key
gespeichert wird (der Dateiname ist natürlich frei wählbar):
openssl genrsa -out myRoot.key 2048
Im nächsten Schritt wird dann das eigentliche Zertifikat für unsere CA erstellt:
openssl req -x509 -new -nodes -key myRoot.key -sha256 -days 3650 \
-out myRoot.crt
Das neue Zertifikat wird in der Datei myRoot.crt
gespeichert. Die Speicherung erfolgt dabei im PEM-Format(). Allerdings ist die Dateierweiterung .crt
gebräuchlicher als .pem
und erleichtert später das Einspielen des Zertifikats.
Für die Erstellung des Zertifikats werden verschiedene Informationen abgefragt:
Country Name (2 letter code) [1]:DE
State or Province Name (full name) [2]:NRW
Locality Name (eg, city) :Brilon
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyFirma
Organizational Unit Name (eg, section) :
Common Name (e.g. server FQDN or YOUR name) :example.com
Email Address :root@example.com
Es ist eigentlich relativ egal, was hier eingegeben wird, aber sinnvolle Eingaben erleichtern später das Auffinden des Zertifikats.
Ob das Zertifikat richtig erstellt wurde, kann mit Hilfe von openssl
überprüft werden. Mit dem Befehl
openssl x509 -in myRoot.crt -text -noout
werden alle im Zertifikat enthaltenen Informationen ausgegeben. Besonders wichtig ist dabei dieser Wert:
X509v3 Basic Constraints: critical
CA:TRUE
Installation des Zertifikats
Das im vorherigen Schritt erstellte Zertifikat myRoot.crt
kann jetzt auf allen Rechnern und Browsern installiert werden, dies es benötigen.
Microsoft Windows
Microsoft Windows hat eine zentrale Zertifikatsverwaltung, die aber nicht so ganz einfach zu finden ist. Um sie aufzurufen, startet man die "Microsoft Management Console" (mmc.exe
) und fügt das Snap-in "Zertifikate" hinzu.
Zum Importieren des selbst erstellten Zertifikats benötigt man diese Verwaltung allerdings nicht zwingend. Es reicht aus, die Datei mit dem Zertifikat (myRoot.crt
) mit der rechten Maustaste anzuklicken und im Kontextmenü den Menüpunkt Zertifikat installieren aufzurufen. Es wird dann der "Zertifikatimport-Assistent" gestartet.
Im Assistenten wählt man auf der Startseite unter Speicherort die Einstellung "Lokaler Computer" aus und klickt den Weiter-Knopf an. Hierzu sind Administratorrechte nötig.
Auf der Folgeseite muss dann der passende Speicher für das Zertifikat ausgewählt werden.
Das Zertifikat muss zwingend im Speicher für "Vertrauenswürdige Stammzertifizierungsstellen" abgelegt werden.
Linux (Debian, Ubuntu)
Auf Linux-Systemen muss das Zertifikat ebenfalls in den entsprechenden Zertifikatsspeicher kopiert werden. Unter Debian und Ubuntu geht dies wie folgt:
sudo mkdir /usr/local/share/ca-certificates/extra
sudo cp myRoot.crt \
/usr/local/share/ca-certificates/extra/myRoot.crt
sudo update-ca-certificates
Bei anderen Linux-Systemen dürfte das Verfahren ähnlich sein.
Android und iOS
Bei Android- und iOS-Geräten muss zunächst die Zertifikatsdatei auf das Gerät gelangen. Das ist bei Android-Geräten meistens einfacher als bei den iOS-Pendants.
Eine allgemein verfügbare Möglichkeit ist der Versand per E-Mail. Hierbei kann es allerdings passieren, dass die Mail vom Provider blockiert wird, weil die angehängte Datei verdächtig erscheint (T-Online mag sie zum Beispiel nicht).
Ist die Datei erst einmal auf dem Gerät, reicht ein "Klick" auf die Datei, um die passende System-App für den Import zu starten. Alternativ kann die Zertifikatsverwaltung auch aus den Systemeinstellungen.
Firefox Browser
Der Firefox Browser hat eine eigene Verwaltung für Stammzertifikate. Um ein neues Zertifikat zu importieren, ruft man die Einstellungen auf und wählt den Unterpunkt Datenschutz & Sicherheit aus.
Ganz unten auf der Einstellungsseite befindet sich der Button Zertifikate anzeigen .... Klickt man diesen Button an, erscheint ein Dialog mit mehreren Tabs. Dort wechselt man zunächst zum Tab Zertifizierungsstellen und klickt auf den Importieren Button. Es kann dann über einen Dateiauswahldialog das Zertifikat (myRoot.crt
) ausgewählt werden.
Im Bestätigungsdialog für das "Herunterladen des Zertifikats" muss noch die Option "Dieser CA vertrauen, um Websites zu identifizieren" selektiert und der Dialog mit OK verlassen werden. Anschließend sollte sich das Zertifikat dann unter Zertifikatsstellen befinden.
Zertifikat für eine (Sub)Domain erstellen
Nach der Erstellung und Verteilung des Stammzertifikats können jetzt beliebig viele Zertifikate für (Sub)Domains erstellt werden. Das Verfahren entspricht der allgemeinen Vorgehensweise für die Beantragung und Erstellung eines Zertifikats:
- Zunächst werden ein privater Schlüssel und ein CSR (Certificate Signing Request) erstellt.
- Aus dem CSR wird dann mit Hilfe des Stammzertifikats ein Zertifikat für die Domäne erstellt.
- Dieses Zertifikat kann anschließend z.B. im Web Server konfiguriert werden.
Es gibt verschiedene Möglichkeiten den Schlüssel, den CSR und das Zertifikat zu erstellen. Dabei gibt es evtl. auch einfachere Varianten als das von mir getestete und beschriebene Verfahren.
Die nach diesem Verfahren erstellten Zertifikate werden von allen getesteten Browsern (Chrome, Firefox, Edge) anstandslos akzeptiert.
Insbesondere Chrome ist da sehr "sensibel".
Privater Schlüssel und CSR erstellen
Für jede Zertifikatsanforderung müssen zunächst ein privater Schlüssel und ein CSR erstellt werden. Das geht am einfachsten, in dem pro Domain zunächst eine Konfigurationsdatei mit den notwendigen Daten erstellt wird.
Als Domainname verwende ich in den Beispielen test.example.private
.
Die Konfigurationsdatei sieht dann wie folgt aus:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C=DE
ST=NRW
L=MeinOrt
O=MeinName
emailAddress=webmaster@example.private
CN = test.example.private
Der gewünschte Domainname steht in der letzten Zeile. Für eine andere Domain muss nur diese Zeile angepasst werden. Ich würde aber auch für die anderen Werte im Bereich [dn]
passende Werte eintragen.
Ich habe die Konfigurationsdatei unter dem Dateinamen test.example.csr.cnf
gespeichert.
Der CSR und der private Schlüssel werden dann mit diesem Befehl erstellt:
openssl req -new -sha256 -nodes \
-out test.example.csr \
-newkey rsa:2048 -keyout test.example.key \
-config test.example.csr.cnf
Der private Schlüssel wird in der Datei test.example.key
abgelegt. Er wird später auch für die Konfiguration des (Web)Servers benötigt.
Der CSR befindet sich in der Datei test.example.csr
. Für die Erzeugung des Zertifikats wird nur der CSR benötigt.
Server-Zertifikat erstellen
Für die Erstellung des Server-Zertifikats wird zunächst eine weitere Konfigurationsdatei erstellt:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = test.example.private
Auch hier muss für andere Domains nur jeweils die letzte Zeile angepasst werden.
Der Eintrag in dieser Zeile muss unbedingt exakt dem Eintrag CN
in der Konfigurationsdatei für die CSR-Erstellung entsprechen.
Die Konfigurationsdatei habe ich unter dem Namen test.example.ext.cnf
gespeichert.
Neben dieser Konfigurationsdatei und der CSR-Datei werden auch das Zertifikat und der private Schlüssel der CA benötigt.
Die Erstellung des Zertifikats erfolgt mit dem folgenden Befehl:
openssl x509 -req -in test.example.csr \
-CA myRoot.crt -CAkey myRoot.key -CAcreateserial \
-extfile test.example.ext.cnf \
-out test.example.crt -days 3650 -sha256
Das neu erzeugte Zertifikat ist in diesem Bespiel 10 Jahre (= 3650 Tage) gültig und wird in der Datei test.example.crt
gespeichert.
Der Inhalt des Zertifikats kann durch Aufruf des Befehls
openssl x509 -in test.example.crt -text -noout
überprüft werden. Wichtig sind die folgenden Einträge:
X509v3 extensions:
...
X509v3 Subject Alternative Name:
DNS:test.example.private
Es muss unbedingt die "X509v3 extension" vorhanden sein und der "Subject Alternative Name" muss dem Domainnamen entsprechen.
SSL im Web Server konfigurieren
Die folgende Konfiguration eines NGINX Web Servers ist nur ein Beispiel.
Für die Konfiguration des Servers für den Zugriff via SSL werden das Server-Zertifikat (ssl_certificate
) und der zugehörige private Schlüssel (ssl_certificate_key
) benötigt.
Die Konfiguration sieht dann wie folgt aus (Pfadangaben sind Windows-like):
server {
listen 443 ssl;
server_name test.example.private;
ssl_certificate c:/nginx/test.example.crt;
ssl_certificate_key c:/nginx/test.example.key;
location / {
...
}
}
Für andere Web Server wie z.B. Apache sieht die Konfiguration ähnlich aus.