В Php для доступа к сайтам по http, https, FTP часто используется библиотека curl.
На практике, однако, наиболее часто используется протокол, HTTP особенно при соединении server-to-server . Curl же используется при таких методах доступа как
XML-RPC или REST для запроса ресурса. Либо же если производится соединение с сервером посредством какого-либо API. Ну и последним использованием curl в php можно назвать парсинг ресурсов.
Тем не менее, при попытке получить доступ к ресурсу по HTTPS, например, через API, могут возникнуть определенные проблемы в подключении, о которых и пойдет речь.
Основной проблемой при данном соединении с использованием Curl можно назвать невозможность библиотекой проверить недоверенный сертификат сайта. Смоделируем ситуацию.
Предположим мы используем следующий код
// Initialize session and set URL. $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // Set so curl_exec returns the result instead of outputting it. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Get the response and close the channel. $response = curl_exec($ch); curl_close($ch);
Если $url указывает на https ресурс как результат выполнения данного кода мы получим
Failed: Error Number: 60. Reason: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Это происходит потому, что Curl не был настроен доверять HTTPS сертификату сервера.
Понятия сертификаты и PKI вращается вокруг доверия сертификатов (CA), и по умолчанию, Curl настроен не доверять CA, таким образом, он не будет доверять сертификату любого веб-сервера. Так почему же не у нас не возникли проблемы посещения HTTPs сайтов через веб-браузер? Разработчики браузера включают в себя список корневых доверенных центров сертификации, у которых может быть приобретен сертификат сайта.
Таким образом необходимо либо разрешить Curl доверять нашему сертификату, либо запретить проверку доверия к сертификату при использовании библиотеки.
Обратимся к более простому решению – запретим Curl проверять сертификат, фактически настроив на доверие к любому полученному сертификату.
Это не очень верное решение с точки зрения безопасности, но действенно. Для выполнения данной настройки перед вызовом curl curl_exec() достаточно вставить следующую строку
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Это заставляет библиотеку Curl принимать любые сертификаты, но если Вы обеспокоены, что у Вас принимаются все сертификаты без разбора необходимо сделать немного больше действий.
Оговоримся, что будем использовать такой параметр Curl CURLOPT_CAINFO и сертификат, полученный с сайта.
Давайте извлечем сертификат, используя наш броузер.
Откроем сайт и увидим следующую картинку в нижней части броузера.
Нажмем «просмотреть сертификат»
И далее в пункте «Детали» на странице сертификатов выберем наш сертификат. Это доверенный корневой сертификат.
Нам необходимо его экспортировать для дальнейшего использования Curl
Нажмем “Экспорт”, и сохраним наш корневой сертификат как X.509 Certificate (PEM).
Далее нам необходимо модифицировать настройки cURL для использования CA сертификата с параметром CURLOPT_CAINFO, где мы укажем место сохранения сертификата
.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");
Failed: Error Number: 60. Reason: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed