Вы просматриваете документацию по Apigee Edge.
Перейдите к документации по Apigee X. Информация
Symptom
Клиентское приложение получает код статуса HTTP 503 с сообщением Сервис недоступен в ответ на запрос к API.
В трассировке интерфейса вы увидите, что error.cause имеет значение Received fatal alert: bad_certificate в потоке целевого запроса для неудачного запроса к API.
Если у вас есть доступ к журналам Message Processor, вы увидите сообщение об ошибке Received fatal alert: bad_certificate для неудачного запроса к API. Эта ошибка возникает во время процесса подтверждения SSL между Message Processor и внутренним сервером при двусторонней настройке TLS.
Сообщение об ошибке
Клиентское приложение получает следующий код ответа:
HTTP/1.1 503 Service Unavailable
Кроме того, может появиться следующее сообщение об ошибке:
{
"fault": {
"faultstring":"The Service is temporarily unavailable",
"detail":{
"errorcode":"messaging.adaptors.http.flow.ServiceUnavailable"
}
}
}Пользователи частного облака увидят следующую ошибку для определенного запроса к API в журналах 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
Возможные причины
Возможные причины:
| Cause | Описание | Инструкции по устранению неполадок, применимые к |
| Нет сертификата клиента | В хранилище ключей, используемом в целевой конечной точке целевого сервера, нет клиентского сертификата. | Пользователи частного и общедоступного облака Edge |
| Несоответствие центра сертификации | Центр сертификации конечного сертификата (первого сертификата в цепочке сертификатов) в хранилище ключей процессора сообщений не совпадает ни с одним из центров сертификации, принимаемых сервером. | Пользователи частного и общедоступного облака Edge |
Распространенные этапы диагностики
- Включите трассировку в интерфейсе Edge, выполните вызов API и воспроизведите проблему.
- В результатах трассировки интерфейса перейдите к каждому этапу и определите, где произошла ошибка. Ошибка произошла бы в целевом запросе.
- Изучите поток, в котором возникла ошибка. Она должна быть указана в трассировке, как показано в примере ниже:

- Как видно на скриншоте выше, error.cause – "Received fatal alert: bad_certificate".
- Если вы пользователь частного облака, следуйте инструкциям ниже:
- Идентификатор письма для неудачного запроса к API можно получить, определив значение заголовка ошибки
X-Apigee.Message-IDна этапе, указанном в трассировке как AX. - Найдите этот идентификатор сообщения в журнале 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 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]
В журнале Message Processor есть трассировка стека для ошибки
Received fatal alert: bad_certificate, но нет дополнительной информации, которая указывала бы на причину этой проблемы.
- Идентификатор письма для неудачного запроса к API можно получить, определив значение заголовка ошибки
- Чтобы разобраться в этой проблеме, вам нужно будет захватить пакеты TCP/IP с помощью инструмента tcpdump.
- Если вы используете частное облако, то можете захватывать пакеты TCP/IP на бэкенд-сервере или Message Processor. Лучше всего перехватывать их на внутреннем сервере, поскольку пакеты расшифровываются именно там.
- Если вы используете общедоступное облако, захватите пакеты TCP/IP на внутреннем сервере.
- Определив, где вы хотите перехватывать пакеты TCP/IP, используйте приведенную ниже команду tcpdump.
tcpdump -i any -s 0 host <IP address> -w <File name>
Если вы получаете пакеты TCP/IP на Message Processor, используйте общедоступный IP-адрес бэкенд-сервера в команде
tcpdump.Если у внутреннего сервера или Message Processor несколько IP-адресов, вам нужно использовать другую команду tcpdump. Дополнительную информацию об этом инструменте и других вариантах команды можно найти в tcpdump.
- Проанализируйте пакеты TCP/IP с помощью Wireshark или другого инструмента, с которым вы знакомы.
Ниже приведен анализ образцов данных пакетов TCP/IP с помощью инструмента Wireshark.

