我试图通过php的stream_socket_client()命令联系一个url,该命令没有错误代码或msg就失败了。这是使用openssl、curl还是其他什么的吗?该站点使用https,并在web浏览器上运行良好。

当我直接调用openssl时,它会连接起来,但与我的证书链没有关联。
root@drupal7 drupal7/includes# openssl s_client -connect test.cgps.org:443
CONNECTED(00000003)
Verify return code: 21 (unable to verify the first certificate)卷曲也一样
curl https://test.cgps.org/?q=/admin/config/search/clean-urls/check
curl: (60) SSL certificate problem: unable to get local issuer certificate因此,我认为我需要将中间证书安装到Linux中,这是通过将Apache使用的中间证书放入/usr/local/share/ca证书和运行update证书来实现的。
root@drupal7 drupal7/includes# update-ca-certificates
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.还是没有运气..。
发布于 2018-02-06 12:08:16
尽管在评论中发表了一项声明,称PHP的steam_socket_client()太低而不关心证书,但我知道确实关心,因为我观察到它在标准位置缺少一些证书的系统上返回false,在那里提供流上下文(告诉它在哪里查找证书)阻止了这种情况的发生。
令人沮丧的是,在您修复这个问题之前,$errno可以保持为0,所以最好先使用另一个工具检查证书颁发机构目录。
诊断
通过curl
要使用curl,通常可以通过添加--verbose标志来了解发生了什么。这将告诉您正在使用哪些连接的证书PEM文件(CAfile/cacert)和CA-目录(capath) (如果有的话)。在输出的顶部,您将得到如下内容:
[...]
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: /home2/wynddorg/private_html/trusted_roots
[...]一旦您知道这些是默认的,您可以调整您的系统配置,或者简单地添加--cacert <concatenated_cert_path>标志或--capath <c_rehash'd_directory>,或者同时添加两者。
通过openssl s_client
使用s_client要复杂一些;您可能可以访问它的-trace选项,这取决于您的版本以及它是如何编译的,但是请尝试:
strace -e open,stat openssl s_client -connect test.cgps.org:443 [-CApath <dir>]
# this trick provided by the amazing xemdetia in irc://freenode/%23%23openssl在CONNECTED(00000003)消息之后大约5行,您应该会看到一个open("...", O_RDONLY) (或几行),它应该显示用于查找证书的位置。
我错过了一个或多个证书。这次又是什么?
一旦您知道丢失了哪些证书,就可以下载它们如图所示,然后执行以下操作:
c_rehash (可能需要root/sudo)一旦您使用了openssl s_client或curl或两者,您就可以指定如下相同的选项:
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'cafile', <concatenated_cert_file_path>);
stream_context_set_option($context, 'ssl', 'capath', <c_rehashed_cert_dir_path>);
// You only really need to provide one of the two options above. Using capath is
// faster, but this only matters if you'll be making a huge number of
// connections.
$ssc = stream_socket_client(
'ssl://subdomain.example.com:443',
$errno,
$errstr,
30,
STREAM_CLIENT_CONNECT,
$context
);
if ($ssc) { /* ... */ }https://stackoverflow.com/questions/33111851
复制相似问题