QTS SSL-Zertifikat 2.2.73: letsencrypt_agent_cli-Binary fügt abgelaufene DST Root CA X3 zur Zertifikatkette hinzu, was strikte TLS-Clients (Alexa, AWS Lambda) lahmlegt

Umgebung

  • QTS SSL-Zertifikat: v2.2.73 (Build 20260310, aktualisiert am 2026-07-09 — aktuellste Version)

  • Domain: benutzerdefinierte DDNS (*.myqnapcloud.com)

  • Nginx vorgeschaltet vor Home Assistant

Fehler

Nach jeder Let’s Encrypt-Erneuerung hängt das Binary letsencrypt_agent_cli von QcloudSSLCertificate das abgelaufene DST Root CA X3-Zertifikat (abgelaufen am 30. September 2021) an /etc/stunnel/uca.pem an. Dadurch schlägt die TLS-Verifizierung für alle strikten Clients wie Alexa Smart Home, AWS Lambda, curl ohne -k usw. fehl, obwohl das Leaf-Zertifikat und die Kette eigentlich gültig sind.

Ursache

Der acme-tiny-Schritt holt korrekt nur das YR1 Intermediate:

cert/chain → YR1 only (das ist gut)

Aber letsencrypt_agent_cli schreibt dann intermediate.pem (kopiert nach uca.pem) wie folgt:

cert/intermediate.pem → YR1 + DST Root CA X3 (abgelaufen 2021) (das ist schlecht)

Das DST-Zertifikat wird im Binary beim Zusammenstellen der Zertifikatskette hardcodiert. cert/chain (der rohe acme-tiny Output) ist sauber — die Korruption passiert im kompilierten Binary.

Das passiert vermutlich, weil LetsEncrypt am 27. Mai 2026 die CA-Hierarchie geändert hat (Quelle1)

Verifizierung

# cert/chain — sauber

openssl x509 -noout -subject -dates -in /mnt/ext/opt/QcloudSSLCertificate/cert/chain

# subject=C=US, O=Let’s Encrypt, CN=YR1 | notAfter=2. Sep 2028 23:59:59 GMT (gut)

# cert/intermediate.pem — fehlerhaft

awk ‘…’ /mnt/ext/opt/QcloudSSLCertificate/cert/intermediate.pem | openssl x509 -noout -subject -dates

# Zertifikat 1: YR1 notAfter=2. Sep 2028 (gut)

# Zertifikat 2: DST Root CA X3 notAfter=30. Sep 2021 14:01:15 (schlecht)

Auswirkung

Browser ignorieren das zusätzliche Zertifikat und verifizieren korrekt. Doch jeder Client mit strikter Kettenvalidierung (Alexa Smart Home Skill, AWS Lambda, Standard-curl) erhält SSL: unable to get local issuer certificate und schlägt fehl.

Workaround (bis zum Fix)

Ein tägliches Cron-Skript, das die nginx.pem aus den sauberen Dateien neu baut, abgelaufene Zertifikate entfernt und das cross-signierte ISRG Root YR anhängt:

0 4 * * * /share/CACHEDEV1_DATA/build_nginx_pem.sh

Benötigter Fix

Der Hardcode für das DST Root CA X3 muss aus letsencrypt_agent_cli entfernt werden. Das Binary soll beim Erstellen von intermediate.pem/uca.pem ausschließlich die Zertifikate aus cert/chain verwenden.

Weitere Lösung aus der OSS-Community: