SSL-Handshake schlägt fehl – Fehlerhaftes Clientzertifikat

<ph type="x-smartling-placeholder"></ph> Sie sehen die Dokumentation zu Apigee Edge.
Gehen Sie zur Apigee X-Dokumentation.
Weitere Informationen

Symptom

Die Clientanwendung empfängt den HTTP-Statuscode 503 mit die Nachricht "Service Unavailable" als Antwort auf eine API-Anfrage. Im UI-Trace sehen Sie, dass die Fehlerquelle error.cause ist Received fatal alert: bad_certificate im Zielanfragefluss für die fehlgeschlagene API-Anfrage.

Wenn Sie Zugriff auf Message Processor-Logs haben, sehen Sie die Fehlermeldung Received fatal alert: bad_certificate für die fehlgeschlagene API-Anfrage. Dieser Fehler wird während des SSL-Handshakes beobachtet. Prozess zwischen dem Message Processor und dem Backend-Server in einer Zwei-Wege-TLS-Einrichtung.

Fehlermeldung

Die Clientanwendung ruft den folgenden Antwortcode ab:

HTTP/1.1 503 Service Unavailable

Außerdem wird möglicherweise die folgende Fehlermeldung angezeigt:

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

Nutzern der privaten Cloud wird für die spezifische API-Anfrage der folgende Fehler angezeigt in den Message Processor-Logs /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

Mögliche Ursachen

Das kann folgende Ursachen haben:

Ursache Beschreibung Geltende Anleitung zur Fehlerbehebung
Kein Clientzertifikat Der im Zielendpunkt des Zielservers verwendete Schlüsselspeicher hat kein Clientzertifikat. Private und öffentliche Edge-Cloud-Nutzer
Zertifizierungsstelle stimmt nicht überein Die Zertifizierungsstelle des untergeordneten Zertifikats (das erste Zertifikat in der Zertifikatskette) im Schlüsselspeicher des Message Processor stimmt mit keiner der Zertifizierungsstellen überein, die vom Back-End-Server akzeptiert wurden. Private und öffentliche Edge-Cloud-Nutzer

Allgemeine Diagnoseschritte

  1. Aktivieren Sie Trace in der Edge-Benutzeroberfläche, führen Sie den API-Aufruf aus und reproduzieren Sie das Problem.
  2. Navigieren Sie in den Trace-Ergebnissen der Benutzeroberfläche durch die einzelnen Phasen und bestimmen Sie, wo die ist ein Fehler aufgetreten. Der Fehler wäre dann im Zielanfragefluss aufgetreten.
  3. Sehen Sie sich den Ablauf an, in dem der Fehler angezeigt wird. Sie sollten den Fehler wie hier gezeigt beobachten. im Beispiel-Trace unten:

    alt_text

  4. Wie Sie im Screenshot oben sehen, ist error.cause „Received schwerer Benachrichtigung: bad_certificate“
  5. Wenn Sie ein Private Cloud-Nutzer sind, gehen Sie so vor: <ph type="x-smartling-placeholder">
      </ph>
    1. Sie können die Nachrichten-ID für die fehlgeschlagene API-Anfrage abrufen, indem Sie die Wert des Fehlerheaders „X-Apigee.Message-ID“ in der Phase, die im Trace durch AX angegeben ist.
    2. Suchen Sie im Message Processor-Protokoll nach dieser Nachrichten-ID /opt/apigee/var/log/edge-message-processor/system.log und bestimmen Sie wenn Sie weitere Informationen zum Fehler finden:
      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]
      

      Das Message Processor-Log enthielt einen Stacktrace für den Fehler Received fatal alert: bad_certificate, aber nicht finden Sie weitere Informationen, die die Ursache des Problems angeben.

  6. Um dieses Problem weiter zu untersuchen, müssen Sie TCP/IP-Pakete mit tcpdump.
    1. Wenn Sie ein Private Cloud-Nutzer sind, können Sie den TCP/IP-Pakete auf dem Backend-Server oder Message Processor. Vorzugsweise sollten Sie sie auf dem Backend-Server erfassen, während die Pakete auf auf dem Back-End-Server.
    2. Wenn Sie ein Öffentlicher Cloud-Nutzer sind, erfassen Sie die TCP/IP-Adressen auf dem Back-End-Server.
    3. Sobald Sie entschieden haben, wo Sie TCP/IP-Pakete erfassen möchten, verwenden Sie die Methode unter tcpdump zum Erfassen von TCP/IP-Paketen.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      Wenn Sie die TCP/IP-Pakete auf den Message Processor übertragen, verwenden Sie die Methode öffentliche IP-Adresse des Back-End-Servers im Befehl tcpdump.

      Wenn es mehrere IP-Adressen für den Backend-Server/Message Processor gibt, müssen Sie einen anderen „tcpdump“-Befehl verwenden. Weitere Informationen finden Sie unter tcpdump finden Sie weitere Informationen zu diesem Tool und anderen Varianten dieses Befehls.

  7. Analysieren Sie die TCP/IP-Pakete mit dem Wireshark-Tool oder einem ähnlichen Tool, mit dem Sie vertraut sind.

