Message d’erreur
state=error: certificate verify failed (unable to get local issuer certificate)
Également affiché sous la forme
- OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 peeraddr=127.0.0.1:8443 state=error: certificate verify failed (unable to get local issuer certificate)
Le message complet est « SSL_connect returned=1 errno=0 peeraddr=<ip>:<port> state=error: certificate verify failed (unable to get local issuer certificate) » ; lors de nos tests, peeraddr figurait dans le message avec la gem openssl 3.0.1 à 4.0.2. Faraday l’enveloppe dans Faraday::SSLError avec le même message ; les bibliothèques qui appellent Net::HTTP directement laissent passer OpenSSL::SSL::SSLError tel quel.
Ruby openssl (Net::HTTP, Faraday, HTTParty, RubyGems) — OpenSSL::SSL::SSLError from SSL_connect
Ce que cela signifie
La liaison OpenSSL de Ruby (utilisée par Net::HTTP, et donc par la plupart des clients HTTP Ruby) n’a pas trouvé l’émetteur de la chaîne de certificats du serveur parmi les AC qu’elle charge. Le texte entre parenthèses est le motif de vérification d’OpenSSL ; tout ce qui précède indique à quel endroit de SSL_connect l’échec s’est produit. En général, l’AC est privée ou se trouve derrière un proxy, ou bien ce Ruby consulte un fichier d’AC qui ne la contient pas.
Pourquoi cela se produit
Une AC privée ou un proxy d’inspection TLS
fréquenteLa chaîne se termine par une racine absente du magasin OpenSSL qu’utilise Ruby.
Un Ruby compilé avec son propre OpenSSL (rbenv, asdf, rvm sous macOS)
fréquenteCes Ruby utilisent le fichier d’AC de l’OpenSSL de Homebrew ou de l’OpenSSL embarqué, et non le trousseau macOS ; les racines ajoutées au trousseau par le service informatique ne s’appliquent pas.
Le serveur omet son certificat intermédiaire
occasionnelleOpenSSL ne récupère pas les certificats intermédiaires manquants : un serveur qui n’envoie que son certificat feuille échoue donc ici, alors que les navigateurs l’acceptent.
RubyInstaller sous Windows
occasionnelleRuby sous Windows est livré avec son propre fichier d’AC ; les racines d’entreprise du magasin Windows n’en font pas automatiquement partie.
Comment corriger l’erreur
- 1.
Installer la racine là où la cherche l’OpenSSL de Ruby
OpenSSL::X509::DEFAULT_CERT_FILE et DEFAULT_CERT_DIR indiquent le chemin du fichier et celui du répertoire ; sous Debian et Ubuntu, update-ca-certificates met à jour ces emplacements.
bash # Ruby's OpenSSL reads the system bundle (see its default paths) ruby -ropenssl -e 'p OpenSSL::X509::DEFAULT_CERT_FILE, OpenSSL::X509::DEFAULT_CERT_DIR' sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && sudo update-ca-certificates - 2.
Définir SSL_CERT_FILE pour le processus
OpenSSL tient compte de SSL_CERT_FILE et de SSL_CERT_DIR ; faites-les pointer vers un fichier d’AC qui contient les racines publiques et votre AC.
bash # One process / environment: point OpenSSL at a bundle with the needed roots export SSL_CERT_FILE=/etc/ssl/private-ca/corp-ca-bundle.pem ruby app.rb - 3.
Donner à un client son propre magasin
Un OpenSSL::X509::Store avec set_default_paths puis add_file conserve les racines publiques et ajoute l’AC privée, avec une vérification complète.
ruby # One client: default roots plus a private CA store = OpenSSL::X509::Store.new store.set_default_paths store.add_file("/etc/ssl/private-ca/corp-root-ca.pem") http = Net::HTTP.new("api.example.com", 443) http.use_ssl = true http.cert_store = store - 4.
Faraday et autres surcouches : passer ca_file ou cert_store
La plupart des bibliothèques HTTP Ruby acceptent des options ssl qui correspondent aux paramètres ca_file, ca_path ou cert_store de Net::HTTP.
ruby conn = Faraday.new("https://api.example.com", ssl: { ca_file: "/etc/ssl/private-ca/corp-root-ca.pem" })
Erreurs associées
state=error: certificate verify failed (self-signed certificate in certificate…Ruby openssl (Net::HTTP, Faraday, RubyGems)Could not verify the SSL certificate for https://gems.example.com/.Bundlercurl: (60) SSL certificate problem: unable to get local issuer certificatecurl (OpenSSL backend)[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local…Python ssl module (OpenSSL)