DST Root CA X3 Expiration | Let's Encrypt
Updated at: 04/10/2021


A seguito dell'imminente scadenza del root-certificate DST Root CA X3 alcuni sistemi potrebbero non riconoscere più i certificati emessi da Let's Encrypt (https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/)

In particolare il problema si presenta in uno dei due seguenti scenari:

  • il sistema (client) non è aggiornato da così tanto tempo da non avere tra i propri certificati trusted il nuovo root-ca "ISRG Root X1"
  • il sistema ha entrambi i certificati (X3 e X1) ma si basa su una versione di openssl < 1.1.0


ATTENZIONE! I passi successivi si riferiscono ad azioni da effettuare sui sistemi client che dialogano con server coperti da certificati Let's Encrypt. Lato server, per gli ambienti Linux non sono necessarie azioni particolari perché il client di rinnovo fornisce già il certificato corretto.

Per i server Windows che utilizzano win-acme leggere la sezione apposita in fondo



Nel primo caso credo sia sufficiente aggiornare le ca-certificates in modo da avere anche le ultime versioni.

Per scoprire se sono presenti i due certificati eseguire il comando:

## Debian
awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep "DST\|ISRG"

## CentOS7
awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-bundle.crt | grep "DST\|ISRG"

## in generale...
awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < percorso-del-file-certificate | grep "DST\|ISRG"


Provo a riportare i punti salienti per verificare se un sistema ha problemi e nel caso come (provare a) risolverlo.

Per fare i test serve il componente “faketime”

Debian

sudo apt install faketime

CentOS7

sudo yum install faketime

Se non è presente nei repo, va scaricato e compilato da qui: https://github.com/wolfcw/libfaketime

Test sistema base:

entrambi questi comandi devono mostrare 200 nello status code e non dare eccezioni

wget --server-response --spider https://techseed.it/
faketime '1 Oct 2021' wget --server-response --spider https://techseed.it/


Fix sistema base:

CentOS7:

## soluzione 1 -> l'ultima versione attualmente rilasciata (2021.2.50-72.el7_9) rimuove automaticamente il certificato X3 scaduto
sudo yum update ca-certificates

## soluzione 2 (se non funzionasse la prima)
trust dump --filter "pkcs11:id=%c4%a7%b1%a4%7b%2c%71%fa%db%e1%4b%90%75%ff%c4%15%60%85%89%10" | openssl x509 | sudo tee /etc/pki/ca-trust/source/blacklist/DST-Root-CA-X3.pem
sudo update-ca-trust extract


Debian

sudo cp /etc/ca-certificates.conf /etc/ca-certificates.conf.orig
sudo nano /etc/ca-certificates.conf
sostituire la riga “mozilla/DST_Root_CA_X3.crt” con “!mozilla/DST_Root_CA_X3.crt
sudo update-ca-certificates


A questo punto entrambi i comandi di cui sopra dovrebbero funzionare correttamente.


Python

Tendenzialmente dovrebbe andare a posto con l'aggiornamento dei certificati di sistema.

Se python utilizza requests, bisogna capire dove sono i suoi certificati, potrebbero essere gli stessi del SO (e in tal caso dovrebbe essere già tutto a posto con i comandi di cui sopra) oppure averne una propria versione che nel caso va corretta.
Sia per python2 che per python3 la strada è medesima (adeguando i comandi e i percorsi)

Test

python -c "import requests; print(requests.get('https://www.techseed.it').status_code)"
faketime '1 Oct 2021' python -c "import requests; print(requests.get('https://www.techseed.it').status_code)"

Se il secondo comando fallisce dobbiamo scoprire dove sono i certificati di python

python -c "import requests; print(requests.certs.where())"

/etc/ssl/certs/ca-certificates.crt --> tendenzialmente questo caso non dovrebbe dare problemi perché usa i certificati del SO precedentemente aggiornati

/usr/local/lib/python2.7/dist-packages/certifi/cacert.pem --> è il caso che potrebbe dare problemi

sudo cp /usr/local/lib/python2.7/dist-packages/certifi/cacert.pem /usr/local/lib/python2.7/dist-packages/certifi/cacert.pem.orig
sudo nano /usr/local/lib/python2.7/dist-packages/certifi/cacert.pem

Cerchiamo il certificato "DST" che presenterà un'intestazione tipo questa:

# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co.

Cancelliamo a mano tutto il blocco del certificato e salviamo il file.

A questo punto i comandi di test dovrebbero funzionare entrambi



PHP

Tendenzialmente anche PHP (a meno di configurazioni particolari nel file .ini) dovrebbe seguire i certificati di sistema.

Per testare se tutto funzionerà a dovere:

## file_get_contents --> è il test più significativo
php -r 'file_get_contents("https://techseed.it/", false, stream_context_create(["http" => ["ignore_errors" => true]])); var_dump($http_response_header);'
faketime '1 Oct 2021' php -r 'file_get_contents("https://techseed.it/", false, stream_context_create(["http" => ["ignore_errors" => true]])); var_dump($http_response_header);'

## curl --> può essere che funzioni basandosi sui certificati di sistema anche ma il comando di prima fallirebbe comunque
php -r '$ch = curl_init("https://techseed.it/"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); $info = curl_getinfo($ch); echo "\n".$info["http_code"]."\n".$info["ssl_verify_result"]."\n"; curl_close($ch);'
faketime '1 Oct 2021' php -r '$ch = curl_init("https://techseed.it/"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); $info = curl_getinfo($ch); echo "\n".$info["http_code"]."\n".$info["ssl_verify_result"]."\n"; curl_close($ch);'


Se invece php non usa i certificati di sistema (ad esempio spesso su windows si passano dei certificati ad hoc) va aggiornato il file che usa php.

Scaricare da qui la versione aggiornata https://curl.haxx.se/ca/cacert.pem e modificare i parametri seguenti di php.ini impostando il giusto percorso file

curl.cainfo="/path/to/cacert.pem"
openssl.cafile="/path/to/cacert.pem"


Server Windows

Per i server Windows che utilizzano win-acme per IIS, nonostante la versione 2.1.19 dovrebbe risolvere il problema dell'issuer, c'è un problema di "concorrenzialità" del certificato intermedio R3, quindi può capitare che venga distribuita una catena di certificati con l'R3 che scade il 29/09/2021 anche se è presente la versione nuova aggiornata.

Al momento l'unica soluzione che ho trovato è quella di invalidare sul server la versione in scadenza del certificato R3 e quindi rinnovare a mano in modo forzato i certificati

Qui vengono spiegati i passaggi per disabilitare il certificato: https://github.com/win-acme/win-acme/issues/1918#issuecomment-913193060 che sostanzialmente sono:

  • Start > Manage Computer Certificates > Intermediate Certification Authorities > Certificates
  • Right-click on the R3 certificate which is expiring -> Properties
  • Under "Certificate Purposes", choose "Disable all purposes for this certificate"


Per forzare il rinnovo dei certificati, eseguire il client wacs con l'opzione --force

.\wacs.exe --force

quindi selezionare il menu "A" e poi "R"

A questo punto IIS rilascerà la versione corretta con tutta la catena aggiornata