Falhas no handshake de SSL: certificado de cliente inválido

Esta é a documentação do Apigee Edge.
Acesse Documentação da Apigee X.
informações

Sintoma

O aplicativo cliente recebe o código de status HTTP 503 com a mensagem "Service Unavailable" em resposta a uma solicitação de API. No trace de IU, você vai observar que o erro error.cause é Received fatal alert: bad_certificate no fluxo de solicitação de destino. para a solicitação de API com falha.

Se você tiver acesso aos registros do processador de mensagens, você notará a mensagem de erro como Received fatal alert: bad_certificate para a solicitação de API com falha. Esse erro é observado durante o handshake de SSL processo entre o processador de mensagens e o servidor de back-end em uma configuração TLS bidirecional.

Mensagem de erro

O aplicativo cliente recebe o seguinte código de resposta:

HTTP/1.1 503 Service Unavailable

Além disso, você poderá encontrar a seguinte mensagem de erro:

{
 "fault": {
    "faultstring":"The Service is temporarily unavailable",
    "detail":{
        "errorcode":"messaging.adaptors.http.flow.ServiceUnavailable"
    }
 }
}

Os usuários da nuvem privada verão o seguinte erro na solicitação de API específica nos registros do processador de mensagens /opt/apigee/var/log/edge-message-processor/system.log:

