PHP流包装程序和带有证书的Windows证书存储

时间:2019-12-11 13:30:28

标签: php windows https ssl-certificate guzzle

设置/环境:

在我们的PHP应用程序中,有时我们需要从PHP向其他服务器发出HTTPS请求。有问题的设置如下:

  • 我们正在使用PHP流包装器执行HTTP请求(使用Guzzle HTTP)。我们之所以这样做,是因为流包装器支持使用Windows Certficiate Store进行证书验证。
  • 服务器在Windows上运行。
  • 我们对HTTPS请求使用代理。
  • 将防火墙配置为允许
    1. 访问我们正在处理请求的服务器。
    2. 访问与使用的证书相关的所有证书吊销列表。

我们的问题

有时候,我们的HTTPS请求有时会失败,并出现证书验证错误。这个问题一直存在,直到有人打开到服务器的远程桌面会话并请求我们尝试在服务器Internet Explorer中查询的相同URL。之后,我们的PHP应用程序可以按需执行其请求。

问题:

这是什么问题?而我们可以做些什么来进一步分析呢?

3 个答案:

答案 0 :(得分:2)

如果这是一个大问题,那么每次都会发生。

但是,请尝试使用cURL发出相同的HTTPS调用,以验证是否是这种情况,并查看cURL请求是否也可以像Internet Explorer一样暂时清除问题。

但是,这看起来像是一个缓存问题-PHP服务器请求无法正确访问(启动证书)证书存储,它只能在某人之后使用其服务否则,其他人就已经获得了访问权限,并且前提是缓存没有过期。为确保确实如此,只需定期发出呼叫并标记用户登录和使用IE之间的时间间隔,然后Guzzle呼叫就会开始失败。如果我是对的,那时间将永远相同。

这可能是一个权限问题(我想它可能是 is ,但是要赋予什么权限,我很茫然地猜测)。除非获得该URL的最新CRL,而PHP无法获取它们,否则可能不允许调用。也可以通过在错误情况下通过从PHP启动的PowerShell脚本运行IE连接尝试到相同URL的IE连接尝试来暂时解决这种情况,或者(更可能且希望如此)尝试运行所述脚本会引发一些更多有用的错误消息

更新

我研究了Windows上的PHP如何通过Guzzle处理TLS,但没有发现明显的问题。但是我发现了an interesting page about TLS/SSL quirks

更有趣的是,我还发现了一些参考资料,说明PHP最终如何使用Schannel进行TLS连接,以及Windows以及特别是Internet Explorer如何对互操作性持谨慎态度。因此,我建议您尝试activating the Schannel log on Windows,看看是否有任何结果。

此外,在链接的页面上,有对正在使用的客户端缓存的引用,相关页面的结尾为here(“ ClientCacheTime”)。

答案 1 :(得分:1)

这不是应用程序问题。

我99%确信这是路由问题,并且在某些情况下,数据包会在路由器中丢失。我将研究网络,更改环境,或者在可能的情况下进行一些网络嗅探或监视。

如果您的网络基础设施不错,则可以进行SNPM陷阱以收集请求计数和超时数据(从路由器和交换机),并将其提取到Elastic APM中。这将为您提供非常详细的时间序列分析。

答案 2 :(得分:1)

您可以看到这是https://github.com/guzzle/guzzle/issues/394 verify的问题。并且如果您将verify设置为false,则会使您的系统受到的安全攻击。

// Use the system's CA bundle (this is the default setting)
$client->request('GET', '/', ['verify' => true]);

// Use a custom SSL certificate on disk.
$client->request('GET', '/', ['verify' => '/path/to/cert.pem']);

// Disable validation entirely (don't do this!).
$client->request('GET', '/', ['verify' => false]);

这些是Request Options,您可以看到如何进行SSL证书验证。他们将问题描述为以下

  

并非所有系统在磁盘上都具有已知的CA捆绑软件。例如Windows   和OS X没有用于CA捆绑包的单一公共位置。什么时候   将“ verify”设置为true,Guzzle会尽力找到最   系统上的适当CA捆绑包。使用cURL或PHP时   PHP版本大于等于5.6的流包装器,默认情况下会发生这种情况。什么时候   在版本低于5.6的版本中使用PHP流包装器,Guzzle尝试查找   您的CA捆绑软件的顺序如下:

     

检查是否在您的php.ini文件中设置了openssl.cafile。

     

检查是否在您的php.ini文件中设置了curl.cainfo。

     

检查/etc/pki/tls/certs/ca-bundle.crt是否存在(Red Hat,CentOS,Fedora;   由ca-certificates软件包提供)

     

检查/etc/ssl/certs/ca-certificates.crt是否存在(Ubuntu,Debian;由   ca-certificates软件包)

     

检查/usr/local/share/certs/ca-root-nss.crt是否存在(FreeBSD;由   ca_root_nss软件包)

     

检查是否/usr/local/etc/openssl/cert.pem(OS X;由自制软件提供)

     

检查C:\ windows \ system32 \ curl-ca-bundle.crt是否存在(Windows)

     

检查C:\ windows \ curl-ca-bundle.crt是否存在(Windows)

     

此查询的结果被缓存在内存中,以便后续的调用可以在同一内存中进行。   过程将很快返回。但是,仅发送一个   请求类似Apache之类的每个进程,您应该考虑   将openssl.cafile环境变量设置为磁盘上的路径   文件,以便跳过整个过程

另请参见和how to ignore invalid ssl certificate errors in-guzzle 5guzzle-request-fails