#Что происходит и как определить неисправность
Ошибка TLS в cURL при HTTPS-запросе из PHP — чаще проблема проверки цепочки сертификатов, имени узла или системного набора доверенных центров. Выключать CURLOPT_SSL_VERIFYPEER или CURLOPT_SSL_VERIFYHOST ради «исправления» опасно: так запрос перестанет подтверждать подлинность сервера.
#Вероятные причины и признаки
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Нет актуального набора корневых сертификатовНет актуального набора корневых сертификатов. curl из терминала работает иначе, чем расширение PHP, в ошибке 60 | curl из терминала работает иначе, чем расширение PHP, в ошибке 60 | Обновить доверенный системный набор и проверить настройку curl.cainfo. |
| Сервер отдаёт неполную/чужую цепочкуСервер отдаёт неполную/чужую цепочку. Внешняя проверка сертификата показывает недоверенный intermediate либо hostname mismatch | Внешняя проверка сертификата показывает недоверенный intermediate либо hostname mismatch | Исправить конфигурацию удалённого сервера, а не обходить проверку. |
| Прокси или системные часы нарушают проверкуПрокси или системные часы нарушают проверку. Ошибка появляется только на рабочем сервере или после изменения времени | Ошибка появляется только на рабочем сервере или после изменения времени | Проверить время, доверенную корпоративную цепочку и настройки прокси. |
#Пошаговая диагностика и исправление
- Сохраните текст ошибки и имя адресатаНайдите запись curl_error() / curl_errno() в журнале приложения. Запишите код ошибки без секретных параметров URL, заголовков Authorization и токенов. Различайте ошибку 60, 35 и 28: у них разные причины; неверное имя сертификата отдельно от тайм-аута.
- Проверьте тот же адрес с сервераВ SSH выполните запрос к известному HTTPS-адресу; подставьте целевой домен без закрытых параметров. Посмотрите код ответа, данные TLS и возможную ошибку проверки. Не используйте -k или --insecure: они скрывают подлинную проблему.
- Команда для Linux/macOS терминала; заменить example.org реальным разрешённым адресомLinux · Терминал (Bash)КомандаКоманда для Linux/macOS терминала; заменить example.org реальным разрешённым адресом. Это curl CLI, не расширение PHP.
curl -Iv --connect-timeout 10 https://example.org/
- Проверьте системную датуИз SSH сравните системные часы и UTC. При сильном расхождении сертификаты могут казаться ещё не действительными или просроченными. Исправление синхронизации выполняет администратор, а не изменение времени внутри приложения.
- Только просмотр времени в UTCLinux · Терминал (Bash)КомандаТолько просмотр времени в UTC.
date -u
- Уточните, каким PHP выполняется запросВ панели сайта откройте версию PHP и её дополнительные настройки; CLI php -v может относиться к другому интерпретатору. Для веб-запроса временно проверьте ini_get("curl.cainfo") и ini_get("openssl.cafile") через закрытую страницу; удалите её после диагностики.
- Проверьте цепочку удалённого узлаУ администратора удалённого сервиса запросите корректную полную цепочку сертификатов. Если вы администрируете адресат, проверьте, что настроен fullchain, имя узла совпадает с SAN, сертификат не истёк, промежуточные сертификаты доступны. Не устанавливайте чужой самоподписанный CA без проверки подлинности.
- Проверьте доверенные CA и параметры cURLНа Debian/Ubuntu доверенные CA обычно предоставляет пакет ca-certificates; в контейнере/образе может быть отдельное хранилище. Если curl.cainfo указывает на старый путь, сверяйте существование файла и содержимое. Не загружайте случайный сертификат с форума.
- Исправьте конфигурацию на тестовой копииОбновите штатный пакет сертификатов средствами поддерживаемой ОС либо укажите проверенный CA bundle для curl.cainfo. Сохраните исходный параметр. Для клиентского подключения через корпоративный прокси запросите доверенную цепочку у администратора организации.
- Повторите запрос и оставьте проверку TLS включённойСначала проверьте HTTPS командой без -k, затем действующий PHP-запрос. Убедитесь, что CURLOPT_SSL_VERIFYPEER=true и CURLOPT_SSL_VERIFYHOST=2, код ошибки стал нулевым, а HTTP-ответ ожидаемым. При повторении откатите изменение и сравните различия окружения CLI/FPM.
#Как проверить результат
Правильный признак — успешная проверка подлинности сертификата и ожидаемый ответ при сохранённой проверке TLS, а не исчезновение ошибки после отключения защиты.
#Если не помогло
При ошибке 60 просмотрите CA и цепочку; при 35 — протоколы, шифры и прокси; при 28 — сеть и тайм-ауты. Если сбой только для одного API, передайте администратору API безопасные сведения о цепочке и времени.