2017-10-23 05:28:57,813 org:org-name env:env-name api:apiproxy-name rev:revision-number messageid:message_id NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context.handshakeFailed() : SSLClientChannel[C:IP address:port # Remote host:IP address:port #]@65461 useCount=1 bytesRead=0 bytesWritten=0 age=529ms lastIO=529ms handshake failed, message: Received fatal alert: bad_certificate

Causas possíveis

Estas são as possíveis causas desse problema:

Causa Descrição Instruções para solução de problemas aplicáveis
Sem certificado do cliente O keystore usado no endpoint de destino do servidor de destino não tem nenhum certificado do cliente. Usuários de nuvem pública e privada de borda
Incompatibilidade da autoridade de certificação A autoridade certificadora do certificado de folha (o primeiro certificado da cadeia de certificados) no keystore do processador de mensagens não corresponde a nenhuma das autoridades de certificação aceitas pelo servidor de back-end. Usuários de nuvem pública e privada de borda

Etapas comuns do diagnóstico

  1. Ative o rastreamento na interface do Edge, faça a chamada de API e reproduza o problema.
  2. Nos resultados do trace da interface, navegue por cada fase e determine onde os ocorreu um erro. O erro teria ocorrido no fluxo de solicitação de destino.
  3. Examine o fluxo que mostra o erro. Você deve observar o erro conforme mostrado no trace de exemplo abaixo:

    alt_text

  4. Como mostra a captura de tela acima, error.cause é "Alerta fatal recebido: bad_certificate".
  5. Se você for usuário da nuvem privada, siga as instruções abaixo:
    1. Você pode obter o ID da mensagem para a solicitação de API com falha determinando o valor do cabeçalho de erro "X-Apigee.Message-ID" na fase indicada por AX no rastro.
    2. Procure esse ID de mensagem no registro do processador de mensagens /opt/apigee/var/log/edge-message-processor/system.log e determinar Se você puder encontrar mais informações sobre o erro:
      2017-10-23 05:28:57,813 org:org-name env:env-name api:apiproxy-name
      rev:revision-number messageid:message_id NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context.handshakeFailed() :
      SSLClientChannel[C:IP address:port # Remote host:IP address:port #]@65461 useCount=1
      bytesRead=0 bytesWritten=0 age=529ms lastIO=529ms handshake failed, message: Received fatal alert: bad_certificate
      2017-10-23 05:28:57,813 org:org-name env:env-name api:apiproxy-name
      rev:revision-number messageid:message_id NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context.handshakeFailed() : SSLInfo:
      KeyStore:java.security.KeyStore@52de60d9 KeyAlias:KeyAlias TrustStore:java.security.KeyStore@6ec45759
      2017-10-23 05:28:57,814 org:org-name env:env-name api:apiproxy-name
      rev:revision-number messageid:message_id NIOThread@0 ERROR ADAPTORS.HTTP.FLOW - RequestWriteListener.onException() :
      RequestWriteListener.onException(HTTPRequest@6071a73d)
      javax.net.ssl.SSLException: Received fatal alert: bad_certificate
      at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[na:1.8.0_101]
      at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666) ~[na:1.8.0_101]
      at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634) ~[na:1.8.0_101]
      at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1800) ~[na:1.8.0_101]
      at com.apigee.nio.NIOSelector$SelectedIterator.findNext(NIOSelector.java:496) [nio-1.0.0.jar:na]
      at com.apigee.nio.util.NonNullIterator.computeNext(NonNullIterator.java:21) [nio-1.0.0.jar:na]
      at com.apigee.nio.util.AbstractIterator.hasNext(AbstractIterator.java:47) [nio-1.0.0.jar:na]
      at com.apigee.nio.NIOSelector$2.findNext(NIOSelector.java:312) [nio-1.0.0.jar:na]
      at com.apigee.nio.NIOSelector$2.findNext(NIOSelector.java:302) [nio-1.0.0.jar:na]
      at com.apigee.nio.util.NonNullIterator.computeNext(NonNullIterator.java:21) [nio-1.0.0.jar:na]
      at com.apigee.nio.util.AbstractIterator.hasNext(AbstractIterator.java:47) [nio-1.0.0.jar:na]
      at com.apigee.nio.handlers.NIOThread.run(NIOThread.java:59) [nio-1.0.0.jar:na]
      

      O registro do processador de mensagens tinha um stack trace para o erro Received fatal alert: bad_certificate, mas não tenha outras informações que indiquem a causa desse problema.

  6. Para investigar o problema mais a fundo, você precisará capturar pacotes TCP/IP usando tcpdump.
    1. Se você for usuário da nuvem privada, poderá capturar a pacotes TCP/IP no servidor de back-end ou no processador de mensagens. De preferência, capture-os no servidor de back-end à medida que os pacotes são descriptografados no servidor de back-end.
    2. Se você for um usuário da nuvem pública, capture o TCP/IP pacotes no servidor de back-end.
    3. Depois de decidir onde quer capturar os pacotes TCP/IP, use o método abaixo de tcpdump para capturar pacotes TCP/IP.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      Se você estiver coletando os pacotes TCP/IP no processador de mensagens, endereço IP público do servidor de back-end no comando tcpdump.

      Se houver vários endereços IP para o servidor de back-end/processador de mensagens, use outro comando tcpdump. Consulte tcpdump para mais informações sobre essa ferramenta e outras variantes desse comando.

  7. Analise os pacotes TCP/IP usando a ferramenta Wireshark ou uma ferramenta semelhante que você conheça.

Esta é a análise de amostras de dados de pacotes TCP/IP usando a ferramenta Wireshark:

alt_text

  1. A mensagem 4 no tcpdump acima mostra que o processador de mensagens (fonte) enviou uma mensagem "Client Hello" ao servidor de back-end (destino).
  2. A mensagem 5 mostra que o servidor de back-end confirma a mensagem Client Hello do processador de mensagens.
  3. O servidor de back-end envia a mensagem "Server Hello" junto com o certificado, e solicita que o cliente envie seu certificado na Mensagem no 7.
  4. O processador de mensagens conclui a verificação do certificado e confirma a mensagem ServerHello do servidor de back-end na Mensagem 8.
  5. O processador de mensagens envia o certificado para o servidor de back-end na Mensagem no 9.
  6. O servidor de back-end confirma o recebimento da mensagem Certificado na mensagem 11.
  7. No entanto, ele envia imediatamente um Alerta fatal: certificado inválido para o Processador de mensagens (mensagem no 12). Isso indica que o certificado enviado pelo o processador de mensagens estava com problemas e, por isso, a verificação de certificado falhou no servidor de back-end. Consequentemente, o handshake de SSL falhou e a conexão será fechado.


    alt_text

  8. Agora, vejamos a mensagem no 9 para verificar o conteúdo do certificado enviado pelo processador de mensagens:


    alt_text

  9. Como você pode notar, o servidor de back-end não recebeu nenhum certificado do cliente (Certificate Length: 0). Portanto, o servidor de back-end envia o alerta fatal: certificado inválido.
  10. Normalmente, isso acontece quando o cliente, ou seja, o processador de mensagens (um processo baseado em Java):
    1. não tiver nenhum certificado do cliente no keystore; ou
    2. Não é possível enviar um certificado do cliente. Isso poderá acontecer se ele não conseguir encontrar um certificado emitido por uma das autoridades de certificação aceitáveis do servidor de back-end. Ou seja, se a autoridade certificadora do certificado de folha do cliente (ou seja, o primeiro certificado da cadeia) não corresponde a nenhuma das credenciais do servidor de back-end autoridades certificadoras aceitáveis, o processador de mensagens não enviará o certificado.

