Сообщение об ошибке
verify error:num=21:unable to verify the first certificate
Также выводится как
- Verify return code: 21 (unable to verify the first certificate)
openssl s_client выводит эту ошибку как «verify error:num=21:…» и «Verify return code: 21 (…)». В Node.js та же ситуация называется UNABLE_TO_VERIFY_LEAF_SIGNATURE («unable to verify the first certificate»).
OpenSSL CLI (openssl s_client) — X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
Что это означает
Ошибка OpenSSL 21 (X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE): цепочка состоит из одного сертификата, собственного сертификата сервера, и его издателя найти не удалось, поэтому нельзя проверить даже подпись конечного сертификата. Прямо перед этой ошибкой s_client обычно выводит ошибку 20 для глубины 0. Исправлять почти всегда нужно сервер: он должен отправлять свой промежуточный сертификат.
Почему это происходит
В конфигурации сервера указан только конечный сертификат
частоcert.pem вместо fullchain.pem, сертификат, вставленный в балансировщик нагрузки без цепочки, или запись в хранилище ключей Java, импортированная без сертификата выпускающего CA.
Цепочка настроена, но не отправляется
иногдаНекоторым серверам цепочку нужно указывать в отдельной директиве или поле (SSLCertificateChainFile в старых версиях Apache, поле цепочки в облачном балансировщике нагрузки); пакет сертификатов не на своём месте молча игнорируется.
Сервер отправляет промежуточный сертификат, которым конечный сертификат не выпущен
иногдаПосле того как CA сменил промежуточные сертификаты, старый файл цепочки отдаёт сертификат, который не является издателем конечного; OpenSSL не может его использовать.
Как исправить
- 1.
Проверьте, что отправляет сервер
Проблему подтверждает единственный сертификат, издатель которого (i:) — промежуточный CA.
bash openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:' - 2.
Отдавайте конечный и промежуточные сертификаты
Склейте по порядку конечный сертификат и выпустивший его промежуточный (или несколько промежуточных) и укажите этот файл в конфигурации сервера; выведите содержимое пакета, чтобы проверить порядок.
bash # Build the file the server should use: leaf, then intermediates (issuer of each previous one) cat server.pem intermediate.pem > fullchain.pem openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout # check the order - 3.
Найдите правильный промежуточный сертификат
Расширение Authority Information Access в конечном сертификате указывает URL сертификата его издателя; скачайте этот сертификат, при необходимости преобразуйте в PEM и добавьте в файл цепочки.
bash # Where to download the missing intermediate: the leaf's Authority Information Access URL openssl x509 -in server.pem -noout -ext authorityInfoAccess curl -sS -o intermediate.der http://ca.example.com/issuing-ca.crt openssl x509 -inform der -in intermediate.der -out intermediate.pem