gpt4 book ai didi

PHP stream_socket_client 连接失败

转载 作者:太空宇宙 更新时间:2023-11-03 13:38:15 27 4
gpt4 key购买 nike

我正在尝试通过 php 的 stream_socket_client() 命令联系一个 url,该命令失败了,没有错误代码或消息。这是否使用 openssl、curl 或其他东西?该站点使用 https 并且在 Web 浏览器中运行良好。

enter image description here

当我直接调用 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 相同

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-certificates 并运行 update-ca-certificates。

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.

仍然没有运气......

最佳答案

尽管评论中声明说 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) (或几个)应该揭示哪些位置被用来查找证书。


我缺少一个或多个证书。现在怎么办?

一旦知道缺少哪些证书,就可以下载它们 as shown here ,然后执行任何操作:

  • 将它们连接成一个 PEM 文件(最好是 in order),然后在您尝试连接到您的站点时指定该文件
  • 将它们作为单独的“.crt”文件保存在默认目录中,然后运行c_rehash在该目录上(可能需要 root/sudo)
  • 将它们作为单独的“.crt”文件保存在另一个目录中,并在连接时明确指定为 capath。您可能希望在共享主机上执行此操作,或者如果您不希望所有应用程序都信任证书,则只信任某些证书。

一旦你有了与 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) { /* ... */ }

关于PHP stream_socket_client 连接失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33111851/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com