Errori di handshake SSL - Certificato client non valido

Stai visualizzando la documentazione di Apigee Edge.
Vai alla sezione Documentazione di Apigee X.
Informazioni

Sintomo

L'applicazione client riceve un codice di stato HTTP 503 con il messaggio "Servizio non disponibile" in risposta a una richiesta API. Nella traccia della UI, noterai che l'errore error.cause è Received fatal alert: bad_certificate nel flusso di richiesta target per la richiesta API non riuscita.

Se hai accesso ai log del processore di messaggi, il messaggio di errore sarà Received fatal alert: bad_certificate per la richiesta API non riuscita. Questo errore viene osservato durante l'handshake SSL tra il processore di messaggi e il server di backend in una configurazione TLS a due vie.

Messaggio di errore

L'applicazione client riceve il seguente codice di risposta:

HTTP/1.1 503 Service Unavailable

Potresti inoltre visualizzare il seguente messaggio di errore:

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

Gli utenti del cloud privato vedranno il seguente errore per la richiesta API specifica nei log del processore di messaggi /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

Possibili cause

Le possibili cause sono le seguenti:

Causa Descrizione Istruzioni per la risoluzione dei problemi applicabili per
Nessun certificato client L'archivio chiavi utilizzato nell'endpoint di destinazione del server di destinazione non ha certificati client. Utenti periferici di cloud privati e pubblici
Mancata corrispondenza dell'autorità di certificazione L'autorità di certificazione del certificato foglia (il primo certificato nella catena di certificati) nel Keystore del processore di messaggi non corrisponde a nessuna delle autorità di certificazione accettate dal server di backend. Utenti periferici di cloud privati e pubblici

Passaggi diagnostici comuni

  1. Abilita la traccia nella UI di Edge, effettua la chiamata API e riproduci il problema.
  2. Nei risultati della traccia UI, esplora ogni fase e determina dove si è verificato un errore. L'errore si è verificato nel flusso di richiesta target.
  3. Esamina il flusso che mostra l'errore; dovresti osservare l'errore come mostrato nell'esempio riportato di seguito:

    alt_text

  4. Come puoi vedere nello screenshot riportato sopra, il valore di error.cause è "Avviso irreversibile ricevuto: bad_certificate".
  5. Se sei un utente di Private Cloud, segui queste istruzioni:
      .
    1. Puoi ottenere l'ID messaggio per la richiesta API non riuscita determinando il valore dell'intestazione errore "X-Apigee.Message-ID" nella Fase indicata da AX nella traccia.
    2. Cerca questo ID messaggio nel log del processore di messaggi /opt/apigee/var/log/edge-message-processor/system.log e determina se puoi trovare ulteriori informazioni sull'errore:
      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]
      

      Il log del processore di messaggi conteneva un'analisi dello stack per l'errore Received fatal alert: bad_certificate, ma non non fornire ulteriori informazioni che indichino la causa del problema.

  6. Per indagare ulteriormente sul problema, dovrai acquisire pacchetti TCP/IP utilizzando tcpdump.
    1. Se sei un utente di Private Cloud, puoi acquisire di pacchetti TCP/IP sul server di backend o sul processore di messaggi. Preferibilmente, acquisiscili sul server di backend mentre i pacchetti vengono decriptati il server di backend.
    2. Se sei un utente del cloud pubblico, acquisisci il protocollo TCP/IP sul server di backend.
    3. Una volta deciso dove vuoi acquisire i pacchetti TCP/IP, utilizza la classe sotto tcpdump per acquisire pacchetti TCP/IP.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      Se stai accettando i pacchetti TCP/IP sul processore di messaggi, utilizza il metodo indirizzo IP pubblico del server di backend nel comando tcpdump.

      Se sono presenti più indirizzi IP per il server di backend o il processore di messaggi: devi usare un altro comando tcpdump. Consulta tcpdump per ulteriori informazioni su questo strumento e per altre varianti del comando.

  7. Analizza i pacchetti TCP/IP utilizzando lo strumento Wireshark o uno strumento simile che conosci.

Di seguito è riportata l'analisi dei dati di pacchetti TCP/IP di esempio utilizzando lo strumento Wireshark:

