Wyświetlasz dokumentację Apigee Edge.
Otwórz dokumentację
Apigee X. info
Krótki opis problemu
Aplikacja kliencka otrzymuje kod stanu HTTP 503 z
komunikatem „Service Unavailable” w odpowiedzi na żądanie do interfejsu API.
W śledzeniu w interfejsie użytkownika zobaczysz, że w przypadku nieudanego żądania do interfejsu API error.cause
to Received fatal alert: bad_certificate w sekcji Target Request Flow
(Przepływ żądania do serwera docelowego).
Jeśli masz dostęp do logów procesora komunikatów,
zobaczysz komunikat o błędzie jako Received fatal alert: bad_certificate
w przypadku nieudanego żądania do interfejsu API. Ten błąd występuje podczas procesu uzgadniania SSL
między procesorem komunikatów a serwerem backendu w konfiguracji TLS dwukierunkowej.
Komunikat o błędzie
Aplikacja kliencka otrzymuje ten kod odpowiedzi:
HTTP/1.1 503 Service Unavailable
Może też pojawić się ten komunikat o błędzie:
{
"fault": {
"faultstring":"The Service is temporarily unavailable",
"detail":{
"errorcode":"messaging.adaptors.http.flow.ServiceUnavailable"
}
}
}Użytkownicy Private Cloud zobaczą ten błąd w przypadku konkretnego żądania do interfejsu API
w logach procesora komunikatów /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
Możliwe przyczyny
Możliwe przyczyny tego problemu:
| Przyczyna | Opis | Instrukcje rozwiązywania problemów, których dotyczy |
| Brak certyfikatu klienta | Magazyn kluczy używany w punkcie końcowym serwera docelowego nie zawiera certyfikatu klienta. | Użytkownicy Edge Private i Public Cloud |
| Niezgodność urzędu certyfikacji | Urząd certyfikacji certyfikatu liścia (pierwszego certyfikatu w łańcuchu certyfikatów) w magazynie kluczy procesora komunikatów nie pasuje do żadnego z urzędów certyfikacji akceptowanych przez serwer backendu. | Użytkownicy Edge Private i Public Cloud |
Typowe czynności diagnostyczne
- Włącz śledzenie w interfejsie Edge, wywołaj interfejs API i odtwórz problem.
- W wynikach śledzenia w interfejsie użytkownika przejdź przez każdy etap i określ, gdzie wystąpił błąd. Błąd wystąpił w sekcji Target Request Flow (Przepływ żądania do serwera docelowego).
- Sprawdź przepływ, w którym występuje błąd. Powinien on wyglądać tak jak w przykładowym śledzeniu poniżej:

- Jak widać na zrzucie ekranu powyżej, error.cause to "Received fatal alert: bad_certificate".
- Jeśli jesteś użytkownikiem Private Cloud, wykonaj te czynności:
- Identyfikator wiadomości w przypadku nieudanego żądania do interfejsu API możesz uzyskać, określając
wartość nagłówka błędu "
X-Apigee.Message-ID" na etapie wskazanym przez AX w śledzeniu. - Wyszukaj ten identyfikator wiadomości w logu procesora komunikatów
/opt/apigee/var/log/edge-message-processor/system.logi sprawdź czy możesz znaleźć dodatkowe informacje o błędzie: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]
Log procesora komunikatów zawiera ślad stosu błędu
Received fatal alert: bad_certificate, ale nie zawiera żadnych dodatkowych informacji wskazujących na przyczynę tego problemu.
- Identyfikator wiadomości w przypadku nieudanego żądania do interfejsu API możesz uzyskać, określając
wartość nagłówka błędu "
- Aby dokładniej zbadać ten problem, musisz przechwycić pakiety TCP/IP za pomocą
tcpdump.
- Jeśli jesteś użytkownikiem Private Cloud, możesz przechwycić pakiety TCP/IP na serwerze backendu lub procesorze komunikatów. Najlepiej przechwycić je na serwerze backendu, ponieważ pakiety są na nim odszyfrowywane.
- Jeśli jesteś użytkownikiem Public Cloud, przechwyć pakiety TCP/IP na serwerze backendu.
- Gdy zdecydujesz, gdzie chcesz przechwycić pakiety TCP/IP, użyj tego poniższego polecenia tcpdump , aby je przechwycić.
tcpdump -i any -s 0 host <IP address> -w <File name>
Jeśli przechwytujesz pakiety TCP/IP na procesorze komunikatów, w poleceniu
tcpdumpużyj publicznego adresu IP serwera backendu.Jeśli serwer backendu lub procesor komunikatów ma kilka adresów IP, musisz użyć innego polecenia tcpdump. Więcej informacji o tym narzędziu i innych wariantach tego polecenia znajdziesz w dokumentacji tcpdump.
- Przeanalizuj pakiety TCP/IP za pomocą narzędzia Wireshark lub podobnego narzędzia, które znasz.
Oto analiza przykładowych danych pakietów TCP/IP za pomocą narzędzia Wireshark:

