Errores de protocolo de enlace SSL: certificado de cliente incorrecto

Estás viendo la documentación de Apigee Edge.
Ve a la Documentación de Apigee X.
información

Síntoma

La aplicación cliente recibe un código de estado HTTP de 503 con el mensaje "Service Unavailable" como respuesta a una solicitud de API. En el seguimiento de la IU, observarás que error.cause es Received fatal alert: bad_certificate en el flujo de solicitud de destino para la solicitud a la API con errores.

Si tienes acceso a los registros de Message Processor, verás el mensaje de error como Received fatal alert: bad_certificate. para la solicitud a la API con errores. Este error se observa durante el protocolo de enlace SSL entre el Message Processor y el servidor de backend en una configuración de TLS bidireccional.

Mensaje de error

La aplicación cliente obtiene el siguiente código de respuesta:

HTTP/1.1 503 Service Unavailable

Además, puedes observar el siguiente mensaje de error:

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

Los usuarios de la nube privada verán el siguiente error para la solicitud específica a la API En los registros de Message Processor /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 posibles

Las posibles causas de este problema son las siguientes:

Causa Descripción Instrucciones de solución de problemas aplicables a
Sin certificado de cliente El almacén de claves usado en el extremo de destino del servidor de destino no tiene ningún certificado de cliente. Usuarios perimetrales de nubes privadas y públicas
Discrepancia en la autoridad certificadora La autoridad certificadora del certificado de hoja (el primer certificado de la cadena de certificados) del almacén de claves del procesador de mensajes no coincide con ninguna de las autoridades certificadoras que acepta el servidor backend. Usuarios perimetrales de nubes privadas y públicas

Pasos comunes de diagnóstico

  1. Habilita el seguimiento en la IU de Edge, realiza la llamada a la API y reproduce el problema.
  2. En los resultados de seguimiento de la IU, navega por cada Fase y determina dónde se produjo un error. El error se habría producido en el flujo de solicitud de destino.
  3. Examina el Flow que muestra el error. Deberías observarlo como se muestra a continuación. en el seguimiento de ejemplo que aparece a continuación:

    alt_text

  4. Como puede ver en la captura de pantalla anterior, error.cause es “Se recibió una alerta irrecuperable: bad_certificate”.
  5. Si eres un usuario de la Nube privada, sigue estas instrucciones:
    1. Puedes obtener el ID del mensaje para la solicitud a la API con errores determinando el valor del encabezado de error "X-Apigee.Message-ID" en la Fase indicada por AX en el seguimiento.
    2. Buscar este ID de mensaje en el registro de Message Processor /opt/apigee/var/log/edge-message-processor/system.log y determinar Si encuentras más información sobre el error, sigue estos pasos:
      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]
      

      El registro de Message Processor tenía un seguimiento de pila del error Received fatal alert: bad_certificate, pero no si tienes más información que indique la causa del problema.

  6. Para investigar más a fondo este problema, deberás capturar paquetes TCP/IP con tcpdump.
    1. Si eres un usuario de la nube privada, puedes capturar el paquetes TCP/IP en el servidor de backend o Message Processor. Preferentemente, capturarlos en el servidor de backend a medida que los paquetes se desencriptan en el servidor de backend.
    2. Si eres un usuario de la nube pública, captura el TCP/IP. paquetes en el servidor de backend.
    3. Una vez que hayas decidido dónde te gustaría capturar los paquetes TCP/IP, usa el a continuación de tcpdump para capturar paquetes TCP/IP.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      Si tomas los paquetes TCP/IP del Message Processor, usa el la dirección IP pública del servidor de backend en el comando tcpdump.

      Si hay varias direcciones IP para el servidor de backend/Procesador de mensajes, entonces debes usar un comando tcpdump diferente. Consulta tcpdump para obtener más información sobre esta herramienta y otras variantes de este comando.

  7. Analice los paquetes TCP/IP con la herramienta Wireshark o una herramienta similar con la que esté familiarizado.

Este es el análisis de datos de muestra de paquetes TCP/IP con la herramienta Wireshark:

