【问题标题】:how to fix stream_socket_enable_crypto(): SSL operation failed with code 1如何修复 stream_socket_enable_crypto():SSL 操作失败,代码为 1
【发布时间】:2015-08-13 22:12:30
【问题描述】:
stream_socket_enable_crypto(): SSL operation failed with code 1. 
OpenSSL Error messages: error:14090086:SSL 
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

我正在使用 Laravel 4.2、PHP 5.6、Apache 2.4

我在 Amazon ec2 Linux 中安装了 GoDaddy SSL。

当我使用 https 访问该站点时,SSL 工作正常。

当我调用我的函数时发生错误:

<?php

public function sendEmail() 
{
        \Mail::send ( 'emails.code.code', $data, function ($sendemail) use($email) {
            $sendemail->from ( 'info@me.com', 'Me Team' );
            $sendemail->to ( $email, '' )->subject ( 'Activate your account' );
        } );

}
?>

我读了一些关于这个的文章,他们说有些事情我们应该做一些改变,他们放了那个代码但我不知道在哪里插入它。

正在阅读:https://www.mimar.rs/en/sysadmin/2015/php-5-6-x-ssltls-peer-certificates-and-hostnames-verified-by-default/

还有这个phphttp://php.net/manual/en/migration56.openssl.php的文档很难理解。

所以我的问题是如何解决这个问题?

【问题讨论】:

标签: php laravel amazon-ec2 ssl-certificate apache2.4


【解决方案1】:

尝试更改app/config/email.php

smtpmail

【讨论】:

  • Laravel 框架问题,更改协议已删除问题。
  • 现在它没有抛出错误,但在将其更改为“邮件”后,我没有收到邮件,而是显示为在我的应用程序中发送的邮件,可能是什么问题?
  • 改成mail直接从服务器发送邮件,而不是连接到smtp服务器!
  • 这是一个非常糟糕的答案,因为它没有描述此更改的后果。当通过 SMTP 发送电子邮件时,laravel 登录到您的服务器并代表您发送和发送电子邮件。如果您将其更改为“邮件”,它将通过 PHP 邮件发送邮件,这意味着它将受到更高的垃圾邮件评分,因为 PHP 本质上是在欺骗电子邮件。如果需要,您可以使用 PHP 邮件从 bill@microsoft.com 发送电子邮件。但他们可能最终会成为垃圾邮件。更多信息在这里。 jvfconsulting.com/blog/…
  • 关于电子邮件欺骗,这就是为什么有SPF和DKIM记录的原因,与PHP或其他东西是否发送电子邮件无关。如果您的域设置正确,则只要您使用正确的域,通过 SMTP 或 PHP 发送它是平等的。
【解决方案2】:

编者注:禁用 SSL 验证具有安全隐患。如果不验证 SSL/HTTPS 连接的真实性,恶意攻击者可以冒充受信任的端点(例如 Gmail),您将容易受到 Man-in-the-Middle Attack 的攻击。

在将其用作解决方案之前,请确保您完全了解安全问题。

我在 laravel 4.2 中也有这个错误,我是这样解决的。找出StreamBuffer.php。对我来说,我使用 xampp,我的项目名称是 itis_​​db,因为我的路径是这样的。所以试着根据你的来找

C:\xampp\htdocs\itis_​​db\vendor\swiftmailer\swiftmailer\lib\classes\Swift\Transport\StreamBuffer.php

在StreamBuffer.php中找出这个函数

private function _establishSocketConnection()

并将这两行粘贴到这个函数中

$options['ssl']['verify_peer'] = FALSE;
$options['ssl']['verify_peer_name'] = FALSE;

并重新加载您的浏览器并尝试再次运行您的项目。对我来说,我是这样穿的:

private function _establishSocketConnection()
{
    $host = $this->_params['host'];
    if (!empty($this->_params['protocol'])) {
        $host = $this->_params['protocol'].'://'.$host;
    }
    $timeout = 15;
    if (!empty($this->_params['timeout'])) {
        $timeout = $this->_params['timeout'];
    }
    $options = array();
    if (!empty($this->_params['sourceIp'])) {
        $options['socket']['bindto'] = $this->_params['sourceIp'].':0';
    }
    
   $options['ssl']['verify_peer'] = FALSE;
    $options['ssl']['verify_peer_name'] = FALSE;

    $this->_stream = @stream_socket_client($host.':'.$this->_params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, stream_context_create($options));
    if (false === $this->_stream) {
        throw new Swift_TransportException(
            'Connection could not be established with host '.$this->_params['host'].
            ' ['.$errstr.' #'.$errno.']'
            );
    }
    if (!empty($this->_params['blocking'])) {
        stream_set_blocking($this->_stream, 1);
    } else {
        stream_set_blocking($this->_stream, 0);
    }
    stream_set_timeout($this->_stream, $timeout);
    $this->_in = &$this->_stream;
    $this->_out = &$this->_stream;
}

希望你能解决这个问题.....

【讨论】:

  • 这对我有用,但有没有其他方法可以在不接触供应商代码的情况下解决这个问题?
  • 投反对票,因为您不应该编辑供应商代码。首先,您将放弃任何作曲家更新的所有更改。其次 - 供应商没有(也不应该)被添加到控制版本中,因此团队中的任何人都不会得到这个更改。更好的方法是创建自己的类来扩展现有的供应商类。
  • 它对我来说真的很好用。但是有没有办法不接触供应商代码?
  • 您好,我在使用 gmail 发送电子邮件时遇到问题,但通过添加您提供的两行代码已经解决了。你能告诉我为什么我必须放这两行代码吗?
【解决方案3】:

编者注:禁用 SSL 验证具有安全隐患。如果不验证 SSL/HTTPS 连接的真实性,恶意攻击者可以冒充受信任的端点(例如 Gmail),您将容易受到 Man-in-the-Middle Attack 的攻击。

在将其用作解决方案之前,请确保您完全了解安全问题。

对此的简单修复可能是编辑 config/mail.php 并关闭 TLS

'encryption' => env('MAIL_ENCRYPTION', ''), //'tls'),

基本上就是这样做

$options['ssl']['verify_peer'] = FALSE;
$options['ssl']['verify_peer_name'] = FALSE;

您也应该放松安全性,但在第一个选项中,无需深入研究供应商的代码。

【讨论】:

【解决方案4】:

阅读app/config/mailphp

Supported : "smtp", "mail", "sendmail"

根据您机器上安装的邮件实用程序,填写驱动程序密钥的值。我会做的

'driver' => 'sendmail',

