Wenn Ihr Browser eine Verbindung zu einer HTTPS-Website herstellt, vertraut er dem Zertifikat nicht einfach blind. Er verifiziert eine Vertrauenskette — eine verknuepfte Reihe von Zertifikaten, die von Ihrem Website-Zertifikat bis zu einer vorab vertrauten Root-Zertifizierungsstelle (CA) fuehrt.
Die drei Ebenen
┌─────────────────────────────────┐
│ ROOT CA │ Vorinstalliert in Browsern/Betriebssystemen
│ (ISRG Root X1 fuer LE) │ Selbstsigniert, lange Gueltigkeit (20+ Jahre)
└───────────────┬─────────────────┘
│ signiert
▼
┌─────────────────────────────────┐
│ INTERMEDIATE CA │ Von der Root signiert
│ (Let's Encrypt R3/R10) │ Mittlere Gueltigkeit (5-10 Jahre)
└───────────────┬─────────────────┘
│ signiert
▼
┌─────────────────────────────────┐
│ IHR ZERTIFIKAT │ Von der Intermediate signiert
│ (example.com) │ Kurze Gueltigkeit (90 Tage fuer LE)
└─────────────────────────────────┘
Root-CA — Von Browsern und Betriebssystemen vertraut. Im Zertifikatsspeicher des Geraets gespeichert. Selbstsigniert (niemand signiert fuer die Root — sie IST der Vertrauensanker). Root-Schluessel werden offline in Hardware-Sicherheitsmodulen aufbewahrt.
Intermediate-CA — Von der Root signiert. Stellt tatsaechlich End-Entity-Zertifikate aus. Wenn eine Intermediate kompromittiert wird, muss nur sie widerrufen werden — die Root bleibt sicher.
End-Entity-Zertifikat — Ihr Zertifikat. Von der Intermediate signiert. Das ist es, was Ihr Server an Browser sendet.
Wie die Verifizierung funktioniert
Wenn Ihr Browser ein Zertifikat erhaelt:
- Ihr Zertifikat lesen — den Ausstellernamen extrahieren
- Die Intermediate finden — entweder aus der Serverantwort oder dem Browser-Cache
- Intermediate-Signatur verifizieren — pruefen, ob sie von einer vertrauten Root signiert ist
- Signatur Ihres Zertifikats verifizieren — pruefen, ob es von der Intermediate signiert ist
- Gueltigkeitsdaten pruefen — keines der Zertifikate ist abgelaufen
- Domain-Uebereinstimmung pruefen — der SAN/CN des Zertifikats stimmt mit der URL ueberein
- Widerruf pruefen — Zertifikat wurde nicht widerrufen (OCSP/CRL)
Wenn ein Schritt fehlschlaegt → Browser zeigt eine Sicherheitswarnung.
Warum die Intermediate wichtig ist
Der haeufigste SSL-Fehler ist ein fehlendes Intermediate-Zertifikat. Wenn Ihr Server nur Ihr Zertifikat ohne die Intermediate sendet, koennen Browser die Vertrauenskette nicht aufbauen.
Nginx erwartet fullchain.pem (Ihr Zertifikat + Intermediate kombiniert):
ssl_certificate /etc/ssl/fullchain.pem; # Zertifikat + Intermediate
Apache verwendet separate Dateien:
SSLCertificateFile /etc/ssl/cert.pem # Ihr Zertifikat
SSLCertificateChainFile /etc/ssl/chain.pem # Intermediate
GetHTTPS stellt sowohl fullchain.pem als auch separate cert.pem + chain.pem Dateien bereit, sodass Sie das richtige Format fuer jeden Server haben.
Die Kette von Let’s Encrypt
Die aktuelle Kette von Let’s Encrypt:
ISRG Root X1 (Root, in allen Trust Stores)
└── Let's Encrypt R10 (Intermediate, signiert Ihr Zertifikat)
└── yourdomain.com (Ihr Zertifikat)
Es gibt auch einen kreuz-signierten Pfad ueber IdenTrusts DST Root CA X3 fuer die Kompatibilitaet mit aelteren Geraeten, aber dies ist fuer die meisten Anwendungsfaelle nicht mehr erforderlich.
Haeufig gestellte Fragen
Wie behebe ich Fehler “Zertifikat nicht vertrauenswuerdig”?
Fast immer: Es fehlt das Intermediate-Zertifikat. Verwenden Sie fullchain.pem (Nginx) oder fuegen Sie SSLCertificateChainFile chain.pem hinzu (Apache). Testen Sie mit:
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
Suchen Sie nach “verify return:1” (gut) vs “verify return:0” (Kettenproblem).
Kann ich die Kette in meinem Browser sehen?
Ja. Klicken Sie auf das Schloss → “Zertifikat” (oder “Verbindung ist sicher” → “Zertifikat ist gueltig”). Sie sehen die Kette: Ihr Zertifikat → Intermediate → Root.
Was passiert, wenn eine Root-CA kompromittiert wird?
Die Root wird ueber Browser-/Betriebssystem-Updates aus den Trust Stores entfernt. Alle unter dieser Root ausgestellten Zertifikate werden nicht mehr vertraut. Das ist aeusserst selten — Root-Schluessel werden in Offline-Hardware-Sicherheitsmodulen mit physischen Zugangskontrollen gespeichert.
Warum verwendet Let’s Encrypt ein Intermediate-Zertifikat, anstatt direkt mit der Root zu signieren?
Sicherheitsisolierung. Wenn der Intermediate-Schluessel kompromittiert wird, muss nur er widerrufen werden — die Root bleibt sicher. Der Root-Schluessel wird offline aufbewahrt und nur zum Signieren von Intermediates verwendet. Das ist gaengige Praxis bei allen grossen Zertifizierungsstellen.
Muss ich das Root-Zertifikat auf meinem Server installieren?
Nein. Root-Zertifikate sind in Browsern und Betriebssystemen vorinstalliert. Ihr Server muss nur Ihr Zertifikat + die Intermediate senden. Der Browser hat die Root bereits und verwendet sie zur Verifizierung der Kette.
Kettenprobleme debuggen
Der haeufigste SSL-Fehler in der Produktion ist eine unvollstaendige Zertifikatskette. Hier ist ein systematischer Ansatz zur Diagnose:
Schritt 1: Pruefen Sie die Kette, die Ihr Server sendet
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null
Betrachten Sie die Ausgabe:
Certificate chain
0 s:CN = example.com
i:C = US, O = Let's Encrypt, CN = R10
1 s:C = US, O = Let's Encrypt, CN = R10
i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
---
Verify return code: 0 (ok)
- Depth 0 = Ihr Zertifikat
- Depth 1 = Intermediate
- “Verify return code: 0 (ok)” = Kette ist vollstaendig
Wenn Sie nur Depth 0 sehen (kein Depth 1), fehlt die Intermediate.
Schritt 2: Die Kette reparieren
Nginx: Verwenden Sie fullchain.pem (Zertifikat + Intermediate kombiniert):
ssl_certificate /etc/ssl/fullchain.pem; # NICHT cert.pem
Apache: Fuegen Sie die Intermediate explizit hinzu:
SSLCertificateChainFile /etc/ssl/chain.pem
Wenn Sie chain.pem verloren haben: Laden Sie die Intermediate von Let’s Encrypt von letsencrypt.org/certificates herunter oder stellen Sie Ihr Zertifikat mit GetHTTPS neu aus.
Schritt 3: Die Korrektur verifizieren
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | grep "Verify return code"
# Muss lauten: Verify return code: 0 (ok)