Hier sehen Sie die Analyse von TCP/IP-Beispieldaten mit dem Wireshark-Tool:

alt_text

  1. Nachricht Nr. 4 in der obigen tcpdump-Datei zeigt, dass der Message Processor (Quelle) hat eine "Client Hello"-Nachricht an den Back-End-Server (Ziel) gesendet.
  2. Nachricht 5 zeigt, dass der Backend-Server die Client Hello-Nachricht bestätigt vom Message Processor.
  3. Der Backend-Server sendet die Nachricht "Server Hello" Nachricht zusammen mit dem zugehörigen Zertifikat, und fordert dann den Client auf, sein Zertifikat in Nachricht Nr. 7 zu senden.
  4. Der Message Processor schließt die Verifizierung des Zertifikats ab und bestätigt die ServerHello-Nachricht des Back-End-Servers in Nachricht Nr. 8.
  5. Der Message Processor sendet sein Zertifikat in Nachricht Nr. 9 an den Backend-Server.
  6. Der Backend-Server bestätigt den Empfang der Zertifikat in Nachricht Nr. 11.
  7. Allerdings wird sofort die Meldung Schwerwiegende Benachrichtigung: Ungültiges Zertifikat an den Message Processor (Nachricht 12). Dies gibt an, dass das von dass der Message Processor fehlerhaft war, sodass die Zertifikatsüberprüfung am auf dem Back-End-Server. Daher ist der SSL-Handshake fehlgeschlagen und die Verbindung wird geschlossen.


    alt_text

  8. Schauen wir uns nun die Nachricht Nr. 9 an, um den Inhalt des Zertifikats zu überprüfen, das vom Message Processor gesendet wurde:


    alt_text

  9. Wie Sie sehen, hat der Backend-Server kein Zertifikat vom Client erhalten. (Zertifikatlänge: 0) Daher sendet der Backend-Server die schwerwiegende Benachrichtigung: Ungültiges Zertifikat.
  10. Normalerweise geschieht dies, wenn der Client, also Message Processor (ein Java-basierter Prozess): <ph type="x-smartling-placeholder">
      </ph>
    1. kein Clientzertifikat im Schlüsselspeicher hat oder
    2. Es kann kein Client-Zertifikat gesendet werden. Das kann passieren, wenn ein Zertifikat, das von einer der zulässigen Zertifizierungsstellen des Backend-Servers ausgestellt wurde. Wenn also die Zertifizierungsstelle (d. h. das erste Zertifikat in der Kette) stimmt mit keinem Zertifikat des Backend-Servers überein. zugelassenen Zertifizierungsstellen sendet, sendet der Message Processor das Zertifikat nicht.

