cURL error 60: SSL certificate problem: unable to get local issuer certificate
#Причины ошибки 60
cURL проверяет, что сертификат сервера подписан доверенным центром сертификации. Ошибка unable to get local issuer certificate означает, что у PHP нет актуального набора корневых сертификатов (часто на Windows/XAMPP и старых серверах), либо удалённый сервер отдаёт неполную цепочку (без промежуточного сертификата), либо сертификат просрочен, выдан на другое имя, либо перехватывается корпоративным прокси со своим корневым сертификатом.
#Причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Нет корневых сертификатовWindows/XAMPP. | unable to get local issuer. | Укажите cacert.pem. |
| Неполная цепочка на сервереНет промежуточного. | Работает в браузере, не в PHP. | Исправьте у владельца сервера. |
| Сертификат просроченНе продлён. | certificate has expired. | Обновите сертификат. |
| Имя не совпадаетСертификат на другой домен. | no alternative certificate subject. | Используйте верное имя. |
| Неверное время сервераСдвиг. | Ошибка валидности. | Синхронизируйте время. |
| Корпоративный перехватПрокси подменяет сертификат. | Только в офисной сети. | Добавьте корневой сертификат организации. |
#Порядок
- Проверьте сертификат сайта командой opensslАдминистратору сервера нужно определить, чей сертификат не проверяется: удалённого API или корпоративного прокси. Откройте терминал на сервере PHP и выполните
openssl s_client -connect api.example.com:443 -servername api.example.com -verify_return_error </dev/null(адрес замените), изучитеVerify return codeи даты сертификата. Команда диагностическая; если соединение проходит из браузера, но не из PHP, проблема может быть в хранилище доверенных сертификатов конкретного PHP. - Проверьте дату и время сервераВ Linux выполните
timedatectl statusи сравните дату с текущей; неверные часы приводят к ошибкам срока действия сертификатов. На Windows проверьте «Параметры» → «Время и язык» → «Дата и время» и синхронизацию. Изменять системное время на рабочем сервере следует по согласованию, особенно если используются доменные учётные записи или базы данных; сначала исправьте источник времени NTP. - Скачайте актуальный cacert.pem с https://curl.se/docs/caextract.htmlНа Debian/Ubuntu сначала проверьте системное хранилище через
sudo apt updateиsudo apt install --reinstall ca-certificates, затемsudo update-ca-certificates. Для Windows PHP иногда требуется отдельный проверенный набор корневых сертификатов. Если выбран файл CA bundle сcurl.se/ca/cacert.pem, скачайте его из официального источника по HTTPS в заранее подготовленный каталог, проверьте доступность и права. Не подменяйте системный файл/etc/ssl/certs/cacert.pemнеизвестным содержимым. - Укажите путь в php.ini: curl.cainfo и openssl.cafileЧтобы узнать используемый PHP, в терминале выполните
php --ini, но помните: настройки командной строки и PHP-FPM веб-сайта могут отличаться. В конфигурации нужного обработчика при необходимости установитеcurl.cainfoиopenssl.cafileна абсолютный путь к доверенному CA bundle. Убедитесь, что файл читает пользователь PHP-FPM; не размещайте его в публичном каталоге сайта и не используйте пользовательский сертификат удалённого сервера как универсальный центр доверия. - Перезапустите PHP-FPM или веб-серверПосле изменения настроек администратор запускает
php -i | grep -E "curl.cainfo|openssl.cafile"для CLI и проверяет настройки сайта в панели. Перезагрузите именно нужный пул PHP-FPM или сервис только в согласованное время (имена служб отличаются по версиям и панели), затем повторите тестовый запрос из приложения. Не перезапускайте Nginx/Apache без необходимости. Если ошибка сохраняется, сравните фактический путь файла CA и журнал cURL. - Если сертификат удалённого сервера неполный, сообщите владельцу илиЕсли
openssl s_clientпоказывает неполную цепочку сертификатов удалённого сайта, владелец этого сервера должен установить корректную цепочку на своей стороне (обычно leaf + intermediate). Если API чужой, сообщите поддержке адрес и ошибки проверки, не добавляйте случайный промежуточный сертификат в глобальное хранилище своего сервера. Обход TLS-проверки не исправит проблему надёжным способом. - Для корпоративного прокси добавьте корневой сертификат организацииВ сети с официальным корпоративным TLS-прокси администратор безопасности может выдать доверенный корневой сертификат организации и документированную процедуру установки на рабочем узле. Проверьте подлинность и отпечаток сертификата через доверенный канал; устанавливать его допустимо только на доверенных корпоративных системах. Если прокси не должен подменять TLS, обратитесь к сетевому администратору, а не добавляйте неизвестный CA.
- Отключение проверки допустимо только для локальной отладкиНе используйте
CURLOPT_SSL_VERIFYPEER=false,CURLOPT_SSL_VERIFYHOST=0,--insecureили аналогичные настройки как метод исправления на рабочем сайте. Они отключают защиту от подмены API и перехвата данных, включая пароли и токены. Для отладки используйте тестовую среду и фиксируйте действительную ошибку цепочки; правильное исправление — доверенное хранилище, системное время или сертификат сервера. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Где искать цепочку
Проверьте сайт онлайн на https://www.ssllabs.com/ssltest/ : тест покажет неполную цепочку, просроченные сертификаты и несоответствие имён. Если неполная цепочка у вашего сервера, объедините сертификат сайта и промежуточные в один файл fullchain.pem и укажите его в настройках веб-сервера.