PKI-Lab mit Root-CA und Teilnehmer-CA: Unterschied zwischen den Versionen
| (12 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 57: | Zeile 57: | ||
==Der Certificate Signing Request muss nun zur Zertifizierungsstelle== | ==Der Certificate Signing Request muss nun zur Zertifizierungsstelle== | ||
*http://192.168.9.88 | *http://192.168.9.88 | ||
| − | |||
| − | |||
==Sub-CA durch Root signieren== | ==Sub-CA durch Root signieren== | ||
| Zeile 69: | Zeile 67: | ||
*openssl x509 -in it213-ca.crt -text -noout | *openssl x509 -in it213-ca.crt -text -noout | ||
| + | |||
| + | ==Die Zertifikate können nun hier runtergeladen werden== | ||
| + | *http://192.168.9.88/uploads | ||
| + | |||
==Hinweis zum privaten Schlüssel== | ==Hinweis zum privaten Schlüssel== | ||
| Zeile 88: | Zeile 90: | ||
==Server-Schlüssel und CSR erzeugen== | ==Server-Schlüssel und CSR erzeugen== | ||
| + | ;Variable setzen | ||
| + | *CA=it213-ca | ||
| + | *FQDN=www.it213.int | ||
Der Teilnehmer erzeugt einen Schlüssel und eine CSR für seinen Server. | Der Teilnehmer erzeugt einen Schlüssel und eine CSR für seinen Server. | ||
;Erstellen | ;Erstellen | ||
| − | *openssl req -new -newkey rsa:2048 -nodes -keyout | + | *openssl req -new -newkey rsa:2048 -nodes -keyout $FQDN.key -out $FQDN.csr -subj "/CN=$FQDN" |
;Anzeigen | ;Anzeigen | ||
| − | *openssl req -in | + | *openssl req -in $FQDN.csr -text -noout |
==Server-Zertifikat signieren== | ==Server-Zertifikat signieren== | ||
| Zeile 98: | Zeile 103: | ||
Die Sub-CA signiert das Server-Zertifikat und fügt einen Subject Alternative Name hinzu. | Die Sub-CA signiert das Server-Zertifikat und fügt einen Subject Alternative Name hinzu. | ||
;Signieren | ;Signieren | ||
| − | *openssl x509 -req -in | + | *openssl x509 -req -in $FQDN.csr -CA $CA.crt -CAkey $CA.key -CAcreateserial -out $FQDN.crt -days 365 -extfile <(printf "subjectAltName=DNS:$FQDN") |
;Anzeigen | ;Anzeigen | ||
| − | *openssl x509 -in | + | *openssl x509 -in $FQDN.crt -text -noout |
==Fullchain erstellen== | ==Fullchain erstellen== | ||
| Zeile 109: | Zeile 114: | ||
Dazu wird eine Fullchain-Datei erstellt. | Dazu wird eine Fullchain-Datei erstellt. | ||
| − | *cat | + | *cat $FQDN.crt $CA.crt > $FQDN-fullchain.pem |
Die Reihenfolge ist wichtig. | Die Reihenfolge ist wichtig. | ||
| Zeile 118: | Zeile 123: | ||
</pre> | </pre> | ||
| + | ==Zum Ziel kopieren== | ||
| + | *scp $FQDN-fullchain.pem $FQDN.key kit@$FQDN: | ||
==Zertifikatskette prüfen== | ==Zertifikatskette prüfen== | ||
| Zeile 254: | Zeile 261: | ||
Der Zugriff erfolgt im Browser über https://www.it213.int:8443. | Der Zugriff erfolgt im Browser über https://www.it213.int:8443. | ||
| + | == Tests vom Client == | ||
| + | ;Verschlüsselter Verbindungsaufbau | ||
| + | *openssl s_client -host www.it213.int -port 8443 | ||
| + | ;Welche Zertifikate werden angeboten? | ||
| + | *nmap --script ssl-cert www.it213.int -p 8443 | ||
| + | ;Welche SSL/TLS Versionen werden angeboten | ||
| + | *nmap --script ssl-enum-ciphers www.it213.int -p 8443 | ||
Aktuelle Version vom 19. März 2026, 13:49 Uhr
PKI mit Root-CA und Sub-CA (Beispiel it213)
In diesem Beispiel wird eine einfache PKI aufgebaut.
Der Trainer betreibt eine Root-CA.
Die Teilnehmer erzeugen eine Sub-CA, die von der Root-CA signiert wird.
Mit dieser Sub-CA werden anschließend Server-Zertifikate signiert.
Root-CA erstellen
Die Root-CA ist der Vertrauensanker der PKI und ist selbstsigniert.
- openssl req -new -x509 -newkey rsa:4096 -nodes -keyout ca.key -out ca.crt -days 3650 -subj "/CN=Kit Root CA"
Das Zertifikat kann anschließend kontrolliert werden.
- openssl x509 -in ca.crt -text -noout
Root-CA auf Clients installieren
Damit Clients den Zertifikaten vertrauen, muss die Root-CA im Trust-Store installiert werden.
Debian
Das Root-Zertifikat wird in den lokalen CA-Speicher kopiert.
- cp ca.crt /usr/local/share/ca-certificates/
Der Trust-Store wird aktualisiert.
- update-ca-certificates
Rocky / RHEL
Das Root-Zertifikat wird in den Anchor-Store kopiert.
- cp ca.crt /etc/pki/ca-trust/source/anchors/
Der System Trust Store wird neu erzeugt.
- update-ca-trust extract
Firefox / Chrome / Mozilla
- Müssen getrennt importiert werden.
Sub-CA Request erzeugen (Beispiel it213)
Der Teilnehmer erzeugt einen privaten Schlüssel und eine Certificate Signing Request für seine CA.
- mkdir intermediata-ca
- cd intermediata-ca
- openssl req -new -newkey rsa:4096 -nodes -keyout it213-ca.key -out it213-ca.csr -subj "/CN=it213 Lab CA"
Der Certificate Signing Request muss nun zur Zertifizierungsstelle
Sub-CA durch Root signieren
Die Root-CA signiert die Teilnehmer-CA. Dadurch entsteht die Zertifikatskette.
- openssl x509 -req -in it213-ca.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out it213-ca.crt -days 1460 -extfile <(printf "basicConstraints=CA:TRUE\nkeyUsage=keyCertSign,cRLSign")
Das signierte CA-Zertifikat kann kontrolliert werden.
- openssl x509 -in it213-ca.crt -text -noout
Die Zertifikate können nun hier runtergeladen werden
Hinweis zum privaten Schlüssel
Der private Schlüssel der CA wird nur zum Signieren von Zertifikaten benötigt.
Zum Prüfen der Zertifikatskette werden nur die öffentlichen Zertifikate verwendet.
Beispiel:
www.it213.int.crt it213-ca.crt ca.crt
Die Prüfung erfolgt über die Signaturen der Zertifikate.
Server-Schlüssel und CSR erzeugen
- Variable setzen
- CA=it213-ca
- FQDN=www.it213.int
Der Teilnehmer erzeugt einen Schlüssel und eine CSR für seinen Server.
- Erstellen
- openssl req -new -newkey rsa:2048 -nodes -keyout $FQDN.key -out $FQDN.csr -subj "/CN=$FQDN"
- Anzeigen
- openssl req -in $FQDN.csr -text -noout
Server-Zertifikat signieren
Die Sub-CA signiert das Server-Zertifikat und fügt einen Subject Alternative Name hinzu.
- Signieren
- openssl x509 -req -in $FQDN.csr -CA $CA.crt -CAkey $CA.key -CAcreateserial -out $FQDN.crt -days 365 -extfile <(printf "subjectAltName=DNS:$FQDN")
- Anzeigen
- openssl x509 -in $FQDN.crt -text -noout
Fullchain erstellen
Damit Clients die Zertifikatskette aufbauen können, muss der Server die Intermediate-CA mitliefern.
Dazu wird eine Fullchain-Datei erstellt.
- cat $FQDN.crt $CA.crt > $FQDN-fullchain.pem
Die Reihenfolge ist wichtig.
www.it213.int.crt it213-ca.crt
Zum Ziel kopieren
- scp $FQDN-fullchain.pem $FQDN.key kit@$FQDN:
Zertifikatskette prüfen
Die komplette Zertifikatskette kann mit OpenSSL überprüft werden.
- openssl verify -CAfile ca.crt -untrusted it213-ca.crt www.it213.int.crt
PKI-Struktur
Kit Root CA
└── it213-ca
└── www.it213.int
Der Client kennt die Root-CA aus dem Trust-Store.
Der Server liefert beim TLS-Handshake das Server-Zertifikat und die Sub-CA.
Der Client kann damit die vollständige Zertifikatskette prüfen.
Troubleshooting: OpenSSL & PKI Fehler
| Fehlermeldung / Symptom | Mögliche Ursache | Lösung |
|---|---|---|
| "Self-signed certificate in certificate chain" | Der Client vertraut der Root-CA nicht oder die Root-CA wurde nicht im Trust-Store installiert. | Prüfen, ob update-ca-certificates (Debian) oder update-ca-trust (Rocky) ausgeführt wurde. Browser ggf. neu starten. |
| "Depth lookup: unable to get local issuer certificate" | Die Intermediate-CA (Sub-CA) fehlt in der Kette, die der Server ausliefert. | Prüfen, ob die Datei fullchain.pem korrekt erstellt wurde (Reihenfolge!) und im Webserver (SSLCertificateFile / ssl_certificate) eingebunden ist. |
| "Certificate is not valid for 'xyz.int'" | Der Subject Alternative Name (SAN) fehlt oder ist falsch geschrieben. | Zertifikat prüfen mit: openssl x509 -in cert.crt -text -> Suche nach "X509v3 Subject Alternative Name". |
| "Verification error: certificate has expired" | Systemzeit auf Server oder Client ist falsch (häufig bei VMs nach Suspend). | Datum/Uhrzeit mit dem Befehl date prüfen und ggf. per NTP synchronisieren. |
| "Modulus mismatch" | Der private Schlüssel passt kryptografisch nicht zum vorliegenden Zertifikat. | Vergleichen der MD5-Hashes beider Dateien (siehe unten unter "Nützliche Befehle"). |
| "CA:FALSE" bei der Sub-CA | Die Sub-CA wurde ohne die Extension basicConstraints=CA:TRUE signiert. | Die Sub-CA ist nicht berechtigt, weitere Zertifikate zu signieren. Sub-CA mit den richtigen Extensions neu erstellen. |
Nützliche Prüfbefehle für die Administration
Modulus-Check (Passen Key und CRT zusammen?)
Um sicherzustellen, dass ein Zertifikat zu einem Private Key gehört, müssen die Modulus-Hashes identisch sein:
openssl x509 -noout -modulus -in www.it213.int.crt | openssl md5
openssl rsa -noout -modulus -in www.it213.int.key | openssl md5
TLS-Handshake live testen
Simuliert einen Verbindungsaufbau und zeigt die vom Server gesendete Zertifikatskette an:
openssl s_client -connect localhost:443 -showcerts
Zertifikatsinhalt schnell prüfen
openssl x509 -in fullchain.pem -text -noout
Python Webserver mit SSL/TLS
In dieser Anleitung wird ein einfacher HTTPS-Webserver mit Python erstellt, der statische Inhalte aus einem Verzeichnis ausliefert.
Als erstes müssen wir die fullchain.pem und den privaten Schlüssl zu Server bringen
- scp fullchain.pem www.it213.int.key www:
Auf dem Webserver
- ssh kit@www
Verzeichnis erstellen
Zuerst wird ein Arbeitsverzeichnis für die Webinhalte und das Server-Skript angelegt.
- mkdir html
Keys anpassen
Die Zertifikatsdateien müssen in das Verzeichnis kopiert und für das Skript passend benannt werden.
- cp fullchain.pem html/own.crt
- cp www.it213.int.key html/own.key
Konfiguration
Das Python-Skript konfiguriert den Server so, dass er auf Port 8443 lauscht und die SSL-Verschlüsselung nutzt.
- nano html/https.py
import http.server, ssl
server_address = ('0.0.0.0', 8443)
handler = http.server.SimpleHTTPRequestHandler
httpd = http.server.HTTPServer(server_address, handler)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile="own.crt", keyfile="own.key")
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
print("HTTPS läuft auf https://0.0.0.0:8443")
httpd.serve_forever()
Statische Seite erstellen
Damit der Server eine Seite anzeigt, wird eine index.html im Verzeichnis erstellt.
- nano html/index.html
<html> <head> <title>IT213 Testseite</title> </head> <body> <h1>Erfolg!</h1> <p>Der verschlüsselte Python-Webserver funktioniert und liefert diese Seite aus.</p> </body> </html>
Starten
Um den Server zu starten, wechselt man in das Verzeichnis und führt das Skript aus.
- cd html
- python3 https.py
Der Zugriff erfolgt im Browser über https://www.it213.int:8443.
Tests vom Client
- Verschlüsselter Verbindungsaufbau
- openssl s_client -host www.it213.int -port 8443
- Welche Zertifikate werden angeboten?
- nmap --script ssl-cert www.it213.int -p 8443
- Welche SSL/TLS Versionen werden angeboten
- nmap --script ssl-enum-ciphers www.it213.int -p 8443