Перейти к содержимому
ecdsa.com
curl (OpenSSL backend)curl

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

curl: (60) SSL certificate problem: certificate has expired

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

  • curl: (60) SSL certificate OpenSSL verify result: certificate has expired (10)

Текст причины одинаков в сборках curl с OpenSSL 1.1.1, 3.0 и 3.5. Более новые версии curl (8.22.0 в нашей проверке) формулируют его как «SSL certificate OpenSSL verify result: certificate has expired (10)». Для сертификатов, которые ещё не действительны, причина другая: «certificate is not yet valid».

curl (OpenSSL backend) — CURLE_PEER_FAILED_VERIFICATION, X509_V_ERR_CERT_HAS_EXPIRED (10)

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

У одного из сертификатов в цепочке, которую построил curl, дата notAfter раньше текущего времени на машине, где запущен curl. Обычно это собственный сертификат сервера, но тот же текст выдаёт и просроченный промежуточный сертификат или перекрёстно подписанный корневой сертификат. Проверка идёт по локальным часам, поэтому неверные часы выглядят в точности как просроченный сертификат.

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

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

  1. 1.

    Выясните, у какого сертификата истёк срок действия

    Выведите дату notAfter каждого сертификата, который отдаёт сервер. Если просрочен конечный сертификат, продлите его; если промежуточный — замените файл цепочки тем, который сейчас публикует ваш CA.

    bash
    # Split the served chain into cert1.pem (leaf), cert2.pem, ... and print each expiry date
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | awk '/BEGIN CERT/{n++; f="cert" n ".pem"} /BEGIN CERT/,/END CERT/{print > f}'
    for f in cert*.pem; do openssl x509 -in "$f" -noout -subject -enddate; done
  2. 2.

    Продлите сертификат, перезагрузите конфигурацию и проверьте, что отдаётся на самом деле

    После продления перезагрузите конфигурацию каждого процесса и устройства, которые терминируют TLS для этого имени, а затем проверьте дату со стороны сети, а не по файлу на диске.

    bash
    sudo certbot renew                    # or your ACME client / CA portal
    sudo systemctl reload nginx           # the server keeps serving the old file until reloaded
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
      | openssl x509 -noout -enddate      # confirm the new date is what the network sees
  3. 3.

    Исправьте часы клиента

    Если на других машинах с сертификатом всё в порядке, синхронизируйте время на проблемной машине по NTP. В контейнерах часы берутся с хоста, поэтому исправлять их нужно там.

    bash
    date -u                       # compare with the real UTC time
    timedatectl status            # "System clock synchronized: yes"?
    sudo timedatectl set-ntp true
  4. 4.

    Обновите пакет сертификатов CA на клиенте

    На давно работающих системах обновлённый пакет ca-certificates удаляет выведенные из употребления корневые сертификаты и добавляет актуальные, и OpenSSL может выбрать действительный путь вместо просроченного.

    bash
    # Old clients: refresh the root store so they stop building paths through retired roots
    sudo apt-get update && sudo apt-get install --only-upgrade ca-certificates   # Debian/Ubuntu
    sudo dnf upgrade ca-certificates                                             # RHEL/Fedora

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

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