Message d’erreur
cURL error 60: SSL certificate problem: unable to get local issuer certificate
Également affiché sous la forme
- GuzzleHttp\Exception\ConnectException: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.se/libcurl/c/libcurl-errors.html) for https://api.example.com:8443/
Guzzle la met en forme ainsi : « cURL error 60: SSL certificate problem: <reason> (see https://curl.se/libcurl/c/libcurl-errors.html) for <url> » ; les anciennes versions de Guzzle renvoyaient vers https://curl.haxx.se/libcurl/c/libcurl-errors.html. La raison qui suit « problem: » varie (« self-signed certificate in certificate chain », « certificate has expired »). Appelée directement, curl_error() renvoie le texte qui suit « cURL error 60: ».
PHP — Guzzle (and Laravel HTTP client, Symfony HttpClient on curl) over ext-curl; curl_errno() 60
Ce que cela signifie
L’extension curl de PHP (utilisée par Guzzle, le client HTTP de Laravel et le transport curl de Symfony HttpClient) n’a pas pu vérifier le certificat du serveur : erreur libcurl 60, avec la raison OpenSSL « unable to get local issuer certificate ». libcurl n’a trouvé dans son fichier d’AC aucune AC ayant émis la chaîne du serveur. Sous Windows, le fichier d’AC n’est souvent pas configuré du tout ; ailleurs, l’AC est privée ou le serveur omet un certificat intermédiaire.
Pourquoi cela se produit
PHP sous Windows sans fichier d’AC
fréquenteLes builds PHP pour Windows ne fournissent pas de fichier d’AC ; tant que curl.cainfo ne pointe pas vers un tel fichier (par exemple le cacert.pem du projet curl), chaque requête HTTPS échoue de cette manière.
Une AC privée ou un proxy d’inspection TLS
fréquenteLes API internes et les connexions qui passent par un proxy ont des chaînes qui aboutissent à des racines absentes du fichier d’AC qu’utilise libcurl.
Le serveur omet son certificat intermédiaire
occasionnellelibcurl avec OpenSSL ne récupère pas les certificats intermédiaires manquants.
Images de conteneur sans certificats d’AC (à jour)
occasionnelleLes images PHP personnalisées construites sans ca-certificates, ou avec un fichier d’AC ancien, échouent aussi pour les hôtes publics.
Comment corriger l’erreur
- 1.
Configurer curl.cainfo et openssl.cafile
Définissez les deux dans php.ini pour qu’ext-curl et les flux PHP utilisent le même fichier d’AC ; n’oubliez pas que la CLI et PHP-FPM chargent souvent des fichiers php.ini différents.
ini ; php.ini — CA bundle for ext-curl (Guzzle, Laravel Http, Symfony HttpClient) and for streams curl.cainfo = "/etc/ssl/certs/ca-certificates.crt" openssl.cafile = "/etc/ssl/certs/ca-certificates.crt" ; Windows: download cacert.pem from https://curl.se/docs/caextract.html and use its full path - 2.
Guzzle : passer un fichier d’AC à verify
L’option verify accepte le chemin d’un fichier d’AC ; Guzzle vérifie que le fichier existe et lève sinon « SSL CA bundle not found ».
php // Trust a private CA for one client: verify takes a CA bundle path $client = new GuzzleHttp\Client(['verify' => '/etc/ssl/private-ca/corp-root-ca.pem']); $response = $client->get('https://api.example.com/'); - 3.
Installer l’AC dans le magasin du système
Sous Linux, les extensions curl et OpenSSL de PHP utilisent par défaut le fichier d’AC de la distribution ; openssl_get_cert_locations() affiche les chemins.
bash # Debian/Ubuntu-based PHP images: install the root, then check what PHP uses cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && update-ca-certificates php -r 'var_dump(openssl_get_cert_locations()); echo ini_get("curl.cainfo"), PHP_EOL;' - 4.
Vérifier quel php.ini est actif
php --ini liste les fichiers chargés ; une directive ajoutée au mauvais fichier (CLI, FPM ou Apache) n’a aucun effet.
bash php --ini # which php.ini files are loaded (CLI and FPM differ!) php -i | grep -E 'curl.cainfo|openssl.cafile'
Erreurs associées
cURL error 77: error setting certificate file: /etc/ssl/missing-ca.pemPHP ext-curl (Guzzle, Laravel HTTP client)SSL operation failed with code 1. OpenSSL Error messages:PHP streams (file_get_contents, fopen, stream_socket_client, SoapClient, mail libraries)curl: (60) SSL certificate problem: unable to get local issuer certificatecurl (OpenSSL backend)