Im Folgenden werden diese Ursachen näher erläutert.

Ursache: Kein Clientzertifikat

Diagnose

Wenn im Bereich mit den SSL-Informationen kein Zertifikat im Schlüsselspeicher vorhanden ist des Zielendpunkts oder des Zielservers aus, der im Zielendpunkt verwendet wird, ist das die Ursache für diesen Fehler.

Führen Sie die folgenden Schritte aus, um festzustellen, ob das die Ursache ist:

  1. Ermitteln Sie den Schlüsselspeicher, der am Zielendpunkt oder auf dem Zielserver verwendet wird für den jeweiligen API-Proxy. Gehen Sie dazu so vor: <ph type="x-smartling-placeholder">
      </ph>
    1. Schlüsselspeicher-Referenznamen aus dem Keystore-Element abrufen im Abschnitt SSLInfo des Zielendpunkts oder Zielservers.

      Sehen wir uns einen Beispielabschnitt „SSLInfo“ in einer Zielendpunktkonfiguration an:

      <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>ref://myKeystoreRef</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>ref://myTrustStoreRef</TrustStore>
      </SSLInfo>
    2. Im obigen Beispiel lautet der Name der Schlüsselspeicher-Referenz "myKeystoreRef".
    3. Gehen Sie zur Edge-Benutzeroberfläche und wählen Sie API Proxies -> Umgebungskonfigurationen.

      Wähle den Tab Referenzen aus und suche nach dem Namen des Schlüsselspeicher-Referenznamens. Notieren Sie sich den Namen in der Spalte Reference (Referenz) für die spezifische Schlüsselspeicher-Referenz. Dies ist der Name Ihres Schlüsselspeichers.


      alt_text

    4. Im Beispiel oben sehen Sie, dass myKeystoreRef den Verweis zu „myKeystore“. Daher lautet der Schlüsselspeichername „myKeystore“.
  2. Prüfen Sie, ob dieser Schlüsselspeicher das Zertifikat enthält, entweder mithilfe der Edge-Benutzeroberfläche oder der Zertifikate für die Keystore API auflisten
  3. Wenn der Schlüsselspeicher Zertifikate enthält, gehe zu Ursache: Zertifizierungsstelle stimmt nicht überein.
  4. Wenn der Schlüsselspeicher kein Zertifikat enthält, ist das der Grund, Das Client-Zertifikat wird nicht vom Message Processor gesendet.

Auflösung

  1. Stellen Sie sicher, dass die korrekte und vollständige Client-Zertifikatskette in den jeweiligen Schlüsselspeicher im Message Processor hochgeladen wird.

Ursache: Zertifizierungsstelle stimmt nicht überein

Wenn der Server den Client auffordert, sein Zertifikat zu senden, gibt die akzeptierten Aussteller oder Zertifizierungsstellen an. Wenn der Aussteller bzw. die Zertifizierungsstelle des untergeordneten Zertifikats (d. h. der erste Zertifikat in der Zertifikatskette) im Schlüsselspeicher des Message Processor mit keiner der vom Backend-Server akzeptierten Zertifizierungsstellen übereinstimmen, erstellt Message Processor, ein Java-basierter Prozess, das Zertifikat nicht an den Backend-Server senden.

