Échecs de handshake SSL – Certificat client incorrect

<ph type="x-smartling-placeholder"></ph> Vous consultez la documentation Apigee Edge.
Accédez à la page Documentation sur Apigee X.
En savoir plus

Symptôme

L'application cliente reçoit un code d'état HTTP 503 avec le message Service Unavailable (Service non disponible) en réponse à une requête API Dans la trace de l'interface utilisateur, vous observerez que la valeur error.cause est Received fatal alert: bad_certificate dans le flux de requêtes cible pour la requête API en échec.

Si vous avez accès aux journaux du processeur de messages, vous remarquerez le message d'erreur Received fatal alert: bad_certificate pour la requête API en échec. Cette erreur est observée lors du handshake SSL. entre le processeur de messages et le serveur backend dans une configuration TLS bidirectionnelle.

Message d'erreur

L'application cliente reçoit le code de réponse suivant:

HTTP/1.1 503 Service Unavailable

Le message d'erreur suivant peut également s'afficher:

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

Les utilisateurs de Private Cloud verront l'erreur suivante pour la requête API spécifique dans les journaux du processeur de messages /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

Causes possibles :

Les causes possibles de ce problème sont les suivantes:

Cause Description Instructions de dépannage applicables à
Aucun certificat client Le keystore utilisé dans le point de terminaison cible du serveur cible ne possède aucun certificat client. Utilisateurs de cloud privé et public Edge
Incohérence de l'autorité de certification L'autorité de certification du certificat d'entité finale (le premier certificat de la chaîne de certificats) dans le keystore du processeur de messages ne correspond à aucune des autorités de certification acceptées par le serveur backend. Utilisateurs de cloud privé et public Edge

Étapes de diagnostic courantes

  1. Activez Trace dans l'interface utilisateur Edge, effectuez l'appel d'API et reproduisez le problème.
  2. Dans les résultats de trace de l'interface utilisateur, parcourez chaque phase et déterminez où se trouve erreur s'est produite. L'erreur s'est produite dans le flux de demande cible.
  3. Examinez le flux qui affiche l'erreur. Vous devez observer l'erreur comme indiqué. dans l'exemple de trace ci-dessous:

    alt_text

  4. Comme vous pouvez le voir dans la capture d'écran ci-dessus, la valeur de error.cause est "Alerte fatale reçue: bad_certificate".
  5. Si vous êtes un utilisateur du Private Cloud, suivez les instructions ci-dessous: <ph type="x-smartling-placeholder">
      </ph>
    1. Pour obtenir l'ID du message de la requête API qui a échoué, déterminez le valeur de l'en-tête d'erreur "X-Apigee.Message-ID" dans la phase indiquée par AX dans la trace.
    2. Recherchez cet identifiant de message dans le journal du processeur de messages. /opt/apigee/var/log/edge-message-processor/system.log et déterminer si vous avez plus d'informations sur l'erreur:
      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]
      

      Le journal du processeur de messages contenait une trace de pile pour l'erreur Received fatal alert: bad_certificate, mais pas disposez d'informations supplémentaires indiquant la cause de ce problème.

  6. Pour examiner ce problème plus en détail, vous devez capturer des paquets TCP/IP à l'aide de tcpdump.
    1. Si vous êtes un utilisateur du Private Cloud, vous pouvez capturer le Paquets TCP/IP sur le serveur backend ou le processeur de messages. De préférence, capturez-les sur le serveur backend lorsque les paquets sont déchiffrés sur le serveur backend.
    2. Si vous êtes un utilisateur de cloud public, capturez le TCP/IP des paquets sur le serveur backend.
    3. Une fois que vous avez choisi où capturer les paquets TCP/IP, utilisez la méthode en dessous de tcpdump pour capturer les paquets TCP/IP.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      Si vous prenez les paquets TCP/IP sur le processeur de messages, utilisez le adresse IP publique du serveur backend dans la commande tcpdump.

      S'il existe plusieurs adresses IP pour le serveur backend/le processeur de messages, alors vous devez utiliser une autre commande tcpdump. Consultez tcpdump pour en savoir plus sur cet outil et sur les autres variantes de cette commande.

  7. Analysez les paquets TCP/IP à l'aide de l'outil Wireshark ou d'un outil similaire que vous connaissez bien.