Vamos analisar cada uma dessas causas separadamente da seguinte forma.

Causa: nenhum certificado do cliente

Diagnóstico

Se não houver um certificado no Keystore especificado na seção Informações do SSL do endpoint de destino ou do servidor de destino usado no endpoint de destino, essa é a causa do erro.

Siga as etapas abaixo para determinar se essa é a causa:

  1. Determine o keystore que está sendo usado no endpoint de destino ou no servidor de destino para o proxy de API específico. Basta seguir as etapas abaixo:
    1. Consiga o nome de referência do Keystore no elemento Keystore. na seção SSLInfo no endpoint ou no servidor de destino.

      Vejamos um exemplo de seção SSLInfo em uma configuração de endpoint de destino:

      <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>ref://myKeystoreRef</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>ref://myTrustStoreRef</TrustStore>
      </SSLInfo>
    2. No exemplo acima, o nome de referência do Keystore é "myKeystoreRef".
    3. Acesse a interface do Edge e selecione Proxies de API -> Configurações do ambiente.

      Selecione a guia Referências e procure o nome da referência do keystore. Anote o nome na coluna Referência da referência específica do keystore. Esse será o nome do keystore.


      alt_text

    4. No exemplo acima, myKeystoreRef tem a referência para "myKeystore". Portanto, o nome do Keystore é myKeystore.
  2. Verifique se este keystore contém o certificado usando a interface do usuário do Edge ou o Listar certificados para a API Keystore.
  3. Se o keystore contiver certificados, vá para Causa: falta de correspondência da autoridade certificadora.
  4. Se o keystore não tiver nenhum certificado, esse é o motivo o certificado do cliente não for enviado pelo processador de mensagens.

Resolução

  1. Certifique-se de que a cadeia completa e correta de certificados do cliente seja carregada no keystore específico no processador de mensagens.

Causa: incompatibilidade da autoridade de certificação

Geralmente, quando o Servidor solicita que o Cliente envie seu Certificado, ele indica o conjunto de emissores ou autoridades certificadoras aceitos. Se o emissor/autoridade de certificação do certificado de folha (ou seja, o primeiro o certificado na cadeia de certificados) no Keystore do processador de mensagens não não correspondem a nenhuma das Autoridades Certificadoras aceitas pelo servidor de back-end, o processador de mensagens (que é um processo baseado em Java) não enviar o certificado ao servidor de back-end.