- Сообщение № 4 в tcpdump выше показывает, что Message Processor (источник) отправил сообщение Client Hello на бэкенд-сервер (назначение).
- В сообщении 5 показано, что бэкенд-сервер подтверждает сообщение Client Hello от Message Processor.
- Внутренний сервер отправляет сообщение "Server Hello" вместе со своим сертификатом, а затем запрашивает у клиента его сертификат в сообщении № 7.
- Message Processor завершает проверку сертификата и подтверждает сообщение ServerHello от бэкенд-сервера (сообщение № 8).
- Message Processor отправляет свой сертификат на бэкенд-сервер в сообщении 9.
- Внутренний сервер подтверждает получение сертификата обработчика сообщений в сообщении 11.
Однако он сразу же отправляет критическое предупреждение "Недействительный сертификат" в Message Processor (сообщение № 12). Это означает, что сертификат, отправленный Message Processor, был недействительным, поэтому проверка сертификата на бэкенд-сервере не удалась. В результате рукопожатие SSL не удалось, и подключение будет закрыто.

Теперь посмотрим на сообщение № 9, чтобы проверить содержимое сертификата, отправленного Message Processor:

- Как вы можете заметить, серверная часть не получила сертификат от клиента (Certificate Length: 0). Поэтому сервер отправляет оповещение о неустранимой ошибке: "Недействительный сертификат".
- Обычно это происходит, когда клиент, то есть обработчик сообщений (процесс на основе Java):
- В хранилище ключей нет сертификата клиента.
- Не удается отправить сертификат клиента. Это может произойти, если не удается найти сертификат, выданный одним из допустимых центров сертификации серверной части. Это означает, что если центр сертификации конечного сертификата клиента (то есть первого сертификата в цепочке) не совпадает ни с одним из допустимых центров сертификации внутреннего сервера, процессор сообщений не отправит сертификат.
Рассмотрим каждую из этих причин отдельно.
Причина: нет сертификата клиента
диагностика;
Если в хранилище ключей, указанном в разделе "Информация об SSL" конечной точки или целевого сервера, используемого в конечной точке, нет сертификата, это и является причиной ошибки.
Чтобы проверить, так ли это, выполните следующие действия:
- Чтобы определить, какое хранилище ключей используется в целевой конечной точке или целевом сервере для определенного прокси API, выполните следующие действия:
- Получите справочное имя хранилища ключей из элемента Keystore в разделе SSLInfo в целевой конечной точке или целевом сервере.
Ниже приведен пример раздела SSLInfo в конфигурации целевой конечной точки:
<SSLInfo> <Enabled>true</Enabled> <ClientAuthEnabled>true</ClientAuthEnabled> <KeyStore>ref://myKeystoreRef</KeyStore> <KeyAlias>myKey</KeyAlias> <TrustStore>ref://myTrustStoreRef</TrustStore> </SSLInfo>
- В примере выше имя ссылки на хранилище ключей – myKeystoreRef.
- Откройте интерфейс Edge и выберите API Proxies (Прокси API) > Environment Configurations (Конфигурации среды).
Откройте вкладку Цифровые отпечатки и найдите название цифрового отпечатка хранилища ключей. Запишите название в столбце Ссылка для определенной ссылки на хранилище ключей. Это будет название хранилища ключей.

