All links of one day
in a single page.
<Previous day - Next day>

rss_feedDaily RSS Feed
floral_left The Daily Shaarli floral_right
——————————— Monday 18, January 2021 ———————————

Utilisateurs de Let's Encrypt et d'un client ACME minimaliste, attention au nouveau certificat intermédiaire R3

Résumé : Let's Encrypt a remplacé son vieux certificat intermédiaire nommé « Let's Encrypt Authority X3 » par un nouveau nommé « R3 ». Si tu utilises une implémentation minimaliste d'ACME (genre acme-tiny) qui récupère uniquement le certificat de ton site web auprès de Let's Encrypt, il faudra changer toi-même le certificat intermédiaire dans tes serveurs TLS, sans quoi une partie des clients web ne pourra plus accéder à ton service.



Depuis plusieurs semaines, plusieurs flux RSS sont en erreur « 60 SSL certificate problem: unable to get local issuer certificate » dans mon agrégateur RSS.

Pourtant, j'accède sans problèmes à ces sites web avec Firefox.

J'essaye d'accéder aux sites web depuis le serveur qui héberge mon lecteur de flux RSS :

$ wget https://exegetes.eu.org
--2021-01-18 22:30:45--  https://exegetes.eu.org/
Résolution de exegetes.eu.org (exegetes.eu.org)… 2001:910:800::82, 80.67.169.82
Connexion à exegetes.eu.org (exegetes.eu.org)|2001:910:800::82|:443… connecté.
Erreur : le certificat de « exegetes.eu.org » n’est pas de confiance.
Erreur: The certificate of « exegetes.eu.org » doesn't have a known issuer.

Même problème avec cURL :

$ curl https://exegetes.eu.org
curl: (60) SSL certificate problem: unable to get local issuer certificate

Au moins, le problème ne dépend pas d'une bibliothèque TLS en particulier car wget utilise GnuTLS alors que curl utilise OpenSSL.

Ce n'est plus une erreur relative à PHP comme à l'époque où mon chroot Apache httpd empêchait PHP d'utiliser le magasin des autorités de certification du système. Chroot que j'ai viré depuis afin d'activer HTTP/2.

Sur mon ordinateur de bureau, wget génère la même erreur.

Tous les sites web concernés utilisent Let's Encrypt malgré le danger que constitue sa force de frappe.



Creusons un peu :

$ openssl s_client -connect exegetes.eu.org:443
CONNECTED(00000003)
depth=0 CN = exegetes.eu.org
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = exegetes.eu.org
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:CN = exegetes.eu.org
   i:C = US, O = Let's Encrypt, CN = R3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3

$ openssl s_client -connect jonathan.michalon.eu:443
CONNECTED(00000003)
depth=0 CN = jonathan.michalon.eu
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = jonathan.michalon.eu
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:CN = jonathan.michalon.eu
   i:C = US, O = Let's Encrypt, CN = R3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3

$ openssl s_client -connect www.codelyoko.fr:443
CONNECTED(00000003)
depth=0 CN = www.codelyoko.fr
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = www.codelyoko.fr
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:CN = www.codelyoko.fr
   i:C = US, O = Let's Encrypt, CN = R3

Le testeur TLS de SSLLabs affiche « This server's certificate chain is incomplete […] Chain issues Incomplete, Extra certs ».

Les deux premiers cas sont identiques : le serveur présente le certificat x509 du site web (dit certificat feuille), signé par le certificat intermédiaire R3 de Let's Encrypt ainsi que le certificat X3 de Let's Encrypt signé par IdenTrust (DST). La chaîne de certification est cassée : site web - R3 !- X3 - DST. Comme le certificat intermédiaire R3 n'est pas disponible dans le magasin de certificats de Debian (et c'est normal, aucun certificat intermédiaire l'est), c'est game over.

Le dernier cas est encore plus simple : le certificat intermédiaire n'est pas communiqué par le serveur, seul le certificat feuille l'est. Comme R3 n'est pas présent dans le magasin des certificats des autorités de certification de Debian, c'est l'échec.



Que s'est-il passé ? Depuis le 20 décembre 2020, Let's Encrypt signe les nouveaux certificats de ses """"clients"""" avec son nouveau certificat intermédiaire nommé R3. Ce dernier remplace Let's Encrypt Authority X3 qui expire en 2021 (il a une durée de vie de 5 ans).

Tu vas me dire "ben oui mais l'API de Let's Encrypt retourne, en plus du certificat client, le nouveau certificat intermédiaire (R3), donc tout devrait fonctionner". Oui, sauf si un site web utilise un outil minimaliste de renouvellement automatique des certificats. Exemple : jonathan.michalon.eu utilise acme-tiny qui récupère uniquement le certificat client, charge à l'utilisateur de configurer un certificat intermédiaire indépendemment.



Pourquoi cela fonctionne avec Firefox et Chromium, alors ? Quand tu accèdes à un site web avec une chaîne valide, Firefox enregistre le certificat R3 et, du coup, est capable de le resortir pour compléter le maillon manquant quand un site web a une chaîne incomplète. Cela se fait sans que le certificat R3 apparaisse forcément dans le catalogue des certificats… Pour valider cette hypothèse, il suffit d'utiliser un vieux profil qui a jamais connu R3 et d'aller directement sur un site web défectueux : une erreur s'affiche. En allant sur un site web qui utilise R3 dans une chaîne complète puis en retournant sur le site web défectueux, plus aucune erreur s'affiche.

-