【讨论】:

    【解决方案5】:

    编者注:禁用 SSL 验证具有安全隐患。如果不验证 SSL/HTTPS 连接的真实性,恶意攻击者可以冒充受信任的端点(例如 Gmail),您将容易受到 Man-in-the-Middle Attack 的攻击。

    在将其用作解决方案之前,请确保您完全了解安全问题。

    您可以在 /config/mail.php 中添加以下代码(在 laravel 5.1、5.2、5.4 上测试和工作)

    'stream' => [
       'ssl' => [
          'allow_self_signed' => true,
          'verify_peer' => false,
          'verify_peer_name' => false,
       ],
    ],
    

    【讨论】:

    • 我在 .env 文件中添加了以下代码,加上您提出的更改,现在它正在工作(我使用的是 laravel 5.3),感谢 o/ MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail。 com MAIL_PORT=587 MAIL_USERNAME=test@gmail.com MAIL_PASSWORD=密码 MAIL_ENCRYPTION=tls
    • 你太棒了
    • 请注意,这对于测试服务器来说是可以的,但不应该在生产环境中使用,因为它不安全。
    • 这对我有用,但请注意,这仅适用于测试服务器。上线时,您需要安全设置
    • 在 Laravel 7.x 中,配置移动到mail.mailers.smtp.stream
    【解决方案6】:

    要解决此问题,您首先需要检查您要连接的主机的 SSL 证书。例如使用ssllabsother ssl tools。就我而言,中间证书是错误的。

    如果证书正常,请确保您服务器上的 openSSL 是最新的。运行openssl -v 以检查您的版本。也许您的版本太旧了,无法使用证书。

    在极少数情况下,您可能希望禁用 ssl 安全功能,例如 verify_peer、verify_peer_name 或 allow_self_signed。请对此非常小心,并且切勿在生产中使用它。这只是临时测试的一个选项。

    【讨论】:

      【解决方案7】:

      对于 Laravel 5.4
      gmail


      .env 文件中

      MAIL_DRIVER=mail
      MAIL_HOST=mail.gmail.com
      MAIL_PORT=587
      MAIL_USERNAME=<username>@gmail.com
      MAIL_PASSWORD=<password>
      MAIL_ENCRYPTION=tls
      

      config/mail.php

      'driver' => env('MAIL_DRIVER', 'mail'),
      
      'from' => [
          'address' => env(
              'MAIL_FROM_ADDRESS', '<username>@gmail.com'
          ),
          'name' => env(
              'MAIL_FROM_NAME', '<from_name>'
          ),
      ],
      

      【讨论】:

        【解决方案8】:

        在我的情况下,我做了以下

        $mail = new PHPMailer;
        $mail->isSMTP();            
        $mail->Host = '<YOUR HOST>';
        $mail->Port = 587;
        $mail->SMTPAuth = true;
        $mail->Username = '<USERNAME>';
        $mail->Password = '<PASSWORD>';
        $mail->SMTPSecure = '';
        $mail->smtpConnect([
            'ssl' => [
                'verify_peer' => false,
                'verify_peer_name' => false,
                'allow_self_signed' => true
            ]
        ]);
        $mail->smtpClose();
        
        $mail->From = '<MAILFROM@MAIL.COM>';
        $mail->FromName = '<MAIL FROM NAME>';
        
        $mail->addAddress("<SENDTO@MAIL.com>", '<SEND TO>');
        
        $mail->isHTML(true);
        $mail->Subject= '<SUBJECTHERE>';
        $mail->Body =  '<h2>Test Mail</h2>';
        $isSend = $mail->send();
        

        【讨论】:

        • 它实际上对我有帮助,因为 Codeigniter 4 自己的库无法做到这一点。
        【解决方案9】:
        $default = [ ... ];
        
        $turnOffSSL = [
            'stream' => [
                'ssl' => [
                    'allow_self_signed' => true,
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                ],
            ],
        ];
        
        $environment = env('APP_ENV');
        
        if ($environment === 'local') {
            return array_merge($default, $turnOffSSL);
        }
        
        return $default;
        

        【讨论】:

          【解决方案10】:

          编辑您的 .env 并在邮件配置行之后添加此行

          MAIL_ENCRYPTION=""
          

          保存并尝试发送电子邮件

          【讨论】:

            【解决方案11】:

            如何修复 Laravel(至少 5、6、7)、WordPress(以及我猜想的其他 PHP + cURL 实现):

            cURL website下载最新的cacert.pem文件。

            wget https://curl.haxx.se/ca/cacert.pem
            

            编辑php.ini(您可以通过php --ini 找到它),更新(如果它们不存在则创建)这两行:

            curl.cainfo="/path/to/downloaded/cacert.pem"
            ...
            openssl.cafile="/path/to/downloaded/cacert.pem"
            

            这些行应该已经存在但被注释掉了,所以取消注释它们并使用下载的cacert.pem的路径编辑这两个值

            重启 PHP 和 Nginx/Apache。

            编辑:您可能需要chown/chmod 下载的证书文件,以便 PHP(以及运行它的用户)可以读取它。

            source

            【讨论】:

            • 是否有自动化的方式来保持最新状态?每隔几个月就要手动更新一次,不知道什么时候更新。
            • 我猜你可以每月做一次 CRON 来更新文件,并重新加载相关服务。我不知道有什么工具可以自动维护它。
            【解决方案12】:

            终于!这是我的 AVG 防病毒软件,它有一个称为电子邮件屏蔽的功能,将其禁用,错误就消失了。

            【讨论】:

              【解决方案13】:

              这开始发生在我的一台服务器上,它使用 wordpress 和一个使用 PHPMailer 的插件,最近没有任何变化。

              解决办法:sudo yum install ca-certificates

              现在它再次完美运行,我还重新启动了 httpd(不确定是否需要)

              我无法弄清楚真正的问题,我怀疑这是旧 ca-certificates 包中的硬编码日期。

              【讨论】:

              • 我运行了相同的命令并重新启动,但对我来说不是固定的。我正在运行 centos 7.9
              【解决方案14】:

              将加密类型从 SSL 更改为 TLS 对我有效。

              【讨论】:

                猜你喜欢
                • 2015-01-21
                • 2017-11-09
                • 2018-03-07
                • 2015-04-27
                • 2013-08-25
                • 1970-01-01
                • 2020-10-20
                • 2021-05-14
                • 1970-01-01
                相关资源
                最近更新 更多