У меня есть внутренний сервер (внутренний по отношению к моей сети), к которому я делаю вызов REST API с моего внешнего сервера.
Я не знаю, поможет ли это, но на внешнем сервере работает php 5.3.6 с cURL 7.19.7.
Чтобы сделать его более безопасным (кроме окна брандмауэра, которое ограничивает внешние IP-адреса, которые могут вызывать мой внутренний сервер, только статическим IP-адресом моего внешнего сервера), я сгенерировал самоподписанный сертификат сервера SSL для моего внутреннего сервера.
Я также создал сертификат клиента, который будет использоваться моим внешним сервером при выполнении вызовов.
Вызовы выполняются с использованием библиотеки cURL PHP. Страница, на которой совершаются звонки, выглядит так (эта страница была создана как «доказательство концепции», чтобы увидеть, что звонок действительно может быть сделан):
<?php
$mycurl = curl_init();
$verbose = fopen('curl_error_log','a');
$url_site = 'https://internal.server.com/api_test.php';
$options = array(
CURLOPT_HEADER => false
,CURLOPT_RETURNTRANSFER => true
,CURLOPT_VERBOSE => true
,CURLOPT_STDERR => $verbose
,CURLOPT_HTTPHEADER => array('Accept: application/json')
,CURLOPT_CAINFO => realpath('/certs/server/certs.pem')
,CURLOPT_CAPATH => realpath('/certs/server')
,CURLOPT_SSL_VERIFYPEER => true
,CURLOPT_SSL_VERIFYHOST => 2
,CURLOPT_SSLCERT => realpath('/certs/client.crt.pem')
,CURLOPT_SSLKEY => realpath('/certs/client.key.pem')
,CURLOPT_SSLCERTTYPE => 'PEM'
,CURLOPT_URL => $url_site
);
curl_setopt_array($mycurl, $options);
$webResponse = curl_exec($mycurl);
fclose($verbose);
?>
<html>
<head>
<title></title>
</head>
<body>
<p>Error: <?php echo curl_error($mycurl); ?></p>
<p>Error no.: <?php echo curl_errno($mycurl); ?></p>
<p>Result: <?php echo $webResponse; ?></p>
</body>
</html>
ПРИМЕЧАНИЕ. предыдущая версия этого "доказательства концепции" без использования клиентского сертификата прекрасно работала. В этой версии для параметров CURLOPT_VERIFYPEER и CURLOPT_VERIFYHOST было задано значение FALSE, а для всех SSL... и CA ... варианты отсутствовали.
Страница возврата выглядит так:
Error: SSL read: errno -12195
Error no.: 56
Result:
И подробный файл (curl_error_log) имеет это:
* About to connect() to internal.server.com port 443 (#0)
* Trying 111.222.333.444... * connected
* Connected to internal.server.com (111.222.333.444) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /certs/server/certs.pem
CApath: /certs/server
* SSL connection using TLS_DHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate:
* subject: CN=internal.server.com,OU=BI,O=ABC Corp,L=City,ST=State,C=CO
* start date: Apr 13 15:15:38 2015 GMT
* expire date: Apr 12 15:15:38 2016 GMT
* common name: internal.server.com
* issuer: CN=internal.server.com,OU=BI,O=ABC Corp,L=City,ST=State,C=CO
> GET /api_test.php HTTP/1.1
Host: internal.server.com
Accept: application/json
* NSS: client certificate from file
* subject: CN=internal.server.com,OU=BI,O=ABC Corp,L=City,ST=State,C=CO
* start date: Apr 13 15:26:48 2015 GMT
* expire date: Apr 12 15:26:48 2016 GMT
* common name: internal.server.com
* issuer: CN=internal.server.com,OU=BI,O=ABC Corp,L=City,ST=State,C=CO
* SSL read: errno -12195
* Closing connection #0
Любые идеи о том, что я делаю неправильно или чего не хватает? Почему я получаю эту ошибку?
EDIT: я пытался играть с CURLOPT_SSLVERSION =>. Сначала я установил значение 3, и ошибка немного изменилась. Я все еще получил точно такой же подробный вывод, но ближе к низу, где он читается как «SSL read: errno -12195», он стал «SSL read: errno -12271» .
Затем я меняю версию на 2, и раньше она вылетала, выдавая мне "Ошибка NSS -12268" в строке 6 подробного вывода.
Наконец, когда я попробовал 4 или 5, подробный файл был точно таким же, как и выше.
Спасибо.