aethercert
Dokumentation

NGINX: SSL-Zertifikat austauschen

SSL-Zertifikat auf NGINX austauschen: Fullchain-PEM bauen und prüfen, mit Rückweg installieren, nginx -t, Reload ohne Verbindungsabbruch - auch in Docker.

NGINX liest eine PEM-Zertifikatskette und einen privaten Schlüssel aus den Pfaden in ssl_certificate und ssl_certificate_key. Die Dateien zu ersetzen reicht nicht: Die Konfiguration muss nginx -t bestehen, und der Master-Prozess muss sie neu laden.

Voraussetzungen

  • Sie brauchen drei PEM-Dateien von Ihrer CA (Namen variieren): das Serverzertifikat (hier leaf.pem), das bzw. die Zwischenzertifikate (intermediates.pem) und den privaten Schlüssel (private.key, unverschlüsselt). Das Stammzertifikat gehört nicht dazu.

  • Ermitteln Sie jedes Zertifikat, das NGINX tatsächlich nutzt - nginx -T gibt die vollständige geladene Konfiguration aus, nicht nur sites-enabled:

    sudo nginx -T | grep -E 'server_name|ssl_certificate'
  • Behalten Sie die aktuellen Dateien: Der Ablauf unten installiert die neuen in ein neues Verzeichnis, die alten bleiben für einen Rollback liegen.

  • Bei mehreren Servern hinter einem Load Balancer: einen herausnehmen, aktualisieren, wieder hineinnehmen.

Zertifikat Schritt für Schritt austauschen

Führen Sie die Befehle als root aus (oder mit sudo).

  1. Vollständige Kette bauen - Serverzertifikat zuerst - und prüfen:

    cat leaf.pem intermediates.pem > fullchain.pem
    grep -c 'BEGIN CERTIFICATE' fullchain.pem
    openssl x509 -in fullchain.pem -noout -subject -issuer -dates -ext subjectAltName
    openssl verify -untrusted intermediates.pem leaf.pem
    openssl pkey -in private.key -pubout | sha256sum
    openssl x509 -in leaf.pem -noout -pubkey | sha256sum

    Die Anzahl muss der Zahl der zusammengefügten Zertifikate entsprechen - fehlt einer Datei der abschließende Zeilenumbruch, verschmelzen zwei Zertifikate zu einem kaputten Block. openssl verify muss leaf.pem: OK ausgeben (es nutzt die vertrauenswürdigen Stammzertifikate des Systems). Die beiden sha256sum-Werte müssen gleich sein, sonst gehören Schlüssel und Zertifikat nicht zusammen.

  2. In ein neues, versioniertes Verzeichnis installieren und einen Symlink darauf umstellen:

    install -d -m 0700 /etc/nginx/tls/example-2026
    install -m 0644 fullchain.pem /etc/nginx/tls/example-2026/fullchain.pem
    install -m 0600 private.key   /etc/nginx/tls/example-2026/private.key
    ln -sfn /etc/nginx/tls/example-2026 /etc/nginx/tls/example-current

    Der NGINX-Master-Prozess läuft als root und liest den Schlüssel, bevor er die Worker startet; ein nur für root lesbarer Schlüssel (0600) ist daher richtig. Läuft NGINX komplett unter einem anderen Benutzer, muss dieser den Schlüssel lesen können.

  3. Prüfen, ob der Server-Block auf den Symlink zeigt:

    ssl_certificate     /etc/nginx/tls/example-current/fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/example-current/private.key;
  4. Testen, dann neu laden:

    nginx -t && systemctl reload nginx
    journalctl -u nginx --since "5 minutes ago"

    Scheitert nginx -t, hat sich für den laufenden Server nichts geändert - stellen Sie den Symlink zurück und suchen Sie den Fehler. Ein Reload trennt keine Verbindungen: NGINX startet neue Worker mit dem neuen Zertifikat, die alten beenden ihre offenen Verbindungen (langlebige wie WebSockets halten einen alten Worker eine Weile am Leben). Prüfen Sie Journal oder /var/log/nginx/error.log - systemctl is-active allein zeigt nicht, ob der Reload geklappt hat.

NGINX im Container

  • Binden Sie das Zertifikatsverzeichnis in den Container ein, nicht einzelne Dateien. Wird eine Datei auf dem Host ersetzt, entsteht meist eine neue Datei (neuer Inode), und ein Bind-Mount einer einzelnen Datei zeigt weiter die alte.

  • Testen und neu laden im Container:

    docker exec <container> nginx -t
    docker exec <container> nginx -s reload
  • Siehe auch die Anleitung für Docker-Container.

Produktspezifische Hinweise

Schlüssel passt nicht: Meldet nginx -t SSL_CTX_use_PrivateKey ... key values mismatch, gehört das erste Zertifikat der Kettendatei nicht zum Schlüssel. Entweder wurde der falsche Schlüssel installiert, oder die Kettendatei beginnt nicht mit dem Serverzertifikat. Vergleichen Sie die beiden Hashes aus Schritt 1 und prüfen Sie die Reihenfolge.

Durch SNI kommt es auf den getesteten Hostnamen an: Mehrere Server-Blöcke können auf derselben Adresse unterschiedliche Zertifikate nutzen. SELinux oder AppArmor können den Zugriff auf einen neuen Pfad sperren, auch wenn die Dateirechte stimmen - auf SELinux-Systemen führen Sie nach dem Anlegen neuer Dateien restorecon -Rv /etc/nginx/tls aus.

Neues Zertifikat prüfen

openssl s_client -connect www.example.com:443 -servername www.example.com -showcerts </dev/null
openssl x509 -in leaf.pem -noout -fingerprint -sha256

Prüfen Sie Antragsteller und SAN, Aussteller, Ablaufdatum und ob das Zwischenzertifikat mitgesendet wird, und vergleichen Sie den Fingerabdruck des ausgelieferten Zertifikats mit dem von leaf.pem. Testen Sie auch über jeden Load Balancer.

Rollback

Symlink auf das vorherige Verzeichnis zurückstellen, testen und neu laden:

ln -sfn /etc/nginx/tls/example-2025 /etc/nginx/tls/example-current
nginx -t && systemctl reload nginx

Prüfen Sie danach erneut das ausgelieferte Zertifikat. Das setzt voraus, dass das alte Verzeichnis noch existiert - löschen Sie es erst, wenn das neue Zertifikat geprüft ist.

Häufige Probleme

  • Schlüssel und Zertifikat gehören nicht zusammen.
  • Zwischenzertifikate fehlen oder stehen vor dem Serverzertifikat.
  • Zwei Zertifikate sind verschmolzen, weil einer Datei der abschließende Zeilenumbruch fehlte.
  • NGINX wurde ohne nginx -t neu geladen.
  • Die Testanfrage lief ohne SNI und landete beim Standardserver.
  • Im Container zeigt ein Bind-Mount einer einzelnen Datei weiter die alte Datei.

Zertifikatstausch mit aethercert automatisieren

Das aethercert-Deployment-Ziel für NGINX schreibt Zertifikatskette und privaten Schlüssel, setzt Besitzer und Rechte des Schlüssels passend zur NGINX-Konfiguration und führt den konfigurierten Reload-Befehl aus.

Unter Deployment-Ziele finden Sie die Felder dieser Vorlage, die Voraussetzungen auf dem Host und den Stand der Verifizierung.

Quellen

Auf dieser Seite