- Wiadomość nr 4 w tcpdump powyżej pokazuje, że procesor komunikatów (źródło) wysłał wiadomość „Client Hello” do serwera backendu (miejsce docelowe).
- Wiadomość nr 5 pokazuje, że serwer backendu potwierdza wiadomość Client Hello od procesora komunikatów.
- Serwer backendu wysyła wiadomość "Server Hello" wraz z certyfikatem, a następnie prosi klienta o wysłanie certyfikatu w wiadomości nr 7.
- Procesor komunikatów kończy weryfikację certyfikatu i potwierdza wiadomość ServerHello serwera backendu w wiadomości nr 8.
- Procesor komunikatów wysyła swój certyfikat do serwera backendu w wiadomości nr 9.
- Serwer backendu potwierdza otrzymanie certyfikatu procesora komunikatów w wiadomości nr 11.
Jednak natychmiast wysyła do procesora komunikatów Fatal Alert: Bad Certificate (Wiadomość nr 12). Oznacza to, że certyfikat wysłany przez procesor komunikatów był nieprawidłowy, dlatego weryfikacja certyfikatu na serwerze backendu nie powiodła się. W rezultacie uzgadnianie SSL nie powiodło się i połączenie zostanie zamknięte.

Przyjrzyjmy się teraz wiadomości nr 9, aby sprawdzić zawartość certyfikatu wysłanego przez procesor komunikatów:

- Jak widać, serwer backendu nie otrzymał żadnego certyfikatu od klienta (Certificate Length: 0). Dlatego serwer backendu wysyła komunikat Fatal Alert: Bad Certificate.
- Zwykle dzieje się tak, gdy klient, czyli procesor komunikatów (proces oparty na Javie):
- nie ma certyfikatu klienta w magazynie kluczy lub
- nie może wysłać certyfikatu klienta. Może się tak zdarzyć, jeśli nie może znaleźć certyfikatu wydanego przez jeden z urzędów certyfikacji akceptowanych przez serwer backendu. Oznacza to, że jeśli urząd certyfikacji certyfikatu liścia klienta (czyli pierwszego certyfikatu w łańcuchu) nie pasuje do żadnego z urzędów certyfikacji akceptowanych przez serwer backendu, procesor komunikatów nie wyśle certyfikatu.
Przyjrzyjmy się teraz każdej z tych przyczyn osobno.
Przyczyna: brak certyfikatu klienta
Diagnostyka
Jeśli w magazynie kluczy określonym w sekcji SSL Info punktu końcowego serwera docelowego lub serwera docelowego używanego w punkcie końcowym serwera docelowego nie ma certyfikatu, jest to przyczyna tego błędu.
Aby sprawdzić, czy to jest przyczyna problemu, wykonaj te czynności:
- Określ magazyn kluczy używany w punkcie końcowym serwera docelowego lub serwerze docelowym w przypadku konkretnego proxy interfejsu API, wykonując te czynności:
- Pobierz nazwę odwołania do magazynu kluczy z elementu Keystore
w sekcji SSLInfo w punkcie końcowym serwera docelowego lub serwerze docelowym.
Oto przykładowa sekcja SSLInfo w konfiguracji punktu końcowego serwera docelowego:
<SSLInfo> <Enabled>true</Enabled> <ClientAuthEnabled>true</ClientAuthEnabled> <KeyStore>ref://myKeystoreRef</KeyStore> <KeyAlias>myKey</KeyAlias> <TrustStore>ref://myTrustStoreRef</TrustStore> </SSLInfo>
- W powyższym przykładzie nazwa odwołania do magazynu kluczy to „myKeystoreRef”.
- Otwórz interfejs Edge i kliknij API Proxies (Proxy interfejsu API) –> Environment Configurations (Konfiguracje środowiska).
Kliknij kartę References (Odwołania) i wyszukaj nazwę odwołania do magazynu kluczy. Zanotuj nazwę w kolumnie Reference (Odwołanie) dla konkretnego odwołania do magazynu kluczy. Będzie to nazwa magazynu kluczy.