alt_text

  1. Il messaggio 4 nella sezione tcpdump sopra riportata mostra che il processore di messaggi (origine) ha inviato un messaggio "Client Hello" al server di backend (destinazione).
  2. Il messaggio 5 indica che il server di backend conferma il messaggio Client Hello del processore di messaggi.
  3. Il server di backend invia il messaggio "Server Hello" insieme al relativo certificato, e chiede al client di inviare il proprio certificato nel messaggio 7.
  4. Il processore di messaggi completa la verifica del certificato e conferma il messaggio ServerHello del server di backend nel messaggio 8.
  5. Il processore di messaggi invia il proprio certificato al server di backend nel messaggio 9.
  6. Il server di backend conferma di aver ricevuto il modulo certificato nel messaggio 11.
  7. Tuttavia, invia immediatamente un avviso irreversibile: certificato non valido al Processore di messaggi (messaggio n. 12). Ciò indica che il certificato inviato da il processore di messaggi era guasto e la verifica del certificato non è riuscita il server di backend. Di conseguenza, l'handshake SSL non è riuscito e la connessione verrà chiuso.


    alt_text

  8. Vediamo ora il messaggio 9 per verificare il contenuto del certificato inviato dal processore di messaggi:


    alt_text

  9. Come puoi notare, il server di backend non ha ricevuto alcun certificato dal client (Lunghezza certificato: 0). Di conseguenza, il server di backend invia l'avviso irreversibile: certificato non valido.
  10. In genere ciò si verifica quando il client, ovvero il processore di messaggi (un processo basato su Java):
    1. non ha certificati client nel proprio archivio chiavi; oppure
    2. Non è in grado di inviare un certificato client. Ciò può accadere se non riesce a trovare un certificato emesso da una delle autorità di certificazione accettabili del server di backend. Significato: se l'autorità di certificazione del certificato foglia del client (ovvero, il primo certificato della catena) non corrisponde a nessuno dei autorità di certificazione accettabili, il processore di messaggi non invierà il certificato.

Esaminiamo queste cause separatamente nel seguente modo.

Causa: nessun certificato client

Diagnosi

Se nell'archivio chiavi non è presente alcun certificato specificato nella sezione Informazioni SSL dell'endpoint di destinazione o del server di destinazione utilizzato nell'endpoint di destinazione, questa è la causa dell'errore.

Per determinare se la causa è questa, procedi nel seguente modo:

  1. Determinare l'archivio chiavi in uso nell'endpoint di destinazione o nel server di destinazione per il proxy API specifico seguendo questi passaggi:
    1. Recupera il nome di riferimento dell'archivio chiavi dall'elemento Keystore nella sezione SSLInfo nell'endpoint di destinazione o nel server di destinazione.

      Diamo un'occhiata ad una sezione SSLInfo di esempio nella configurazione di un endpoint di destinazione:

      <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>ref://myKeystoreRef</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>ref://myTrustStoreRef</TrustStore>
      </SSLInfo>
    2. Nell'esempio precedente, il nome di riferimento dell'archivio chiavi è "myKeystoreRef".
    3. Vai alla UI Edge e seleziona Proxy API -> Configurazioni dell'ambiente.

      Seleziona la scheda Riferimenti e cerca il nome di riferimento dell'archivio chiavi. Prendi nota del nome nella colonna Riferimento per il riferimento specifico dell'archivio chiavi. Questo sarà il nome del tuo archivio chiavi.


      alt_text

    4. Nell'esempio precedente, puoi notare che myKeystoreRef ha il riferimento in "myKeystore". Pertanto, il nome dell'archivio chiavi è myKeystore.
  2. Verifica se l'archivio chiavi contiene il certificato utilizzando l'interfaccia utente di Edge o Elenca i certificati per l'API keystore.
  3. Se l'archivio chiavi contiene certificati, passa a Causa: mancata corrispondenza con l'autorità di certificazione.
  4. Se l'archivio chiavi non contiene certificati, questo è il motivo. il certificato client non viene inviato dal processore di messaggi.

