Почему появляется ошибка curl: (60) SSL certificate problem
Когда curl заходит на защищённый сайт (адрес начинается с https://), он проверяет цифровую подпись этого сайта. Это похоже на проверку паспорта: у сайта есть свой «документ» (SSL-сертификат), выданный доверенной организацией. Но одной подписи недостаточно - curl хочет увидеть всю цепочку доверия: кто выдал сертификат сайту, а тому — кто выдал ему, и так до самой главной «инстанции», корневого центра.
Иногда сервер отправляет curl только свой собственный документ, забывая приложить промежуточные звенья. Если curl не находит недостающее промежуточное звено у себя в хранилище, он останавливается и выдаёт ошибку unable to get local issuer certificate (не могу найти локальный сертификат издателя).
В Windows или Mac эта проблема встречается реже, потому что обновления системы часто добавляют актуальные сертификаты автоматически, да и браузеры могут использовать собственные списки доверенных центров. В CentOS же за это отвечает один системный файл, который иногда нужно обновлять вручную.
Как понять, какого сертификата не хватает
Давайте найдём виновника. Всё, что потребуется - выполнить несколько простых команд в терминале.
Посмотрим, с каким файлом работает curl
Выполните запрос с флагом подробного вывода:
| 1 | curl -v https://example.com |
Среди появившихся строк найдите:
| 1 | * CAfile: /etc/pki/tls/certs/ca-bundle.crt |
Это и есть тот самый системный «справочник» доверенных сертификатов. Если проблема в нём - будем его пополнять.
Выясним имя недостающего промежуточного сертификата
Введите команду, которая покажет всю цепочку, переданную сервером:
| 1 | openssl s_client -connect paper.seebug.org:443 -showcerts |
В выводе ищите секцию Certificate chain, а в ней - блоки с описаниями s: (subject, кому выдан) и i: (issuer, кем выдан). Например:
| 1 2 | 0 s:CN = example.com i:C = US, O = Let's Encrypt, CN = YR2 |
Здесь CN = YR2 - это имя того самого промежуточного центра, чей сертификат curl не может найти. Запомните это сокращение (YR2, R3, E1 и т.п.) - оно пригодится.
Проверим, есть ли такой сертификат в системе
Используйте поиск по нашему файлу-справочнику:
| 1 | grep -q "CN = YR2" /etc/pki/tls/certs/ca-bundle.crt && echo "Найден" || echo "Отсутствует" |
(Если у вас другое имя, подставьте его вместо YR2). Ответ «Отсутствует» подтвердит, что система действительно не знает такого издателя.
Исправляем ошибку: добавляем нужный сертификат
Действие простое: мы скачаем недостающий документ из официального источника и положим его в системную папку, после чего попросим CentOS обновить единый справочник.
Шаг 1. Скачиваем промежуточный сертификат
Надёжнее всего взять его прямо с сервера удостоверяющего центра. Для Let’s Encrypt с именем YR2 команда будет такой:
| 1 | sudo curl -o /etc/pki/ca-trust/source/anchors/yr2.crt http://yr2.i.lencr.org/ |
Если нужен другой центр (например, R3), замените адрес на соответствующий (http://r3.i.lencr.org/). Если ссылка вдруг недоступна, можно скопировать текст сертификата из вывода openssl s_client -showcerts (блок между -----BEGIN CERTIFICATE----- и -----END CERTIFICATE-----) и сохранить в файл с расширением .crt в ту же папку.
Шаг 2. Обновляем хранилище сертификатов
Теперь попросим систему учесть новый файл:
| 1 | sudo update-ca-trust extract |
Эта команда пересоберёт общий справочник, который использует curl.
Шаг 3. Убедимся, что curl «видит» обновления
Иногда файл, на который curl ссылается (/etc/pki/tls/certs/ca-bundle.crt), сам не обновляется, потому что он хранится отдельно. Проверим:
| 1 | ls -l /etc/pki/tls/certs/ca-bundle.crt |
Если вывод не содержит стрелки ->, значит, это не ссылка на свежий файл, а устаревшая копия. Заменим её символической ссылкой на актуальный справочник:
| 1 2 | sudo mv /etc/pki/tls/certs/ca-bundle.crt /etc/pki/tls/certs/ca-bundle.crt.bak sudo ln -s /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/pki/tls/certs/ca-bundle.crt |
Шаг 4. Проверяем работу
Ещё раз запросите сайт:
| 1 | curl -I https://example.com |
Если вы получили код ответа (например, HTTP/2 200), а не сообщение об ошибке - всё готово.
Что делать, если ошибка повторилась с другим сайтом
Принцип остаётся тем же:
- Определите имя пропущенного промежуточного центра через openssl s_client.
- Найдите и скачайте его сертификат в папку /etc/pki/ca-trust/source/anchors/.
- Выполните sudo update-ca-trust extract.
- Проверьте, что /etc/pki/tls/certs/ca-bundle.crt является ссылкой на обновлённый бандл (при необходимости замените).
Почему не стоит использовать флаг -k
В интернете можно встретить совет запускать "curl -k" - он отключает проверку сертификата, и ошибка пропадает. Но вместе с ней пропадает и защита: curl перестаёт проверять, настоящий ли перед ним сайт или мошеннический. Такой подход допустим только на секунду для теста, но никогда не должен применяться в настоящей работе или скриптах.
Заключение
Ошибка unable to get local issuer certificate в CentOS возникает из-за того, что системный список доверенных сертификатов неполон. Добавив пропущенное промежуточное звено и обновив хранилище, вы навсегда избавляетесь от проблемы. Этот способ работает на CentOS, RHEL, Rocky Linux и всех совместимых дистрибутивах — и не требует никакой переустановки curl или сложных настроек.