Use as etapas abaixo para confirmar se esse é o caso:

  1. Listar certificados para a API Keystore.
  2. Consulte os detalhes de cada certificado obtido na Etapa 1 acima usando o Receba o certificado da API Keystore.
  3. Anote o emissor do certificado de folha (ou seja, o primeiro certificado da cadeia de certificados) armazenado no Keystore.

    Exemplo de certificado de folha

    {
      "certInfo" : [ {
        "basicConstraints" : "CA:FALSE",
        "expiryDate" : 1578889324000,
        "isValid" : "Yes",
        "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com",
        "publicKey" : "RSA Public Key, 2048 bits",
        "serialNumber" : "65:00:00:00:d2:3e:12:d8:56:fa:e2:a9:69:00:06:00:00:00:d2",
        "sigAlgName" : "SHA256withRSA",
        "subject" : "CN=nonprod-api.mycompany.com, OU=ITS, O=MyCompany, L=MELBOURNE, ST=VIC, C=AU",
        "subjectAlternativeNames" : [ ],
        "validFrom" : 1484281324000,
        "version" : 3
      } ],
      "certName" : "nonprod-api.mycompany.com.key.pem-cert"
    }
    

    No exemplo acima, o emissor/autoridade de certificação é "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"

  4. Determine a lista aceita de emissores ou autoridades certificadoras do servidor de back-end usando uma das seguintes técnicas:

    Técnica 1: use o comando openssl abaixo:

    openssl s_client -host <backend server host name> -port <Backend port#> -cert <Client Certificate> -key <Client Private Key>
    

    Consulte a seção Nomes de CA aceitáveis para certificados de cliente. na saída deste comando, conforme mostrado abaixo:

    Acceptable client certificate CA names
    /C=AU/ST=VIC/L=MELBOURNE/O=MyCompany/OU=ITS/CN=nonprod-api.mycompany.com
    /C=AU/ST=VIC/L=MELBOURNE/O=MyCompany/OU=ITS/CN=nonprod-api.mycompany.com
    

    Técnica 2: verificar o pacote Certificate Request em Pacotes TCP/IP, em que o servidor de back-end solicita que o cliente envie o certificado:

    Nos pacotes TCP/IP de amostra mostrados acima, Certificate Request o pacote é a mensagem 7. Consulte a seção "Nomes distintos" que contém as autoridades de certificação aceitáveis do servidor de back-end.

    alt_text

  5. Verifique se a autoridade certificadora obtida na etapa 3 corresponde à lista dos emissores ou autoridades de certificação aceitos pelo servidor de back-end obtidos na etapa 4. Em caso de incompatibilidade, o processador de mensagens não enviará o certificado do cliente ao servidor de back-end.

    No exemplo acima, é possível observar que o emissor do Certificado de Folha do Cliente no keystore do processador de mensagens não corresponde a nenhum do servidor de back-end Autoridades certificadoras aceitas. Portanto, o processador de mensagens enviar o certificado do cliente para o servidor de back-end. Isso faz com que o handshake de SSL falhe e o servidor de back-end envia "Fatal alert: bad_certificate" mensagem.

Resolução

  1. Verifique se o certificado com o emissor/autoridade de certificação correspondente o emissor/autoridade de certificação do certificado de folha do cliente (primeiro certificado na cadeia) é armazenado no Truststore do servidor de back-end.
  2. No exemplo descrito neste Manual, o certificado com o emissor "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" foi adicionado ao Truststore do servidor de back-end para resolver o problema.

Se o problema persistir, consulte Precisa de informações de diagnóstico.

É necessário coletar informações de diagnóstico

Se o problema persistir mesmo depois de seguir as instruções acima, colete as seguintes informações de diagnóstico. Entrar em contato e compartilhar com Suporte do Apigee Edge:

  1. Se você é usuário da nuvem pública, forneça as seguintes informações:
    1. Nome da organização
    2. Nome do ambiente
    3. Nome do proxy da API
    4. Complete o comando curl para reproduzir o erro
    5. Arquivo de rastreamento mostrando o erro
    6. Pacotes TCP/IP capturados no servidor de back-end
  2. Se você é usuário da nuvem privada, forneça as seguintes informações:
    1. Mensagem de erro completa observada
    2. Pacote de proxy de API
    3. Arquivo de rastreamento mostrando o erro
    4. Registros do processador de mensagens /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. Pacotes TCP/IP capturados no servidor de back-end ou no processador de mensagens.
    6. Saída de Get cert for keystore API.
  3. Detalhes sobre quais seções deste manual você usou e quais outras insights que nos ajudarão a acelerar a resolução desse problema.