Перейти к содержимому
ecdsa.com
rustls (via reqwest, ureq, hyper-rustls, tonic)Rust

Сообщение об ошибке

invalid peer certificate: UnknownIssuer

Также выводится как

  • InvalidCertificate(UnknownIssuer)

reqwest выводит эту ошибку в конце цепочки причин: «error sending request for url (…): client error (Connect): invalid peer certificate: UnknownIssuer»; в выводе Debug она выглядит как InvalidCertificate(UnknownIssuer). ureq выводит «io: invalid peer certificate: UnknownIssuer». Нативные исполняемые файлы на основе rustls (pnpm 12, многие CLI-утилиты) показывают тот же текст.

rustls (via reqwest, ureq, hyper-rustls, tonic) — rustls::Error::InvalidCertificate(CertificateError::UnknownIssuer)

Что это означает

rustls не смог построить цепочку от сертификата сервера ни к одному из настроенных якорей доверия. UnknownIssuer — единый код rustls для любой ошибки построения цепочки: частный CA или CA прокси, отсутствующий промежуточный сертификат или самоподписанный сертификат. Какие корневые сертификаты считаются доверенными, зависит от того, как собран крейт: с платформенным модулем проверки (хранилище ОС), с rustls-native-certs (корневые сертификаты ОС, загружаемые при запуске) или с webpki-roots (встроенный при компиляции список Mozilla).

Почему это происходит

Как исправить

  1. 1.

    Добавьте корневой сертификат в клиент

    ClientBuilder::add_root_certificate добавляет якорь доверия, сохраняя полную проверку (имён, дат).

    rust
    // Trust a private root for this client (in addition to the default roots)
    let pem = std::fs::read("corp-root-ca.pem")?;
    let client = reqwest::Client::builder()
        .add_root_certificate(reqwest::Certificate::from_pem(&pem)?)
        .build()?;
  2. 2.

    Установите корневой сертификат в хранилище ОС

    С платформенным модулем проверки (по умолчанию в reqwest 0.13) корневые сертификаты из хранилища операционной системы считаются доверенными; в Linux достаточно update-ca-certificates.

    bash
    # reqwest 0.13 verifies with the platform verifier: install the root in the OS store
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt
    sudo update-ca-certificates
  3. 3.

    Проверьте, какой источник корневых сертификатов встроен в сборку

    cargo tree показывает, что используется: webpki-roots или rustls-native-certs; если должно действовать хранилище ОС, переключите features.

    bash
    # Which root source is compiled into this binary? (a crate that is absent reports no match)
    cargo tree -e features -i rustls-platform-verifier   # OS verifier (reqwest 0.13 default)
    cargo tree -e features -i rustls-native-certs        # OS roots loaded at start-up
    cargo tree -e features -i webpki-roots               # Mozilla roots compiled in, OS store ignored
  4. 4.

    Владельцам серверов: отправляйте промежуточный сертификат

    Если в рукопожатии только один сертификат и его издатель — промежуточный 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:'

Связанные ошибки

Открыть всю базу ошибок подписей