【问题标题】:Net::SSLeay gets ":SSL3_GET_SERVER_CERTIFICATE:certificate verify failed" failure when accessing pop.gmail.com, as seen by so many othersNet::SSLeay 在访问 pop.gmail.com 时出现“:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed”失败,正如许多其他人所看到的那样
【发布时间】:2020-07-13 22:32:54
【问题描述】:

我有一个 perl 脚本,它使用 CPAN Mail::Box::POP3s 包从 pop.gmail.com:995 下载电子邮件。执行此操作的源代码是:

   my $pop = Mail::Box::POP3s->new(username => $recordsUser,
          password => $recordsPassword,
          server_name => $pop3Server);
   my($nrOfMsgs) = $pop->nrMessages;
   print "Received $nrOfMsgs\n";

在一个 Windows 10 系统上,这可以完美运行。 但另一方面它失败了,签名:

DEBUG: .../IO/Socket/SSL.pm:1890: new ctx 76411024
DEBUG: .../IO/Socket/SSL.pm:393: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:395: socket connected
DEBUG: .../IO/Socket/SSL.pm:413: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:443: using SNI with hostname pop.gmail.com
DEBUG: .../IO/Socket/SSL.pm:479: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:1359: SSL connect attempt failed with unknown error

DEBUG: .../IO/Socket/SSL.pm:485: fatal SSL error: SSL connect attempt failed with unknown error error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
DEBUG: .../IO/Socket/SSL.pm:1924: free ctx 76411024 open=76411024
DEBUG: .../IO/Socket/SSL.pm:1932: OK free ctx 76411024
ERROR: Cannot connect to pop.gmail.com:995 for POP3: Bad file descriptor
ERROR: Cannot create POP3 client for inbox.
Can't call method "nrMessages" on an undefined value at ./emailToNotes.pl line 110.

这两个系统都运行带有 Active Perl 5.16.3 的 Windows10 Pro(截至 2019 年更新)。 在有效的系统上,我有: IO::Socket::SSL 版本 1.84 Net::SSLeay 1.52 版 OpenSSL 1.02 版 在失败的系统上,我有: IO::Socket::SSL 版本 1.962 Net::SSLeay 1.55 版 Openssl 版本 1.1.1d 查看网络上所有先前提到的这种错误综合症,我尝试了: - 修补 IO::Socket::SSL 以将 $can_client_sni 设置为 0 - 从https://curl.haxx.se/ca/cacert.pem 下载受信任的 CA 链,并通过调用 Net::SSLeay::X509_STORE_add_crl 将其添加到 Net::SSLeay 这些都不能解决问题。 两个系统的 Windows 10 的唯一区别是,工作系统在 2018 年安装了 Windows 10 Pro,而新系统是 2 周前才购买的。 我已经尝试了 2 天不同的解决方案,并且肯定可以从 Steffen Ullrich 等专家那里获得一些帮助。 提前致谢。

【问题讨论】:

  • Net::SSLeay::X509_STORE_add_crl 不会添加任何受信任的证书,但会添加 CRL。此外,还不清楚您在这里使用了哪个 SSL 存储。

标签: perl sockets ssl


【解决方案1】:

首先,请注意您所使用的软件有些部分已经过时了。 IO::Socket::SSL 和 Net::SSleay 的版本已有 7 年历史,并且在这些年中进行了很多改进。有趣的是,尽管您的 OpenSSL 版本似乎更新了很多,而且您还在运行 Windows 10,这表明最近的软件和非常旧的软件出现了奇怪的混合。

您在一台机器上使用的 IO::Socket::SSL 版本 1.84 默认情况下不会验证证书,因此即使证书有问题也可以正常工作。另一台机器上使用的 1.962 版本坚持默认验证证书。这意味着两台机器实际上可能存在与证书相关的相同问题,但您只会在一台机器上注意到它。

不幸的是,Mail::POP3Client(自 7 年以来不受支持)无法设置使用哪个信任存储,而是依赖于系统上正确设置的信任存储。 Windows 上的 OpenSSL(Perl 使用)通常不是这种设置。较新版本的 IO::Socket::SSL 将自动获取信任库 Mozilla::CA(如果已安装但不是您正在使用的旧版本)。

我建议您远离这个旧的软件堆栈。使用较新版本的 IO::Socket::SSL 和 Net::SSLeay 并安装 Mozilla::CA 作为信任库。我建议也使用 Net::POP3 而不是 Mail::POP3Client,因为后者早已不再受支持,而第一个也可以让您更好地控制证书验证。我不确定您正在使用的 ActivePerl,但免费的 Strawberry Perl 通常带有相当新的软件堆栈。

