Сообщение об ошибке
verify error:num=19:self-signed certificate in certificate chain
Также выводится как
- verify error:num=19:self signed certificate in certificate chain
- error 19 at 2 depth lookup: self-signed certificate in certificate chain
OpenSSL 3.x выводит «self-signed», 1.1.1 — «self signed». openssl verify выводит эту ошибку как «error 19 at <depth> depth lookup: …», где глубина — позиция корневого сертификата в цепочке.
OpenSSL CLI (openssl s_client / openssl verify) — X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
Что это означает
Ошибка OpenSSL 19 (X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN): цепочку удалось построить до самоподписанного корневого сертификата, который прислала другая сторона, но этого корневого сертификата нет в хранилище доверенных сертификатов. В отличие от ошибки 18, здесь есть настоящая иерархия CA; в отличие от ошибки 20, все звенья на месте. Либо этому корневому сертификату нужно доверять локально, либо соединение перехватывают.
Почему это происходит
Прокси с инспекцией TLS
частоКорпоративные прокси отправляют в цепочке собственный корневой сертификат. Если в субъекте верхнего сертификата указана ваша компания или производитель средств защиты, соединение проходит инспекцию TLS.
Частный CA: сервер сам отправляет его корневой сертификат
частоВнутренние сервисы часто отправляют полную цепочку вместе с корневым сертификатом, но клиентам всё равно нужно установить этот корневой сертификат как якорь доверия.
Проверка запущена без нужного хранилища доверенных сертификатов
иногдаПроверка с -CAfile, указывающим не на тот файл, или в образе, в хранилище которого нет корневого сертификата компании, выдаёт этот код для внутреннего сервиса, который настроен правильно.
Как исправить
- 1.
Определите корневой сертификат и его отпечаток
Разделите отдаваемую цепочку на сертификаты и выведите для каждого субъект, издателя и отпечаток SHA-256; сравните отпечаток корневого сертификата с тем, который публикует ваш ИТ-отдел или команда PKI.
bash openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | awk '/BEGIN CERT/{n++} {print > ("cert" n ".pem")}' for f in cert[0-9]*.pem; do openssl x509 -in "$f" -noout -subject -issuer -fingerprint -sha256 2>/dev/null; done - 2.
Проверьте с правильным корневым сертификатом, затем установите его
Если с -CAfile и опубликованным корневым сертификатом выводится «Verify return code: 0 (ok)», установите этот корневой сертификат в системное хранилище.
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com \ -CAfile corp-root-ca.pem 2>&1 | grep 'Verify return code' sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && sudo update-ca-certificates - 3.
Владельцам серверов: отправляйте только конечный и промежуточные сертификаты
Отправка корневого сертификата тратит байты в каждом рукопожатии и никогда не делает его доверенным; вместо этого распространите корневой сертификат на клиенты.
bash # Server owners: the root does not belong in the served chain cat server.pem intermediate.pem > fullchain.pem
Связанные ошибки
verify error:num=18:self-signed certificateOpenSSL CLI (openssl s_client / openssl verify)verify error:num=20:unable to get local issuer certificateOpenSSL CLI (openssl s_client / openssl verify)curl: (60) SSL certificate problem: self-signed certificate in certificate chaincurl (OpenSSL backend)self-signed certificate in certificate chainNode.js tls / https / fetch