- W powyższym przykładzie widać, że myKeystoreRef odwołuje się do „myKeystore”. Dlatego nazwa magazynu kluczy to myKeystore.
- Pobierz nazwę odwołania do magazynu kluczy z elementu Keystore
w sekcji SSLInfo w punkcie końcowym serwera docelowego lub serwerze docelowym.
- Sprawdź, czy ten magazyn kluczy zawiera certyfikat, korzystając z interfejsu Edge lub interfejsu API List certs for keystore.
- Jeśli magazyn kluczy zawiera certyfikaty, przejdź do sekcji Przyczyna: niezgodność urzędu certyfikacji.
- Jeśli magazyn kluczy nie zawiera żadnego certyfikatu, jest to powód, dla którego certyfikat klienta nie jest wysyłany przez procesor komunikatów.
Rozwiązanie
- Upewnij się, że prawidłowy i kompletny łańcuch certyfikatów klienta został przesłany do konkretnego magazynu kluczy w procesorze komunikatów.
Przyczyna: niezgodność urzędu certyfikacji
Gdy serwer prosi klienta o wysłanie certyfikatu, wskazuje zwykle zestaw akceptowanych wystawców lub urzędów certyfikacji. Jeśli wystawca lub urząd certyfikacji certyfikatu liścia (czyli pierwszego certyfikatu w łańcuchu certyfikatów) w magazynie kluczy procesora komunikatów nie pasuje do żadnego z urzędów certyfikacji akceptowanych przez serwer backendu, procesor komunikatów (który jest procesem opartym na Javie) nie wyśle certyfikatu do serwera backendu.
Aby sprawdzić, czy tak jest w Twoim przypadku, wykonaj te czynności:
- Użyj interfejsu API List certs for keystore.
- Pobierz szczegóły każdego certyfikatu uzyskanego w kroku 1, korzystając z interfejsu API Get cert for keystore.
- Zanotuj wystawcę certyfikatu liścia (czyli pierwszego certyfikatu w łańcuchu certyfikatów) przechowywanego w magazynie kluczy.
Przykładowy certyfikat liścia
{ "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" }W powyższym przykładzie wystawca lub urząd certyfikacji to
"CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" - Określ akceptowaną listę wystawców lub urzędów certyfikacji serwera backendu, korzystając z jednej z tych metod:
Metoda 1. Użyj tego polecenia openssl:
openssl s_client -host <backend server host name> -port <Backend port#> -cert <Client Certificate> -key <Client Private Key>
W danych wyjściowych tego polecenia znajdź sekcję „Acceptable Client Certificate CA names” (Akceptowane nazwy urzędów certyfikacji certyfikatów klienta), jak pokazano poniżej:
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
Metoda 2. Sprawdź pakiet
Certificate Requestw pakietach TCP/IP, w których serwer backendu prosi klienta o wysłanie certyfikatu:W przykładowych pakietach TCP/IP pokazanych powyżej pakiet
Certificate Requestto wiadomość nr 7. Znajdź sekcję „Distinguished Names” (Nazwy wyróżniające), która zawiera akceptowane urzędy certyfikacji serwera backendu.
Sprawdź, czy urząd certyfikacji uzyskany w kroku 3 pasuje do listy akceptowanych wystawców lub urzędów certyfikacji serwera backendu uzyskanej w kroku 4. Jeśli występuje niezgodność, procesor komunikatów nie wyśle certyfikatu klienta do serwera backendu.
W powyższym przykładzie widać, że wystawca certyfikatu liścia klienta w magazynie kluczy procesora komunikatów nie pasuje do żadnego z serwerów backendu akceptowanych urzędów certyfikacji. Dlatego procesor komunikatów nie wysyła certyfikatu klienta do serwera backendu. Powoduje to niepowodzenie uzgadniania SSL, a serwer backendu wysyła komunikat „
Fatal alert: bad_certificate”.
Rozwiązanie
- Upewnij się, że certyfikat z wystawcą lub urzędem certyfikacji, który pasuje do wystawcy lub urzędu certyfikacji certyfikatu liścia klienta (pierwszego certyfikatu w łańcuchu), jest przechowywany w magazynie zaufanych certyfikatów serwera backendu.
- W przykładzie opisanym w tym przewodniku, aby rozwiązać problem, do magazynu zaufanych certyfikatów serwera backendu dodano certyfikat z wystawcą
"issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com".
Jeśli problem nadal występuje, przejdź do sekcji Informacje diagnostyczne, które należy zebrać.
Informacje diagnostyczne, które należy zebrać
Jeśli problem nadal występuje po wykonaniu powyższych instrukcji, zbierz te informacje diagnostyczne. Skontaktuj się z zespołem pomocy Apigee Edge i udostępnij mu te informacje: Apigee Edge Support:
- Jeśli jesteś użytkownikiem Public Cloud, podaj te informacje:
- Nazwa organizacji
- Nazwa środowiska
- Nazwa proxy interfejsu API
- Pełne polecenie curl umożliwiające odtworzenie błędu
- Plik śledzenia, w którym widać błąd
- Pakiety TCP/IP przechwycone na serwerze backendu
- Jeśli jesteś użytkownikiem Private Cloud, podaj te informacje:
- Pełny komunikat o błędzie
- Pakiet proxy interfejsu API
- Plik śledzenia, w którym widać błąd
- Logi procesora komunikatów
/opt/apigee/var/log/edge-message-processor/logs/system.log - Pakiety TCP/IP przechwycone na serwerze backendu lub procesorze komunikatów.
- Dane wyjściowe interfejsu API Get cert for keystore.
- Szczegółowe informacje o tym, które sekcje tego przewodnika zostały przez Ciebie sprawdzone, oraz wszelkie inne informacje, które pomogą nam szybciej rozwiązać ten problem.