alt_text

  1. El mensaje n.o 4 del tcpdump anterior muestra que Message Processor (fuente) envió un mensaje "Client Hello" al servidor de backend (destino).
  2. El mensaje n.o 5 muestra que el servidor backend confirma el mensaje de bienvenida del cliente de Message Processor.
  3. El servidor de backend envía el mensaje “Server Hello” junto con su certificado, y luego solicita al cliente que envíe su certificado en el Mensaje n.o 7.
  4. El procesador de mensajes completa la verificación del certificado y confirma la recepción el mensaje ServerHello del servidor backend en el mensaje n.o 8.
  5. El procesador de mensajes envía su certificado al servidor de backend en el mensaje n.o 9.
  6. El servidor de backend confirma la recepción de la solicitud del procesador de mensajes Certificado en el mensaje n.o 11.
  7. Sin embargo, envía de inmediato una Alerta fatal: Certificado incorrecto al Message Processor (mensaje no 12). Esto indica que el certificado que envió el procesador de mensajes era erróneo y, por lo tanto, la verificación del certificado falló en el servidor de backend. Como resultado, el protocolo de enlace SSL falló y la conexión se cerrará.


    alt_text

  8. Ahora, veamos el Mensaje 9 para verificar el contenido del certificado que envió Message Processor:


    alt_text

  9. Como puedes notar, el servidor de backend no recibió ningún certificado del cliente (Longitud del certificado: 0). Por lo tanto, el servidor de backend envía la alerta Fatal: Bad Certificate.
  10. Generalmente, esto sucede cuando el cliente, es decir, Message Processor (un proceso basado en Java):
    1. No tiene ningún Certificado de cliente en su almacén de claves.
    2. No puede enviar un certificado de cliente. Esto puede suceder si no encuentra un certificado emitido por una de las autoridades de certificación aceptables del servidor backend. Es decir, si la autoridad certificadora del certificado de hoja del cliente (es decir, el primer certificado de la cadena) no coincide con ninguno de los autoridades certificadoras aceptables, el Procesador de mensajes no enviará el certificado.

Veamos cada una de estas causas por separado de la siguiente manera.

Causa: sin certificado de cliente

Diagnóstico

Si no existe ningún certificado en el almacén de claves especificado en la sección Información sobre SSL del extremo de destino o el servidor de destino utilizado en el extremo de destino, esa es la causa del error.

Sigue estos pasos para determinar si esta es la causa:

  1. Determina el almacén de claves que se utiliza en el extremo o servidor de destino para el proxy de API específico mediante los siguientes pasos:
    1. Obtén el nombre de referencia del almacén de claves desde el elemento Keystore. en la sección SSLInfo del extremo de destino o del servidor de destino.

      Veamos una sección SSLInfo de muestra en una configuración de extremo de destino:

      <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>ref://myKeystoreRef</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>ref://myTrustStoreRef</TrustStore>
      </SSLInfo>
    2. En el ejemplo anterior, el nombre de referencia del almacén de claves es "myKeystoreRef".
    3. Dirígete a la IU de Edge y selecciona API Proxies -> Configuraciones del entorno.

      Selecciona la pestaña Referencias y busca el nombre de referencia del almacén de claves. Anota el nombre en la columna Reference de la referencia específica del almacén de claves. Este será el nombre del almacén de claves.


      alt_text

    4. En el ejemplo anterior, puedes observar que myKeystoreRef tiene la referencia a “myKeystore”. Por lo tanto, el nombre del almacén de claves es myKeystore.
  2. Verifica si este almacén de claves contiene el certificado con la IU de Edge o Enumera certificados para la API del almacén de claves.
  3. Si el almacén de claves contiene certificados, dirígete a Causa: Discrepancia en la autoridad certificadora.
  4. Si el almacén de claves no contiene ningún certificado, entonces es por ese motivo. el procesador de mensajes no envía el certificado de cliente.

Solución

  1. Asegúrate de que se suba la cadena completa y correcta de certificados de cliente al almacén de claves específico en el procesador de mensajes.

Causa: Discrepancia en la autoridad certificadora