Voici l'analyse d'exemples de données de paquets TCP/IP à l'aide de l'outil Wireshark:

alt_text

  1. Le message n°4 dans tcpdump ci-dessus montre que le processeur de messages (source) a envoyé un message "Client Hello" au serveur backend (destination).
  2. Le message 5 indique que le serveur backend accuse réception du message "Client Hello" du processeur de messages.
  3. Le serveur backend envoie le message "Server Hello" avec son certificat, puis demande au client d'envoyer son certificat dans le message n° 7.
  4. Le processeur de messages termine la vérification du certificat et accuse réception au message ServerHello du serveur backend dans le message n°8.
  5. Le processeur de messages envoie son certificat au serveur backend dans le message n° 9.
  6. Le serveur backend accuse réception de la réponse du Certificat dans le message n° 11.
  7. Cependant, il envoie immédiatement une Alerte fatale: certificat incorrect au Processeur de messages (message n° 12). Cela indique que le certificat envoyé par le processeur de messages était défectueux et la vérification du certificat a échoué sur le serveur backend. Par conséquent, le handshake SSL a échoué et la connexion sera fermé.


    alt_text

  8. Examinons maintenant le message n°9 pour vérifier le contenu du certificat envoyé par le processeur de messages:


    alt_text

  9. Comme vous pouvez le constater, le serveur backend n'a reçu aucun certificat du client. (Longueur du certificat: 0). Le serveur backend envoie donc l'alerte fatale: certificat incorrect.
  10. Cela se produit généralement lorsque le client, c'est-à-dire le processeur de messages (un processus Java): <ph type="x-smartling-placeholder">
      </ph>
    1. ne possède pas de certificat client dans son keystore ;
    2. Impossible d'envoyer un certificat client. Cela peut se produire s'il ne trouve pas Certificat émis par l'une des autorités de certification agréées par le serveur backend. Cela signifie que si l'autorité de certification du certificat Feuille du client (le premier certificat de la chaîne) ne correspond à aucune adresse e-mail du serveur des autorités de certification acceptables, alors le Prestataire de services de messagerie n'enverra pas le certificat.

Examinons chacune de ces causes séparément.

Cause: absence de certificat client

Diagnostic

Si le keystore ne contient aucun certificat dans la section Informations SSL du point de terminaison cible ou du serveur cible utilisé dans le point de terminaison cible, c'est la cause de cette erreur.

Suivez les étapes ci-dessous pour déterminer si cela est la cause du problème:

  1. Déterminer le keystore utilisé sur le point de terminaison cible ou le serveur cible pour le proxy d'API spécifique en procédant comme suit: <ph type="x-smartling-placeholder">
      </ph>
    1. Récupérez le nom de référence du keystore à partir de l'élément Keystore. dans la section SSLInfo du point de terminaison cible ou du serveur cible.

      Examinons un exemple de section SSLInfo dans une configuration de point de terminaison cible:

      <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>ref://myKeystoreRef</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>ref://myTrustStoreRef</TrustStore>
      </SSLInfo>
    2. Dans l'exemple ci-dessus, le nom de référence du keystore est myKeystoreRef.
    3. Accédez à l'interface utilisateur Edge et sélectionnez API Proxies -> Configurations de l'environnement.

      Sélectionnez l'onglet Références et recherchez le nom de la référence Keystore. Notez le nom dans la colonne Référence de la référence Keystore spécifique. Il s'agira du nom de votre keystore.


      alt_text

    4. Dans l'exemple ci-dessus, vous remarquerez que myKeystoreRef a la référence par "myKeystore". Par conséquent, le nom du keystore est myKeystore.
  2. Vérifiez si ce keystore contient le certificat à l'aide de l'interface utilisateur Edge ou de la Répertoriez les certificats pour l'API Keystore.
  3. Si le keystore contient un ou plusieurs certificats, passez à Cause: non-concordance de l'autorité de certification.
  4. Si le keystore ne contient aucun certificat, c'est pour cette raison le certificat client n’est pas envoyé par le processeur de messages.

Solution

  1. Assurez-vous que la chaîne de certificats client appropriée et complète est importée dans le keystore spécifique du processeur de messages.

Cause: non-concordance de l'autorité de certification

