#Симптомы, область применения и причины
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, корпоративный прокси или редирект приводят к чужому сертификату. | Проверка имени указывает другую организацию/хост; ошибка зависит от сети. | Проверить конечный адрес и конфигурацию промежуточного прокси. |
#Безопасная диагностика и пошаговое исправление
- Зафиксируйте точный URL и текст ошибкиВ журнале приложения найдите
file_get_contents(): SSL operation failed,certificate verify failedилиFailed to enable crypto. Запишите hostname и дату ошибки без query-параметров, содержащих токены. Уточните, что вызываетсяfile_get_contentsсhttps://, а неcurl_exec: у этих механизмов разные параметры доверенных сертификатов.
- Проверьте тот же адрес в обычном браузереНа своём компьютере откройте адрес https:// соответствующего узла (без секретных параметров). Нажмите значок информации о соединении → сведения о сертификате, уточните имя, сроки действия, цепочку и сообщения браузера. Если браузер тоже предупреждает об опасном сертификате, не нажимайте «Продолжить всё равно» и не обходите проверку: проблему должен исправить владелец сервера.
- Убедитесь в правильной дате и времени Linux-сервераПодключитесь к нужному серверу по SSH и выполните
date -u; команда показывает UTC и не требует root. Сверьте дату и время с достоверным источником. Если часы заметно отличаются, обратитесь к администратору для исправления синхронизации времени; сертификаты могут не считаться действительными до или после дат в цепочке. Самостоятельно менять системные часы на многопользовательском сервере без согласования нельзя.Linux · Терминал (Bash)КомандаПросмотр UTC на Linux по SSH. Команда ничего не меняет и работает без sudo.date -u
- Проверьте сертификат удалённого узла из той же сетиПо 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
- Проверьте конфигурацию OpenSSL в рабочем PHPВ закрытом тестовом обработчике приложения запишите значения
ini_get("openssl.cafile"),ini_get("openssl.capath")и результатopenssl_get_cert_locations(), не показывая их в публичном ответе. Сравните с реальным системным CA-хранилищем и настройками пула PHP-FPM. PHP в CLI может читать другой php.ini, поэтому его вывод не является окончательным доказательством для веб-приложения. Не задавайте случайный скачанный файл сертификатов по неизвестной ссылке. - Временно в закрытой диагностике сайта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'));
- Разберите отдельные причины цепочки и имени хостаЕсли проверка показывает просроченный сертификат или отсутствие промежуточного сертификата на удалённой стороне, направьте владельцу узла время, hostname и вывод проверки без секретов. Если сертификат верен, но относится к другому имени, исправьте именно URL приложения и SNI/настройки сервера. Подмена
peer_nameне должна использоваться для маскировки неверного адреса: проверяемое имя обязано соответствовать доверенному узлу.
- Исправьте доверенные сертификаты в пределах полномочийЕсли системное хранилище действительно устарело, используйте штатное обновление пакета CA-сертификатов вашей Linux-системы под контролем администратора и в согласованное окно. Если предприятие использует проверяющий TLS-прокси, добавление его корневого сертификата допустимо только после подтверждения службой безопасности; не берите сертификат из письма неизвестного отправителя. В случае отдельного
openssl.cafileукажите проверенный CA-файл для конкретного сайта, сохраните старый путь и проверьте совместимость версии PHP.
- Повторите запрос без ослабления 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 и передайте администратору обезличенную диагностику.