【讨论】:

    【解决方案2】:

    您可以使用以下任一

    use strict;
    use warnings;
    use feature 'say';
    
    use Mail::POP3Client;
    
    my $mail;
    
    $mail->{user}   = 'your_account@gmail.com';
    $mail->{passwd} = 'your_password';
    $mail->{host}   = 'pop.gmail.com';
    
    my $pop = new Mail::POP3Client( 
                                USER     => $mail->{user},
                                PASSWORD => $mail->{passwd},
                                HOST     => $mail->{host},
                                USESSL   => 'true',
                                DEBUG    => 0
                               );
    
    $pop->Connect() or die $pop->Message();
    
    say 'Messages: ' . $pop->Count();
    
    $pop->Close();
    

    或者

    use strict;
    use warnings;
    use feature 'say';
    
    use Mail::POP3Client;
    use IO::Socket::SSL;
    
    $IO::Socket::SSL::DEBUG = 0;  # Level 0..3
    
    my($mail,$ssl);
    
    $mail->{user}   = 'your_account@gmail.com';
    $mail->{passwd} = 'your_password';
    
    $ssl->{host}    = 'pop.gmail.com';
    $ssl->{port}    = 995;
    $ssl->{proto}   = 'tcp';
    
    my $socket = IO::Socket::SSL->new( 
                            PeerAddr => $ssl->{host},
                            PeerPort => $ssl->{port},
                            Proto    => $ssl->{proto}
                        ) || die "No socket!";
    
    my $pop = Mail::POP3Client->new();
    
    $pop->User($mail->{user});
    $pop->Pass($mail->{passwd});
    $pop->Socket($socket);
    
    $pop->Connect() or die $pop->Message();
    
    say 'Messages: ' . $pop->Count();
    
    $pop->Close();
    

    使用 Net::POP3 模块的代码

    use strict;
    use warnings;
    use feature 'say';
    
    use Net::POP3;
    use Data::Dumper;
    
    my $mail;
    
    $mail->{host}   = 'pop.gmail.com';
    $mail->{userid} = 'your_account@gmail.com';
    $mail->{passwd} = 'your_password';
    
    my $pop = Net::POP3->new($mail->{host}, SSL => 1, Timeout => 60);
    
    if ($pop->login($mail->{userid}, $mail->{passwd}) > 0) {
      my $msgnums = $pop->list; # hashref of msgnum => size
      say 'Messages: ' . scalar keys %$msgnums;
    }
    
    $pop->quit;
    

    使用以下模块测试

    cpan -D Mail::POP3Client
    Loading internal logger. Log::Log4perl recommended for better logging
    CPAN: CPAN::SQLite loaded ok (v0.217)
    Database was generated on Thu, 02 Apr 2020 02:48:07 GMT
    Mail::POP3Client
    -------------------------------------------------------------------------
            CPAN: Module::CoreList loaded ok (v5.20200314)
    (no description)
            S/SD/SDOWD/Mail-POP3Client-2.19.tar.gz
            C:\bin\Portable\strawberry-perl\perl\site\lib\Mail\POP3Client.pm
            Installed: 2.19
            CPAN:      2.19  up to date
            Sean Dowd (SDOWD)
            pop3client-USEMYCPANADDRESSFORHELP@dowds.net
    
    
    cpan -D IO::Socket::SSL
    Loading internal logger. Log::Log4perl recommended for better logging
    CPAN: CPAN::SQLite loaded ok (v0.217)
    Database was generated on Thu, 02 Apr 2020 02:48:07 GMT
    IO::Socket::SSL
    -------------------------------------------------------------------------
            (no description)
            S/SU/SULLR/IO-Socket-SSL-2.068.tar.gz
            C:\bin\Portable\strawberry-perl\perl\vendor\lib\IO\Socket\SSL.pm
            Installed: 2.067
            CPAN:      2.068  Not up to date
            Steffen Ullrich (SULLR)
            Steffen_Ullrich@genua.de
    
    
    cpan -D Net::POP3
    Loading internal logger. Log::Log4perl recommended for better logging
    CPAN: CPAN::SQLite loaded ok (v0.217)
    Database was generated on Fri, 03 Apr 2020 03:27:32 GMT
    Net::POP3
    -------------------------------------------------------------------------
            CPAN: Module::CoreList loaded ok (v5.20200314)
    (no description)
            S/SH/SHAY/libnet-3.11.tar.gz
            C:\bin\Portable\strawberry-perl\perl\lib\Net\POP3.pm
            Installed: 3.11
            CPAN:      3.11  up to date
            Steve Hay (SHAY)
            shay@cpan.org
    

    【讨论】:

    • 谢谢。我会尝试这两种解决方案。
    • 我尝试了以下代码` my $pop = new Mail::POP3Client(USER => $recordsUser, PASSWORD => $recordsPassword, HOST => $pop3Server, USESSL => 'true', DEBUG => 1); $pop->Connect() 或死 $pop->Message(); `它以同样的方式失败:`调试:.../IO/Socket/SSL.pm:487:致命的 SSL 错误:SSL 连接尝试失败,出现未知错误错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败`
    • 在我之前的评论中,$pop3Server 是“pop.gmail.com”
    • @BalasubramanianKumar -- 尝试将IO::Socket::SSL 更新为最新版本。 MailPOP3Client DEBUG 选项与IO::Socket::SSL(第二个代码sn-p)相比不太好。尝试第二个代码 sn -p 并打开 DEBUG 选项以获取更多详细信息。
    • @BalasubramanianKumar -- pop.google.com 是正确的服务器 Gmail POP settings
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    相关资源
    最近更新 更多