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

Mensagem de erro

curl: (60) SSL: no alternative certificate subject name matches target hostname 'api.example.com'

Também aparece como

  • curl: (60) SSL: no alternative certificate subject name matches target host name 'api.example.com'

O curl 8.x imprime “target hostname”; o curl 7.x imprimia “target host name”. O host entre aspas é o que estiver na URL. Versões muito antigas do curl (anteriores à 7.62.0) usavam o código de saída 51 para essa verificação.

curl (OpenSSL backend) — CURLE_PEER_FAILED_VERIFICATION, hostname check in lib/vtls/openssl.c

O que significa

A cadeia de certificados é confiável, mas nenhum dos nomes DNS (ou endereços IP) na extensão Subject Alternative Name do certificado corresponde ao host da URL. O curl compara o host da URL apenas com as entradas SAN; o Common Name do titular é ignorado quando há uma extensão SAN. O nome entre aspas no final é o host que o curl foi instruído a acessar.

Por que acontece

Como corrigir

  1. 1.

    Comparar a lista de SANs com a URL

    Imprima a extensão subjectAltName do certificado servido. A correção é um certificado que liste o nome ou uma URL que use um dos nomes listados.

    bash
    # Names the served certificate actually covers
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
      | openssl x509 -noout -subject -ext subjectAltName
  2. 2.

    Reemitir o certificado com todos os nomes em uso

    Solicite todos os nomes de host (e endereços IP, se os clientes se conectam por IP) como entradas SAN. Colocar o nome apenas no Common Name não funciona com nenhum cliente atual.

    bash
    # ACME: list every name the certificate must cover
    sudo certbot certonly --nginx -d example.com -d www.example.com -d api.example.com
    
    # Private CA: put all names into subjectAltName (CN is ignored for matching)
    openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \
      -addext "subjectAltName=DNS:api.example.com,DNS:www.example.com,IP:10.0.0.5"
  3. 3.

    Manter o nome e trocar só o endereço

    Quando você precisa chegar a um endereço específico (um nó do balanceador de carga, um túnel, um IP de homologação), --resolve ou --connect-to mantém o host da URL, então o SNI e a verificação do nome de host continuam usando o nome do certificado.

    bash
    # Keep the certificate's name in the URL and steer the connection to another address
    curl --resolve api.example.com:443:10.0.0.5 https://api.example.com/
    curl --connect-to api.example.com:443:lb-internal.example.net:443 https://api.example.com/
  4. 4.

    Donos do servidor: verificar o roteamento por SNI

    Se o certificado muda entre requisições com e sem SNI, adicione um bloco server (ou uma regra de ingress) para o nome e garanta que os clientes não recebam o certificado padrão para nomes de host reais.

    bash
    # Compare what the server returns with and without SNI
    openssl s_client -connect 10.0.0.5:443 -servername api.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject
    openssl s_client -connect 10.0.0.5:443 -noservername </dev/null 2>/dev/null | openssl x509 -noout -subject

Erros relacionados

Ver toda a base de erros de assinatura