繁体   English   中英

尝试使用 fsockopen() 连接 SSL 服务器

[英]Trying to connect SSL server using fsockopen()

我正在从本地主机和生产服务器运行下一个脚本,并且得到不同的输出。 任何人都知道为什么我从我的本地主机得到那个false

<?php
$host = 'ssl://mail.companyname.org';
$port = 993;
$error = 0;
$errorString = "";

var_dump(fsockopen($host, $port, $error, $errorString, 30));
var_dump($errorString);
var_dump($error);

本地主机 output:

布尔(假)

生产服务器output:

类型(流)的资源(4)

更新:在评论/回答之后,我修改了代码,现在我在本地主机上得到了这个 output:

PHP Warning: fsockopen(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in /tmp/test.php on line 7 PHP Warning: fsockopen(): Failed to enable crypto in /tmp/test.php on line 7 PHP Warning: fsockopen(): unable to connect to ssl://mail.twmdata.org:993 (Unknown error) in /tmp/test.php on line 7 bool(false ) 字符串(0) "" 整数(0)

似乎这是服务器证书的问题:

首先,您可以通过以下方式检查您的服务器证书及其链是否有效:

https://www.sslshopper.com/ssl-checker.htm

如果 ssl-checker 出了问题?

  • 您可以尝试在companyname.org中更正 SSL 证书配置

    如果你成功并且错误仍然存在?

    1. 您必须手动添加证书文件

如果您有自签名证书:

  1. 您必须手动添加证书文件

如果您没有证书也不关心中间人攻击,您仍然可以在没有证书的情况下使用 SSL。

  1. 关闭php fsock证书检查(不推荐)

建议至少有一个自签名的证书。 如果您有自签名,请尝试1解决方案。

我发现了问题

您在 PHP 警告日志中公开了您的域名,因此我检查了您的域 SSL。

在我使用此工具检查贵公司的域证书后:

https://www.sslshopper.com/ssl-checker.html#hostname=twmdata.org

您的证书有 2 个错误:

  • 此证书已过期(0 天前)。 现在续约。

  • 证书中的所有常用名称均与输入的名称 (twmdata.org) 不匹配。 在 web 浏览器中访问此站点时,您可能会收到错误消息。

所以看来你必须先更新你的证书

证书错误

更新:

我发现这个答案可能有帮助

https://stackoverflow.com/a/40962061/9287628

它建议使用

stream_context_create(['ssl' => [
   'ciphers' => 'RC4-MD5'
]])

正如@ChrisHaas 建议的那样,如果您想指定证书目录或关闭证书检查,则使用stream_context_createstream_socket_client连接会为您带来很多选择。

根据fsockopen文档

functionstream_socket_client()类似,但提供了更丰富的选项集,包括非阻塞连接和提供 stream 上下文的能力。

基本上, fsockopen是非常低级的,但没有很多选项,或者可以说是“合理的默认值”。

相反,您可以切换到stream_socket_client ,这将允许您将context指定为最后一个参数,并且 object 有很多选项,包括一个专用的选项,其中有十几个特定于 SSL 的选项 从这个 function 创建的 object 与fwrite和其他功能兼容,所以它应该做你希望的一切。

$context = stream_context_create([/*Options here*/]);
$connection = stream_socket_client($host, $errno, $errorString, 30, null, $context);

现在,您应该使用哪些选项?

最糟糕的选择可能是verify_peer 我说“最糟糕”是因为您丢弃了 SSL/TLS 的可验证性部分,仅将其用于加密,这样做会使您容易受到中间人攻击。 但是,这是有时间和地点的,因此如果其他选项太复杂,您可以尝试一下。

$context = stream_context_create(['ssl' => ['verify_peer' => false]]);
$connection = stream_socket_client($host, $errno, $errorString, 30, null, $context);

相反,我建议使用cafilecapath做同样的事情,除了前者用于文件,而后者用于目录。

$context = stream_context_create(['ssl' => ['verify_peer' => true, 'cafile' => '/path/to/file']]);
$connection = stream_socket_client($host, $errno, $errorString, 30, null, $context);

你应该使用什么证书? 我们使用这个库来定期拉取最近的 CA 文件,非常方便。 每个项目都有一些设置,但是一旦你得到它,它就会很快。 请参阅以在众所周知的位置提取 CA 文件。

最后一个选项是local_cert ,如果您可以访问它,您可以将其与保存来自服务器的证书和私钥的 PEM 文件一起使用。

编辑

mail.twmdata.org:993上的证书与其他人谈论的 web 服务器的证书不同,这通常是最佳实践。 您可以使用以下命令检查该证书:

openssl s_client -connect mail.twmdata.org:993 -servername mail.twmdata.org

如果你这样做,你会看到服务器有一个自签名证书,你可以通过将verify_peer选项设置为 false 来绕过它。

删除 @ 符号。 您正在隐藏可能会告诉您问题所在的错误消息。 您还应该在 fsockopen() 的 errorno 参数中设置一个变量并回显它以进行调试。

我的猜测是您尚未在本地服务器上安装 PHP 和 SSL 支持。 这里

Companyname.org 也可能会阻止来自本地服务器的、生产服务器允许的请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM