Сообщение об ошибке
SSL routines:tls_process_client_certificate:peer did not return a certificate
Также выводится как
- error:0A0000C7:SSL routines::peer did not return a certificate
OpenSSL 3.x записывает в журнал «error:0A0000C7:SSL routines:tls_process_client_certificate:peer did not return a certificate:<source>». nginx этот путь не использует: при ssl_verify_client on он завершает рукопожатие и вместо этого возвращает HTTP 400 «No required SSL certificate was sent».
OpenSSL (server side, mutual TLS) — SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE
Что это означает
Это запись на стороне сервера о неудачном рукопожатии со взаимной TLS-аутентификацией: сервер потребовал клиентский сертификат (SSL_VERIFY_FAIL_IF_NO_PEER_CERT), а клиент его не отправил. Затем сервер прерывает соединение оповещением (certificate_required в TLS 1.3, handshake_failure в TLS 1.2), и клиент видит ошибку с этим оповещением.
Почему это происходит
У клиента не настроен сертификат
частоНовое развёртывание, заменённый секрет, который не дошёл до клиента, или библиотека, которой не передали сертификат и ключ.
Проверки состояния балансировщика нагрузки и мониторинг
частоСредства проверки состояния обычно подключаются без клиентского сертификата; на сервере, который требует его для каждого соединения, они порождают непрерывный поток таких строк.
Клиент не нашёл сертификата, подходящего под список CA сервера
иногдаБраузеры и некоторые библиотеки предлагают только сертификат, выпущенный одним из CA, которые перечисляет сервер; иначе они отправляют пустое сообщение Certificate.
Как исправить
- 1.
Настройте клиентский сертификат
Передайте клиенту его сертификат и ключ и проверьте с помощью curl --cert/--key.
bash # Test from the client side with a certificate curl --cert client.pem --key client.key https://mtls.example.com/ - 2.
Сделайте сертификат необязательным там, где это нужно
Серверы, которые также обслуживают проверки состояния или публичные пути, могут запрашивать сертификаты в необязательном режиме и требовать их в отдельных блоках location.
text # nginx: request but do not require a certificate on paths that must stay open (health checks) ssl_verify_client optional; location /internal/ { if ($ssl_client_verify != SUCCESS) { return 403; } } - 3.
Проверьте имена CA, которые объявляет сервер
Издатель клиентских сертификатов должен быть в списке, который отправляет сервер, иначе клиенты, выбирающие сертификат автоматически, не предложат ни одного.
bash # The CA list the server advertises must include the issuer of the client certificates openssl s_client -connect mtls.example.com:443 -servername mtls.example.com </dev/null 2>/dev/null \ | sed -n '/Acceptable client certificate CA names/,/^Requested/p'