Ob das der Fall ist, kannst du mit den folgenden Schritten überprüfen:

  1. Zertifikate für die Keystore API auflisten
  2. Rufen Sie die Details zu jedem Zertifikat ab, das Sie in Schritt 1 oben erhalten haben, mithilfe der Zertifikat für Keystore API abrufen
  3. Notieren Sie sich den Aussteller des untergeordneten Zertifikats (das erste in der Zertifikatskette), das im Schlüsselspeicher gespeichert ist.

    Musterblattzertifikat

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

    Im obigen Beispiel ist der Aussteller bzw. die Zertifizierungsstelle "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"

  4. Bestimmen Sie die vom Back-End-Server akzeptierte Liste der Aussteller oder Zertifizierungsstellen mithilfe einer der folgenden Techniken:

    Verfahren 1: Verwenden Sie den folgenden Befehl „openssl“:

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

    Weitere Informationen finden Sie im Abschnitt Zulässige CA-Namen für Clientzertifikate. in die Ausgabe dieses Befehls ein, wie unten gezeigt:

    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
    

    Verfahren 2: Prüfen Sie das Certificate Request-Paket im TCP/IP-Pakete, bei denen der Back-End-Server den Client auffordert, sein Zertifikat zu senden:

    In den oben gezeigten TCP/IP-Beispielpaketen Certificate Request Paket ist Nachricht Nr. 7. Weitere Informationen finden Sie im Abschnitt die die zulässigen Zertifizierungsstellen des Back-End-Servers enthält.

    alt_text

  5. Prüfen Sie, ob die in Schritt 3 erhaltene Zertifizierungsstelle mit der Liste übereinstimmt der akzeptierten Aussteller oder Zertifizierungsstellen des Backend-Servers, die in Schritt 4 abgerufen wurden. Bei einer Abweichung sendet der Message Processor das Clientzertifikat nicht zum Back-End-Server.

    Im Beispiel oben sehen Sie, dass der Aussteller des Blattzertifikats im Schlüsselspeicher des Message Processor stimmt mit keinem der Schlüsselspeicher des Back-End-Servers überein. Akzeptierte Zertifizierungsstellen Daher stellt der Message Processor Das Clientzertifikat wird an den Backend-Server gesendet. Dies führt dazu, dass der SSL-Handshake fehlschlägt und der Backend-Server "Fatal alert: bad_certificate" sendet angezeigt.

Auflösung

  1. Achten Sie darauf, dass das Zertifikat mit dem Aussteller/der Zertifizierungsstelle übereinstimmt Aussteller/Zertifizierungsstelle des Blattzertifikats des Clients (erstes Zertifikat) in der Kette) im Truststore des Back-End-Servers gespeichert.
  2. Im in diesem Playbook beschriebenen Beispiel ist das Zertifikat mit dem Aussteller "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" wurde dem Truststore des Backend-Servers hinzugefügt, um das Problem zu beheben.

Wenn das Problem weiterhin besteht, gehen Sie zu Diagnoseinformationen müssen erfasst werden.

Erfassen von Diagnoseinformationen erforderlich

Wenn das Problem trotz Befolgen der obigen Anweisungen weiterhin besteht, benötigen wir die folgenden Diagnosedaten. Kontaktieren und teilen mit Apigee Edge-Unterstützung:

  1. Wenn Sie ein Nutzer der öffentlichen Cloud sind, geben Sie die folgenden Informationen an: <ph type="x-smartling-placeholder">
      </ph>
    1. Name der Organisation
    2. Name der Umgebung
    3. API-Proxy-Name
    4. Führen Sie den curl-Befehl aus, um den Fehler zu reproduzieren.
    5. Ablaufverfolgungsdatei mit Fehler
    6. Auf dem Backend-Server erfasste TCP/IP-Pakete
  2. Wenn Sie ein Nutzer der Private Cloud sind, geben Sie die folgenden Informationen an: <ph type="x-smartling-placeholder">
      </ph>
    1. Vollständige Fehlermeldung beobachtet
    2. API-Proxy-Bundle
    3. Ablaufverfolgungsdatei mit Fehler
    4. Message Processor-Logs /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. Auf dem Backend-Server oder Message Processor erfasste TCP/IP-Pakete.
    6. Ausgabe von Get cert for keystore API
  3. Details dazu, welche Abschnitte in diesem Playbook du ausprobiert hast und Erkenntnisse, die uns helfen, eine schnelle Lösung für dieses Problem zu finden.