Pular para o conteúdo
ecdsa.com
Node.js tls.checkServerIdentity()Módulo crypto do Node.js

Mensagem de erro

Hostname/IP does not match certificate's altnames: Host: api.example.com. is not in the cert's altnames: DNS:www.example.com

Também aparece como

  • Hostname/IP does not match certificate's altnames: IP: 127.0.0.1 is not in the cert's list:
  • code: 'ERR_TLS_CERT_ALTNAME_INVALID'
  • ERR_TLS_CERT_ALTNAME_INVALID

O host e a lista de altnames são preenchidos a cada falha. Para endereços IP, o texto é “Hostname/IP does not match certificate's altnames: IP: <address> is not in the cert's list: <entries>”. O npm mostra o erro como “npm error code ERR_TLS_CERT_ALTNAME_INVALID”.

Node.js tls.checkServerIdentity() — code ERR_TLS_CERT_ALTNAME_INVALID

O que significa

A cadeia de certificados é confiável, mas tls.checkServerIdentity() não encontrou nenhum Subject Alternative Name que corresponda ao host ao qual o Node.js se conectou. A mensagem mostra os dois lados: o host que você pediu e os nomes que o certificado realmente contém, então a divergência fica evidente à primeira vista. O Common Name é ignorado quando o certificado tem uma extensão SAN.

Por que acontece

Como corrigir

  1. 1.

    Listar os nomes do certificado

    Compare o subjectAltName com o host ao qual você se conecta.

    bash
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
      | openssl x509 -noout -ext subjectAltName
  2. 2.

    Reemitir com todos os nomes em uso

    Inclua todos os nomes DNS e, onde os clientes se conectam por endereço, as entradas de IP.

    bash
    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.

    Definir servername ao conectar por endereço

    Mantenha o nome do certificado em servername (e no cabeçalho Host) e conecte-se ao endereço; assim a verificação usa o nome correto em vez de ser desativada.

    js
    // Connect to an address but verify the certificate's real name (also sent as SNI)
    import https from "node:https";
    
    https.get({ host: "10.0.0.5", port: 443, path: "/", servername: "api.example.com",
                headers: { host: "api.example.com" } }, (res) => res.resume());
  4. 4.

    Exceção restrita com checkServerIdentity

    Para um host legado cujo certificado ainda não pode ser reemitido, mapeie um único alias conhecido para o nome do certificado e delegue para tls.checkServerIdentity(). Nunca retorne undefined incondicionalmente: isso desativa completamente a verificação do nome.

    js
    // Narrow exception for a host you cannot reissue: accept one extra name, keep all other checks
    import https from "node:https";
    import tls from "node:tls";
    
    const agent = new https.Agent({
      checkServerIdentity: (host, cert) =>
        tls.checkServerIdentity(host === "legacy-alias.internal" ? "api.example.com" : host, cert),
    });

Erros relacionados

Ver toda a base de erros de assinatura