Mensagem de erro
npm error code UNABLE_TO_VERIFY_LEAF_SIGNATURE
Também aparece como
- npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
- npm error request to https://registry.example.com/lodash failed, reason: unable to verify the first certificate
O npm 10 e posteriores imprimem “npm error code UNABLE_TO_VERIFY_LEAF_SIGNATURE”; o npm 9 e anteriores, “npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE”. Versões recentes do Node.js acrescentam “; if the root CA is installed locally, try running Node.js with --use-system-ca” à linha do motivo.
npm (Node.js) — registry request over HTTPS
O que significa
O registro (ou um proxy na frente dele) enviou só o próprio certificado, e o Node.js não encontrou o certificado que o emitiu. Sem o emissor, não há como verificar a assinatura do certificado folha. É um problema de configuração do servidor: falta o certificado intermediário no handshake, e o Node.js não corrige isso baixando-o.
Por que acontece
Um registro privado configurado só com o certificado folha
comumNexus, Artifactory, Verdaccio ou um proxy reverso na frente deles instalados com cert.pem em vez da cadeia completa.
Um proxy que apresenta só o certificado folha
ocasionalAlguns proxies com inspeção de TLS enviam um certificado emitido por um intermediário sem incluir esse intermediário.
Um certificado folha de uma CA privada desconhecida
ocasionalSe o Node.js não conhece nada acima do certificado folha, aparece o mesmo código; confiar na CA (e no intermediário dela) resolve.
Como corrigir
- 1.
Contar os certificados do handshake
Se aparecer só a profundidade 0, com um intermediário como emissor, está confirmado que falta o intermediário.
bash openssl s_client -connect registry.example.com:443 -servername registry.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:' - 2.
Servir a cadeia completa no registro
Configure o terminador TLS na frente do registro com o certificado folha e os intermediários. Isso corrige o npm, o yarn, o pnpm, o Docker e todos os outros clientes de uma vez.
text # Registry behind nginx: serve leaf + intermediate(s) ssl_certificate /etc/nginx/tls/registry.example.com.fullchain.pem; ssl_certificate_key /etc/nginx/tls/registry.example.com.key; - 3.
Solução de contorno: confiar no intermediário no cliente
Um cafile com o intermediário e a raiz dele permite que o npm verifique o certificado folha até que o servidor seja corrigido; o cafile substitui as raízes padrão do npm, então adicione também as raízes públicas se o mesmo npm também usa o registry.npmjs.org.
bash # Until the registry is fixed: trust the intermediate (plus its root) on the client cat issuing-ca.pem corp-root-ca.pem > /etc/ssl/private-ca/registry-ca.pem npm config set cafile /etc/ssl/private-ca/registry-ca.pem