file_get_contents HTTPS: certificate verify failed

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

Проблема относится к потокам HTTPS PHP/OpenSSL, а не к cURL: параметр curl.cainfo сам по себе не исправляет file_get_contents(). Проверка сертификата и имени узла должна оставаться включённой.

В этой статье
  1. Симптомы, область применения и причины
  2. Безопасная диагностика и пошаговое исправление
  3. Как проверить результат и что делать дальше

#Симптомы, область применения и причины

PHP не может прочитать HTTPS-адрес через file_get_contents из-за проверки цепочки доверия или имени узла. Пошаговая диагностика сертификата удалённого сайта, часов, CA-хранилища и настроек OpenSSL без отключения проверки. Проблема относится к потокам HTTPS PHP/OpenSSL, а не к cURL: параметр curl.cainfo сам по себе не исправляет file_get_contents(). Проверка сертификата и имени узла должна оставаться включённой.

Возможная причинаКак узнатьЧто делать
Сертификат удалённого сервера неверныйСертификат просрочен, не совпадает с именем хоста или сервер не отдаёт нужную цепочку.Браузер или openssl s_client тоже сообщает об ошибке для того же имени.Обратиться к владельцу удалённого узла и исправить TLS на его стороне.
На сервере устаревшее доверенное CA-хранилищеPHP использует неполный набор доверенных удостоверяющих центров.В браузере сертификат нормален, а на одном Linux-сервере проверка не проходит.Обновить доверенное хранилище системным способом и проверить openssl.cafile.
Запрос попадает на другой TLS-узелАдрес, SNI, корпоративный прокси или редирект приводят к чужому сертификату.Проверка имени указывает другую организацию/хост; ошибка зависит от сети.Проверить конечный адрес и конфигурацию промежуточного прокси.

#Безопасная диагностика и пошаговое исправление

  1. Зафиксируйте точный URL и текст ошибкиВ журнале приложения найдите file_get_contents(): SSL operation failed, certificate verify failed или Failed to enable crypto. Запишите hostname и дату ошибки без query-параметров, содержащих токены. Уточните, что вызывается file_get_contents с https://, а не curl_exec: у этих механизмов разные параметры доверенных сертификатов.
  1. Проверьте тот же адрес в обычном браузереНа своём компьютере откройте адрес https:// соответствующего узла (без секретных параметров). Нажмите значок информации о соединении → сведения о сертификате, уточните имя, сроки действия, цепочку и сообщения браузера. Если браузер тоже предупреждает об опасном сертификате, не нажимайте «Продолжить всё равно» и не обходите проверку: проблему должен исправить владелец сервера.
  1. Убедитесь в правильной дате и времени Linux-сервераПодключитесь к нужному серверу по SSH и выполните date -u; команда показывает UTC и не требует root. Сверьте дату и время с достоверным источником. Если часы заметно отличаются, обратитесь к администратору для исправления синхронизации времени; сертификаты могут не считаться действительными до или после дат в цепочке. Самостоятельно менять системные часы на многопользовательском сервере без согласования нельзя.
    Linux · Терминал (Bash)Команда
    Просмотр UTC на Linux по SSH. Команда ничего не меняет и работает без sudo.
    date -u
  1. Проверьте сертификат удалённого узла из той же сетиПо SSH на сервере с установленным OpenSSL выполните команду openssl s_client -connect example.org:443 -servername example.org -verify_return_error </dev/null, заменив оба example.org на настоящее доменное имя проблемного адреса. Опция -servername задаёт SNI, -verify_return_error останавливает проверку на ошибке цепочки. Результат изучает администратор: кроме Verify return code важны имя и промежуточные сертификаты; само наличие успешного соединения не доказывает совпадение имени узла. Не вводите токены URL в команду.
    Linux · Терминал (Bash)Команда
    Пример для SSH на Linux. ОБЯЗАТЕЛЬНО замените обе части example.org на реальное имя домена; не используйте команду без замены.
    openssl s_client -connect example.org:443 -servername example.org -verify_return_error </dev/null
  1. Проверьте конфигурацию OpenSSL в рабочем PHPВ закрытом тестовом обработчике приложения запишите значения ini_get("openssl.cafile"), ini_get("openssl.capath") и результат openssl_get_cert_locations(), не показывая их в публичном ответе. Сравните с реальным системным CA-хранилищем и настройками пула PHP-FPM. PHP в CLI может читать другой php.ini, поэтому его вывод не является окончательным доказательством для веб-приложения. Не задавайте случайный скачанный файл сертификатов по неизвестной ссылке.
  2. Временно в закрытой диагностике сайта
    PHP
    Временно в закрытой диагностике сайта. В журнал могут попасть пути конфигурации — не публикуйте его полностью.
    <?php
    error_log('openssl.cafile='.ini_get('openssl.cafile'));
    error_log('openssl.capath='.ini_get('openssl.capath'));
    error_log('cert info available='.(function_exists('openssl_get_cert_locations') ? 'yes' : 'no'));
  1. Разберите отдельные причины цепочки и имени хостаЕсли проверка показывает просроченный сертификат или отсутствие промежуточного сертификата на удалённой стороне, направьте владельцу узла время, hostname и вывод проверки без секретов. Если сертификат верен, но относится к другому имени, исправьте именно URL приложения и SNI/настройки сервера. Подмена peer_name не должна использоваться для маскировки неверного адреса: проверяемое имя обязано соответствовать доверенному узлу.
  1. Исправьте доверенные сертификаты в пределах полномочийЕсли системное хранилище действительно устарело, используйте штатное обновление пакета CA-сертификатов вашей Linux-системы под контролем администратора и в согласованное окно. Если предприятие использует проверяющий TLS-прокси, добавление его корневого сертификата допустимо только после подтверждения службой безопасности; не берите сертификат из письма неизвестного отправителя. В случае отдельного openssl.cafile укажите проверенный CA-файл для конкретного сайта, сохраните старый путь и проверьте совместимость версии PHP.
  1. Повторите запрос без ослабления TLS и откатите изменениеПосле исправления цепочки или доверенного CA выполните исходный тестовый HTTPS-запрос и убедитесь, что он получил ожидаемый HTTP-код и содержимое. Если он всё ещё выдаёт ошибку, проверьте конечный URL после редиректов, сетевую блокировку и CA-путь именно в FPM. Восстановите прежнюю настройку CA из резервной копии, если новые доверенные корни привели к иному поведению. Не устанавливайте verify_peer=false, verify_peer_name=false или allow_self_signed=true ради обхода ошибки.

#Как проверить результат и что делать дальше

Успех — исходный вызов file_get_contents получает данные по HTTPS, проверка сертификата и имени включена, а в журнале исчезает ошибка TLS. Если проблема сохраняется лишь в PHP-FPM, сравните его CA-пути с конфигурацией CLI и передайте администратору обезличенную диагностику.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.