Généralement, lorsque le serveur demande au client d'envoyer son certificat, il indique l'ensemble des émetteurs ou des autorités de certification acceptés. Si l'émetteur/l'autorité de certification du certificat d'entité finale (par exemple, le premier certificat de la chaîne de certificats) dans le keystore du processeur de messages ne fait ne correspondent à aucune des autorités de certification acceptées par le serveur backend, Ensuite, Message Processor (qui est un processus Java) n'envoie pas le certificat au serveur backend.

Pour vérifier si tel est le cas, procédez comme suit:

  1. Répertoriez les certificats pour l'API Keystore.
  2. Récupérez les détails de chaque certificat obtenu à l'étape 1 ci-dessus à l'aide du Obtenir un certificat pour l'API Keystore
  3. Notez l'émetteur du certificat d'entité finale (c'est-à-dire le premier certificat de la chaîne de certificats) stocké dans le keystore.

    Exemple de certificat Feuille

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

    Dans l'exemple ci-dessus, l'émetteur/l'autorité de certification est "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"

  4. Déterminez la liste des émetteurs ou des autorités de certification acceptés pour le serveur backend à l'aide de l'une des techniques suivantes:

    Technique n° 1: Utilisez la commande openssl ci-dessous:

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

    Consultez la section intitulée Noms d'autorités de certification de certificats client autorisés. dans le résultat de cette commande, comme indiqué ci-dessous:

    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
    

    Technique n° 2: Vérifier le paquet Certificate Request dans Paquets TCP/IP, où le serveur backend demande au client d'envoyer son certificat:

    Dans les exemples de paquets TCP/IP présentés ci-dessus, Certificate Request paquet est le message n° 7. Reportez-vous à la section "Noms distinctifs", qui contient les autorités de certification autorisées du serveur backend.

    alt_text

  5. Vérifiez si l'autorité de certification obtenue à l'étape 3 correspond à la liste des émetteurs acceptés ou des autorités de certification du serveur backend obtenus à l'étape 4. En cas de non-concordance, le processeur de messages n'enverra pas le certificat client vers le serveur backend.

    Dans l'exemple ci-dessus, vous pouvez remarquer que l'émetteur du certificat feuille du client dans le keystore du processeur de messages ne correspond à aucune des adresses Autorités de certification acceptées : Par conséquent, le processeur de messages ne envoyer le certificat client au serveur backend. Cela provoque l'échec du handshake SSL et le serveur backend envoie "Fatal alert: bad_certificate" .

Solution

  1. Vérifiez que le certificat auprès de l'émetteur ou de l'autorité de certification correspond l'émetteur/l'autorité de certification du certificat Feuille du client (premier certificat de la chaîne) est stockée dans le Truststore du serveur backend.
  2. Dans l'exemple décrit dans ce playbook, le certificat auprès de l'émetteur "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" a été ajouté au Truststore du serveur backend pour résoudre le problème.

Si le problème persiste, consultez Collecter des informations de diagnostic.

Vous devez collecter des informations de diagnostic

Si le problème persiste même après avoir suivi les instructions ci-dessus, veuillez rassembler les informations de diagnostic suivantes. Contactez-les et partagez-les avec Assistance Apigee Edge:

  1. Si vous êtes un utilisateur de cloud public, fournissez les informations suivantes: <ph type="x-smartling-placeholder">
      </ph>
    1. Nom de l'organisation
    2. Nom de l'environnement
    3. Nom du proxy d'API
    4. Exécutez la commande curl pour reproduire l'erreur
    5. Fichier de suivi affichant l'erreur
    6. Paquets TCP/IP capturés sur le serveur backend
  2. Si vous êtes un utilisateur de Private Cloud, fournissez les informations suivantes: <ph type="x-smartling-placeholder">
      </ph>
    1. Message d'erreur complet observé
    2. Groupe de proxys d'API
    3. Fichier de suivi affichant l'erreur
    4. Journaux du processeur de messages /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. Paquets TCP/IP capturés sur le serveur backend ou le processeur de messages.
    6. Résultat de la commande Get cert for keystore API (Obtenir un certificat pour l'API Keystore)
  3. Des informations sur les sections de ce playbook que vous avez essayées et les autres des informations qui nous aideront à résoudre rapidement ce problème.