Risoluzione

  1. Assicurarsi che la catena di certificati client corretta e completa sia caricata nell'archivio chiavi specifico nel processore di messaggi.

Causa: mancata corrispondenza con l'autorità di certificazione

In genere, quando il server richiede al client di inviare il proprio certificato, indica l'insieme di emittenti o autorità di certificazione accettati. Se l'emittente/l'autorità di certificazione del certificato foglia (ad es. il primo il certificato nella catena di certificati) nel keystore del processore di messaggi non corrisponde a nessuna delle autorità di certificazione accettate dal server di backend, il processore di messaggi (che è un processo basato su Java) non inviare il certificato al server di backend.

Per verificare se è questo il caso, procedi nel seguente modo:

  1. Elenca i certificati per l'API keystore.
  2. Ottieni i dettagli di ciascun certificato ottenuto nel passaggio 1 precedente utilizzando Ottieni certificato per l'API keystore.
  3. Prendi nota dell'emittente del certificato foglia (ad es. il primo certificato nella catena di certificati) archiviato nell'archivio chiavi.

    Esempio di certificato di Fogliolina

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

    Nell'esempio precedente, l'emittente/l'autorità di certificazione è "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"

  4. Determina l'elenco di emittenti o autorità di certificazione accettati dal server di backend utilizzando una delle seguenti tecniche:

    Tecnica 1: utilizzare il comando Opensl riportato di seguito:

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

    Consulta la sezione "Nomi delle CA dei certificati client accettabili". nell'output di questo comando come mostrato di seguito:

    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
    

    Tecnica 2: controllo del pacchetto Certificate Request Pacchetti TCP/IP, in cui il server di backend richiede al client di inviare il proprio certificato:

    Nei pacchetti TCP/IP di esempio mostrati sopra, Certificate Request è il messaggio 7. Fai riferimento alla sezione "Nomi distinti" che contiene le autorità di certificazione accettabili del server di backend.

    alt_text

  5. Verifica se l'autorità di certificazione ottenuta nel passaggio 3 corrisponde all'elenco di autorità di certificazione o emittenti accettati del server di backend ottenuti nel passaggio 4. In caso di mancata corrispondenza, il processore di messaggi non invierà il certificato client. al server di backend.

    Nell'esempio precedente, puoi notare che chi ha emesso il Certificato Fogliolina del client nel Keystore del processore di messaggi non corrisponde a nessun Autorità di certificazione accettate. Pertanto, il processore di messaggi per inviare il certificato client al server di backend. Ciò causa la mancata riuscita dell'handshake SSL e il server di backend invia "Fatal alert: bad_certificate" .

Risoluzione

  1. Assicurati che il certificato con l'emittente/l'autorità di certificazione corrispondente L'emittente/l'autorità di certificazione del certificato foglia del client (primo certificato della catena) viene archiviato nell'archivio di attendibilità del server di backend.
  2. Nell'esempio descritto in questo playbook, il certificato con l'emittente "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" è stato aggiunto all'archivio attendibilità del server di backend per risolvere il problema.

Se il problema persiste, vai alla pagina Raccogliere dati diagnostici.

Raccogliere informazioni diagnostiche

Se il problema persiste anche dopo aver seguito le istruzioni riportate sopra, raccogli le seguenti informazioni diagnostiche. Contattalo e condividilo su Assistenza Apigee Edge:

  1. Se sei un utente del cloud pubblico, fornisci le seguenti informazioni:
    1. Nome dell'organizzazione
    2. Nome ambiente
    3. Nome proxy API
    4. Completa il comando curl per riprodurre l'errore
    5. File di traccia che mostra l'errore
    6. Pacchetti TCP/IP acquisiti sul server di backend
  2. Se sei un utente del cloud privato, fornisci le seguenti informazioni:
    1. Messaggio di errore completo osservato
    2. Bundle proxy API
    3. File di traccia che mostra l'errore
    4. Log del processore di messaggi /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. Pacchetti TCP/IP acquisiti sul server di backend o sul processore di messaggi.
    6. Output di Get cert for keystore API.
  3. Dettagli sulle sezioni di questo Playbook che hai provato e su eventuali altre insight che ci aiuteranno a risolvere rapidamente il problema.