- В примере выше видно, что myKeystoreRef ссылается на "myKeystore". Таким образом, имя хранилища ключей – myKeystore.
- Получите справочное имя хранилища ключей из элемента Keystore в разделе SSLInfo в целевой конечной точке или целевом сервере.
- Проверьте, содержит ли хранилище ключей сертификат, используя интерфейс Edge или API для получения списка сертификатов для хранилища ключей.
- Если в хранилище ключей есть сертификаты, перейдите к разделу Причина: несоответствие центра сертификации.
- Если в хранилище ключей нет сертификата, то именно поэтому Message Processor не отправляет сертификат клиента.
Разрешение
- Убедитесь, что в хранилище ключей Message Processor загружена правильная и полная цепочка сертификатов клиента.
Причина: несоответствие центра сертификации
Как правило, когда сервер запрашивает у клиента сертификат, он указывает набор принятых издателей или центров сертификации. Если издатель или центр сертификации конечного сертификата (первого сертификата в цепочке) в хранилище ключей обработчика сообщений не совпадает ни с одним из центров сертификации, принятых на внутреннем сервере, обработчик сообщений (процесс на основе Java) не отправит сертификат на внутренний сервер.
Чтобы проверить, так ли это, выполните следующие действия:
- List certs for keystore API.
- Получите сведения о каждом сертификате, полученном на шаге 1, с помощью API для получения сертификата для хранилища ключей.
- Запишите издателя конечного сертификата (то есть первого сертификата в цепочке сертификатов), хранящегося в хранилище ключей.
Пример конечного сертификата
{ "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" }В примере выше издателем/центром сертификации является
"CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com". - Определите список издателей или центров сертификации, принимаемых внутренним сервером, одним из следующих способов:
Методика 1. Используйте приведенную ниже команду openssl:
openssl s_client -host <backend server host name> -port <Backend port#> -cert <Client Certificate> -key <Client Private Key>
В выходных данных этой команды найдите раздел Acceptable Client Certificate CA names (Допустимые имена ЦС сертификатов клиента), как показано ниже:
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
Способ 2. Проверьте пакет
Certificate Requestв пакетах TCP/IP, где внутренний сервер запрашивает у клиента его сертификат:В примере пакетов TCP/IP, приведенном выше, пакет
Certificate Request– это сообщение № 7. Обратитесь к разделу "Уникальные имена", в котором указаны допустимые центры сертификации для внутреннего сервера.
Проверьте, соответствует ли центр сертификации, полученный на шаге 3, списку принятых издателей или центров сертификации внутреннего сервера, полученному на шаге 4. Если они не совпадают, Message Processor не отправит сертификат клиента на серверную часть.
В приведенном выше примере видно, что издатель конечного сертификата клиента в хранилище ключей обработчика сообщений не соответствует ни одному из принятых центров сертификации внутреннего сервера. Поэтому Message Processor не отправляет сертификат клиента на бэкенд-сервер. Это приводит к сбою подтверждения SSL, и серверная часть отправляет сообщение "
Fatal alert: bad_certificate".
Разрешение
- Убедитесь, что сертификат с издателем/центром сертификации, который соответствует издателю/центру сертификации конечного сертификата клиента (первого сертификата в цепочке), хранится в хранилище доверенных сертификатов внутреннего сервера.
- В примере, описанном в этом руководстве, для решения проблемы в хранилище доверенных сертификатов внутреннего сервера был добавлен сертификат с издателем
"issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com".
Если проблема не устранена, перейдите к разделу Сбор диагностической информации.
Обязательная диагностическая информация
Если проблема не устранена, соберите следующую диагностическую информацию. Обратитесь в службу поддержки Apigee Edge и предоставьте:
- Если вы используете общедоступное облако, предоставьте следующую информацию:
- Название организации
- Название среды
- Название прокси API
- Полная команда curl для воспроизведения ошибки
- Файл трассировки с ошибкой
- Пакеты TCP/IP, перехваченные на внутреннем сервере
- Если вы используете частное облако, предоставьте следующую информацию:
- Полное сообщение об ошибке
- Пакет прокси API
- Файл трассировки с ошибкой
- Журналы обработчика сообщений
/opt/apigee/var/log/edge-message-processor/logs/system.log - TCP/IP-пакеты, захваченные на бэкенд-сервере или Message Processor.
- Выходные данные API Get cert for keystore.
- Подробную информацию о том, какие разделы этого руководства вы уже изучили, и любые другие сведения, которые помогут нам быстрее решить проблему.