Generalmente, cuando el servidor solicita al cliente que envíe su certificado, indica el conjunto de entidades emisoras o autoridades certificadoras aceptadas. Si es la entidad emisora o la autoridad certificadora del certificado de entidad final (es decir, el primer certificado en la cadena de certificados) en el almacén de claves del procesador de mensajes no coinciden con ninguna de las autoridades certificadoras aceptadas por el servidor backend, Message Processor (que es un proceso basado en Java) enviar el certificado al servidor de backend.

Sigue estos pasos para confirmar si este es el caso:

  1. Enumera certificados para la API del almacén de claves.
  2. Obtenga los detalles de cada certificado obtenido en el paso 1 anterior utilizando el Obtén el certificado para la API del almacén de claves.
  3. Toma nota del emisor del certificado de hoja (es decir, el primer certificado de la cadena de certificados) almacenado en el almacén de claves.

    Ejemplo de certificado de la hoja

    {
      "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"
    }
    

    En el ejemplo anterior, la entidad emisora o la autoridad de certificación se "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"

  4. Determina la lista aceptada de emisores o autoridades de certificación del servidor de backend a través de una de las siguientes técnicas:

    Técnica n° 1: Usa el comando openssl que aparece a continuación:

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

    Consulte la sección "Nombres de AC de certificados de cliente aceptables". en el resultado de este comando, como se muestra a continuación:

    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 n° 2: Revisa el paquete Certificate Request Paquetes TCP/IP, en los que el servidor de backend solicita al cliente que envíe su certificado:

    En los paquetes de TCP/IP de muestra anteriores, Certificate Request paquete es el mensaje n.o 7. Consulte la sección "Nombres distinguidos", que contiene las autoridades certificadoras aceptables del servidor backend.

    alt_text

    .
  5. Verifica si la autoridad certificadora que se obtuvo en el paso 3 coincide con la lista. de las entidades emisoras o autoridades certificadoras aceptadas del servidor backend obtenidas en el paso 4. Si no hay coincidencia, el procesador de mensajes no enviará el certificado de cliente. al servidor de backend.

    En el ejemplo anterior, puedes observar que la entidad emisora del certificado de hoja del cliente en el almacén de claves de Message Processor no coincide con ninguna de las claves del Autoridades certificadoras aceptadas. Por lo tanto, Message Processor no enviar el certificado de cliente al servidor de backend. Esto hace que el protocolo de enlace SSL falle y el servidor de backend envía "Fatal alert: bad_certificate" mensaje.

Solución

  1. Asegúrate de que el certificado coincida con el de la entidad emisora o la autoridad certificadora el emisor o la autoridad certificadora del certificado de la hoja del cliente (primer certificado de la cadena) se almacena en el almacén de confianza del servidor backend.
  2. En el ejemplo descrito en esta Guía, el certificado con la entidad emisora "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" se agregó al almacén de confianza del servidor de backend para resolver el problema.

Si el problema persiste, consulta Se debe recopilar información de diagnóstico.

Se debe recopilar información de diagnóstico

Si el problema persiste, incluso después de seguir las instrucciones anteriores, recopila la siguiente información de diagnóstico. Comunicarse con estos contactos y compartirlos con Asistencia de Apigee Edge:

  1. Si eres usuario de la nube pública, proporciona la siguiente información:
    1. Nombre de la organización
    2. Nombre del entorno
    3. Nombre del proxy de la API
    4. Completar el comando curl para reproducir el error
    5. Archivo de seguimiento que muestra el error
    6. Paquetes TCP/IP capturados en el servidor de backend
  2. Si eres usuario de la nube privada, proporciona la siguiente información:
    1. Se observó un mensaje de error completo
    2. Paquete de proxy de API
    3. Archivo de seguimiento que muestra el error
    4. Registros del procesador de mensajes /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. Paquetes TCP/IP capturados en el servidor de backend o en Message Processor.
    6. Resultado de la API de Get cert for keystore.
  3. Detalles sobre las secciones de esta guía que probaste y cualquier otra estadísticas que nos ayudarán a resolver rápidamente este problema.