简体   繁体   English

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

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

I'm running the next script from my local host and the production server, and Im getting different outputs.我正在从本地主机和生产服务器运行下一个脚本,并且得到不同的输出。 Anyone knows why am I getting that false from my localhost?任何人都知道为什么我从我的本地主机得到那个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);

Local host output:本地主机 output:

bool(false)布尔(假)

Production server output:生产服务器output:

resource(4) of type (stream)类型(流)的资源(4)

UPDATE : after the comments/answer I have modified the code and now Im getting this output on my local host:更新:在评论/回答之后,我修改了代码,现在我在本地主机上得到了这个 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) string(0) "" int(0) 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)

it seems this is problem with server certificate:似乎这是服务器证书的问题:

first you can check if your server certificate and its chains are valid by this:首先,您可以通过以下方式检查您的服务器证书及其链是否有效:

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

if somethings were wrong in ssl-checker?如果 ssl-checker 出了问题?

  • you can try to correct SSL certificate configs in companyname.org您可以尝试在companyname.org中更正 SSL 证书配置

    if you succeed and error was persists?如果你成功并且错误仍然存在?

    1. you have to add Certificate files manually .您必须手动添加证书文件

if you have a self-signed certificate:如果您有自签名证书:

  1. you have to add Certificate files manually .您必须手动添加证书文件

if you dont have certificate nor you dont care about man-in-the-middle attack, you can still use SSL without Certificate.如果您没有证书也不关心中间人攻击,您仍然可以在没有证书的情况下使用 SSL。

  1. turn off php fsock Certificate check (not recommended)关闭php fsock证书检查(不推荐)

its recommended to have a certificate at least a self-signed.建议至少有一个自签名的证书。 if you have a self-signed try 1 solution.如果您有自签名,请尝试1解决方案。

I have found the Problem我发现了问题

You have exposed your Domain name in your PHP Warning Log, so i have checked your domain SSL.您在 PHP 警告日志中公开了您的域名,因此我检查了您的域 SSL。

after i check your company`s domain certificate using this tool:在我使用此工具检查贵公司的域证书后:

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

it had 2 errors with your certificates:您的证书有 2 个错误:

  • This certificate has expired (0 days ago).此证书已过期(0 天前)。 Renew now.现在续约。

  • None of the common names in the certificate match the name that was entered (twmdata.org).证书中的所有常用名称均与输入的名称 (twmdata.org) 不匹配。 You may receive an error when accessing this site in a web browser.在 web 浏览器中访问此站点时,您可能会收到错误消息。

so it seems you have to renew your certificate first所以看来你必须先更新你的证书

证书错误

Update:更新:

i have found this answer maybe helpful我发现这个答案可能有帮助

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

it suggested to use它建议使用

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

as @ChrisHaas suggested connecting with stream_context_create and stream_socket_client brings you a lot of option if you want to dictate the cert directory or you want to turn off certificate check.正如@ChrisHaas 建议的那样,如果您想指定证书目录或关闭证书检查,则使用stream_context_createstream_socket_client连接会为您带来很多选择。

Per the documentation for fsockopen根据fsockopen文档

The functionstream_socket_client() is similar but provides a richer set of options, including non-blocking connection and the ability to provide a stream context. functionstream_socket_client()类似,但提供了更丰富的选项集,包括非阻塞连接和提供 stream 上下文的能力。

Basically, fsockopen is very low-level but without many options, or, arguably, "sane defaults".基本上, fsockopen是非常低级的,但没有很多选项,或者可以说是“合理的默认值”。

Instead, you can switch to stream_socket_client which will allow you to specify a context as the last parameter, and that object has many options, including a dedicated one with over a dozen options specific to SSL .相反,您可以切换到stream_socket_client ,这将允许您将context指定为最后一个参数,并且 object 有很多选项,包括一个专用的选项,其中有十几个特定于 SSL 的选项 The object created from this function is compatible with fwrite and other functions, so it should do everything you are hoping for.从这个 function 创建的 object 与fwrite和其他功能兼容,所以它应该做你希望的一切。

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

Now, what options should you use?现在,您应该使用哪些选项?

The worst option that might work is probably verify_peer .最糟糕的选择可能是verify_peer I say "worst" because you are throwing away the verifiability part of SSL/TLS and only using it for encryption, and doing this will make you susceptible to MitM attacks.我说“最糟糕”是因为您丢弃了 SSL/TLS 的可验证性部分,仅将其用于加密,这样做会使您容易受到中间人攻击。 However, there's a place and time for this, so you could try it if the other options are too complicated.但是,这是有时间和地点的,因此如果其他选项太复杂,您可以尝试一下。

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

Instead, I'd recommend using either cafile or capath which do the same thing except the former is for a file while the latter is for a directory.相反,我建议使用cafilecapath做同样的事情,除了前者用于文件,而后者用于目录。

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

What certs should you use?你应该使用什么证书? We use this library to pull in recent CA files on a periodic basis, very convenient.我们使用这个库来定期拉取最近的 CA 文件,非常方便。 There's a little bit of setup that's per-project but once you get it it goes pretty fast.每个项目都有一些设置,但是一旦你得到它,它就会很快。 See this for pulling in a CA file at a well-known location.请参阅以在众所周知的位置提取 CA 文件。

One other last option is local_cert which you can use with a PEM file that holds the certificate and private key from the server, if you have access to that.最后一个选项是local_cert ,如果您可以访问它,您可以将其与保存来自服务器的证书和私钥的 PEM 文件一起使用。

EDIT编辑

The cert on mail.twmdata.org:993 is different than the web server's cert that other people are talking about, which is generally a best practice. mail.twmdata.org:993上的证书与其他人谈论的 web 服务器的证书不同,这通常是最佳实践。 You can inspect that cert using:您可以使用以下命令检查该证书:

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

If you do that, you'll see that the server has a self-signed cert which you can get around by setting the verify_peer option to false.如果你这样做,你会看到服务器有一个自签名证书,你可以通过将verify_peer选项设置为 false 来绕过它。

Remove the @ symbol.删除 @ 符号。 You are hiding error messages that might tell you what the problem is.您正在隐藏可能会告诉您问题所在的错误消息。 You should also set a variable in the errorno argument to fsockopen() and echo it for debugging.您还应该在 fsockopen() 的 errorno 参数中设置一个变量并回显它以进行调试。

My guess would be that you haven't installed PHP with SSL support on your local server.我的猜测是您尚未在本地服务器上安装 PHP 和 SSL 支持。 See here .这里

Companyname.org might also block requests from your local server that are allowed from the production server. Companyname.org 也可能会阻止来自本地服务器的、生产服务器允许的请求。

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

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