簡體   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