仅在首次尝试时无法建立SSL连接

时间:2014-12-12 15:24:36

标签: php ssl curl openssl certificate

我有一个电子商务网站已经运行了几个月而没有更改代码(并且几年来只对卡处理路径进行了很少的更改)。我现在有一个问题,当第一次打开到信用卡处理器安全服务器的连接时,连接失败。在第二次(或第三次或第四次等)尝试连接成功。经过一段时间 - 也许是5分钟 - 初始连接将再次失败,后续连接将成功。

来自信用卡处理器的PHP API文件的示例代码:

$url = 'https://esplus.moneris.com:443/gateway_us/servlet/MpgRequestArray';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt ($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$dataToSend);
curl_setopt($ch,CURLOPT_TIMEOUT,$gArray[CLIENT_TIMEOUT]);
curl_setopt($ch,CURLOPT_USERAGENT,$gArray[API_VERSION]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);

$response=curl_exec ($ch);

if(!$response) {
    print curl_error($ch);
    print "\n";
    print curl_errno($ch);
    print "\n";
} else {
    print "Success\n";
}

输出:

% php tester_curl.php
error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
35
% php tester_curl.php
Success
% php tester_curl.php
Success
% php tester_curl.php
Success

有一些类似的问题,但我无法解决问题,我没有看到任何相同的错误消息和后续连接尝试在初始失败后成功的症状,例如:

2 个答案:

答案 0 :(得分:1)

服务器有点破碎。它支持TLS1.2和TLS1.0,但不支持TLS1.1(回复TLS1.0即可)。除非您的客户端代码试图通过排除其他协议来强制执行特定协议,否则这通常不是问题。

您描述的行为看起来像客户端降级失败连接上的连接,保持此降级缓存一段时间,但在一段时间后再次使用原始失败版本重试。要追查问题:

  • 检查问题是否也与其他服务器有关
  • 检查其他客户端是否存在同一服务器的问题
  • 检查底层实现。 Curl可以使用GnuTLS,NSS,OpenSSL等等。从错误消息看,它看起来像OpenSSL,但是哪个版本?
  • 检查服务器路径中可能导致问题的任何中间件(防火墙,负载均衡器......)
  • 进行数据包捕获并以可与wireshark(例如cloudshark)一起使用的形式发布在此处

有关如何调试此类问题以及哪些其他信息有用的详细信息,请查看http://noxxi.de/howto/ssl-debugging.html#aid_external_debugging

答案 1 :(得分:0)

我确实发生了使用旧的VirtualMerchant网关的客户端。它在周一下午5点开始失败,并在第二天上午10点再次开始工作。

无论是在命令行上通过openssl,curl,还是通过PHP中的curl,连接都会在第一次失败,然后如果你再运行相同的命令,那么它就会起作用。

我尝试强制使用IPv4(而不是IPv6),设置超时,强制执行不同的协议,降级openssl等,但没有一个能够正常工作。

假设这是DNS和/或服务器在网关端相关的东西,因为我们没有修复它并且它自行修复。

我们运行的是一个只支持TLS 1.1的旧openssl,但它正在运行,然后它再次开始工作,所以它不仅仅是我们的客户端。虽然,我们的客户的年龄一定是问题的一部分,因为其他新客户没有经历过'第一次尝试失败"在同一时间窗口。

长话短说,如果发生这种情况,可能不是你(除了你有一个较旧的OpenSSL)和你可能调用的其他网关/服务器可能需要修复/调整一些东西给它再次开始工作。

请记住,openssl是Linux核心软件包的一部分,因此您无法简单地升级openssl,而不会产生弄乱服务器的严重风险。您必须升级到更新版本的操作系统才能获得更现代化的openssl。