01 октября 2021 года я столкнулся с проблемой — в проекте на WordPress и PHP 7.0 перестали работать все скрипты, которые получают что-то из вне по https с помощью file_get_contents и wp_remote_get. C wp_remote_get все получилось решить просто:
1 |
wp_remote_get($url, ['sslverify' => false ]); |
Но из используемой функции
file_get_contents с проблемой пришлось разбираться чуть более основательно.
В логах nginx ошибка file_get_contents(): Failed to enable crypto in
На все запросы через https. Полностью ошибка выглядела примерно так:
1 2 3 4 5 6 7 8 9 10 11 |
SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate file_get_contents(): Failed to enable crypto in error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /home/web/azzrael.ru/subscribe-azzrael-code-youtube.php on line 2 PHP message: PHP Warning: file_get_contents(): Failed to enable crypto in /home/web/azzrael.ru/subscribe-azzrael-code-youtube.php on line 2 PHP message: PHP Warning: file_get_contents([https://www.youtube.com/channel/UCf6kozNejHoQuFhBDB8cfxA.jpg](https://www.youtube.com/channel/UCf6kozNejHoQuFhBDB8cfxA.jpg)): failed to open stream: operation failed in /home/web/azzrael.ru/subscribe-azzrael-code-youtube.php on line 2 PHP message: PHP Fatal error: Uncaught Exception: cant get file in /home/web/azzrael.ru/subscribe-azzrael-code-youtube.php:3 Stack trace: #0 {main} thrown in /home/web/azzrael.ru/subscribe-azzrael-code-youtube.php on line 3" while reading response header from upstream, client: 8.8.8.8, server: [azzrael.ru](http://azzrael.ru/), request: "GET /subscribe-azzrael-code-youtube.php HTTP/2.0", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "[azzrael.ru](http://azzrael.ru/)" |
Упоминание OpenSSL и ssl3_get_server_certificate вместе сразу дало направление на гугление в сторону проблем с сертификатами. Так и оказалось.
Истечение корневых сертификатов Lets Encrypt
Вероятно сама проблема связана с истечением 30 сентября 2021 года корневых сертификатов Lets Encrypt. Возможно, также что проблема связана с версией PHP — на проекте используется довольно устаревшая PHP 7.0.
Решение проблемы
Есть несколько способов решения. Т.к. проблема касалась нескольких сайтов на сервере и имелся полный доступ к управлению сервером то я сделал следующее:
- Пошел на https://curl.se/docs/caextract.html
- Скачал cacert.pem
- Положил cacert.pem в /etc/ssl/certs/cacert.pem
Затем в php.ini в раздел openssl прописал следующее:
1 2 |
[openssl] openssl.cafile=/etc/ssl/certs/cacert.pem |
Перезагрузил php
service php7.0-fpm restart и проблема исчезла.
Рано или поздно и этот сертификат протухнет. Но, судя по https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt серт полученный в 2021 протухнет в 2028. Это приемлимо.