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:
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
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/
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.
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
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"
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:
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