Pular para o conteúdo
ecdsa.com
curl (OpenSSL backend)curl

Mensagem de erro

curl: (60) SSL certificate problem: certificate has expired

Também aparece como

  • curl: (60) SSL certificate OpenSSL verify result: certificate has expired (10)

O texto do motivo é idêntico em builds do curl com OpenSSL 1.1.1, 3.0 e 3.5. Versões mais novas do curl (8.22.0 no nosso teste) formulam assim: “SSL certificate OpenSSL verify result: certificate has expired (10)”. Certificados que ainda não são válidos produzem outro motivo: “certificate is not yet valid”.

curl (OpenSSL backend) — CURLE_PEER_FAILED_VERIFICATION, X509_V_ERR_CERT_HAS_EXPIRED (10)

O que significa

Um certificado da cadeia montada pelo curl tem data notAfter anterior ao horário atual da máquina que executa o curl. Normalmente é o próprio certificado do servidor, mas um intermediário expirado ou uma raiz com assinatura cruzada produz o mesmo texto. A verificação é feita com o relógio local, então um relógio errado produz exatamente o mesmo erro que um certificado expirado.

Por que acontece

Como corrigir

  1. 1.

    Descobrir qual certificado expirou

    Imprima a data notAfter de cada certificado que o servidor envia. Se o certificado folha expirou, renove-o; se for um intermediário, substitua o arquivo da cadeia pelo que sua CA publica atualmente.

    bash
    # Split the served chain into cert1.pem (leaf), cert2.pem, ... and print each expiry date
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | awk '/BEGIN CERT/{n++; f="cert" n ".pem"} /BEGIN CERT/,/END CERT/{print > f}'
    for f in cert*.pem; do openssl x509 -in "$f" -noout -subject -enddate; done
  2. 2.

    Renovar, recarregar e verificar o que é servido de fato

    Depois de renovar, recarregue todos os processos e dispositivos que fazem a terminação TLS desse nome e confirme a data pelo lado da rede, e não pelo arquivo no disco.

    bash
    sudo certbot renew                    # or your ACME client / CA portal
    sudo systemctl reload nginx           # the server keeps serving the old file until reloaded
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
      | openssl x509 -noout -enddate      # confirm the new date is what the network sees
  3. 3.

    Corrigir o relógio do cliente

    Quando o certificado funciona em outras máquinas, sincronize via NTP a hora da máquina com falha. Em contêineres, o relógio vem do host, então corrija-o lá.

    bash
    date -u                       # compare with the real UTC time
    timedatectl status            # "System clock synchronized: yes"?
    sudo timedatectl set-ntp true
  4. 4.

    Atualizar o bundle de CAs do cliente

    Em sistemas que ficam muito tempo em operação, um pacote ca-certificates atualizado remove raízes aposentadas e adiciona as atuais, o que permite ao OpenSSL escolher um caminho válido em vez de um expirado.

    bash
    # Old clients: refresh the root store so they stop building paths through retired roots
    sudo apt-get update && sudo apt-get install --only-upgrade ca-certificates   # Debian/Ubuntu
    sudo dnf upgrade ca-certificates                                             # RHEL/Fedora

Erros relacionados

Ver toda a base de erros de assinatura