Crypt-SSLeay 无法验证主机名

3
我并不是 Perl 的专家,但由于某些情况,我必须在新的 gentoo 服务器上部署 Perl 脚本。该脚本在其他几个由另一个人配置的服务器上运行良好。因此,在我自己安装的新服务器上,某些软件包具有不同的版本。结果,给定的 Perl 脚本出现了问题: "Net::SSL" 来自 "Crypt-SSLeay" 无法验证主机名;要么安装 "IO::Socket::SSL",要么通过将 "PERL_LWP_SSL_VERIFY_HOSTNAME" 环境变量设置为0来关闭验证。
实际上已经安装了 "IO::Socket::SSL"。 perl -MIO::Socket::SSL -e 'print "$IO::Socket::SSL::VERSION\n"' 2.024 为什么它看不到已安装的模块?在新服务器上我能做什么来解决这个问题而不修改脚本?版本差异很重要吗? 新服务器 Perl 版本:5.24.0 旧服务器 Perl 版本:5.22.1 新服务器: perl -v This is perl 5, version 24, subversion 0 (v5.24.0) built for x86_64-linux perl -MCrypt::SSLeay -e 'print "$Crypt::SSLeay::VERSION\n"' 0.72 perl -MIO::Socket::SSL -e 'print "$IO::Socket::SSL::VERSION\n"' 2.024 env | grep PERL_LWP_SSL_VERIFY_HOSTNAME 旧服务器: perl -v This is perl 5, version 22, subversion 1 (v5.22.1) built for x86_64-linux network6 ~ # perl -MCrypt::SSLeay -e 'print "$Crypt::SSLeay::VERSION\n"' 0.72 network6 ~ # perl -MIO::Socket::SSL -e 'print "$IO::Socket::SSL::VERSION\n"' 2.012 env | grep PERL_LWP_SSL_VERIFY_HOSTNAME

版本可能很重要。自LWP v6.00以来,已验证的连接是默认设置。如果您只是在脚本开头添加$ENV {'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;,它是否有效? - mob
@mob,如果禁用安全检查来运行,它真的能正常工作吗? - ikegami
我不知道。在进行安全检查之前,它是否工作正常? - mob
如果涉及版本问题:服务器之间的确切差异对此有何影响?看起来不是主要版本的差异,我想知道次要版本是否会严重破坏BC。实际上,我仍然认为这不是关于版本的问题,但不幸的是由于Perl包的缺乏,调试选项非常有限。 - Dmitry Pismennyy
似乎使用 $ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0; 对我有用。我遇到了另一个错误,但现在还好。在这个错误中,我看到了 Net::SSL 的提及,这很重要。在其他出现类似错误的服务器上,我看到了 IO::Socket::SSL 的提及。因此,我将尝试显式使用定义而不是常量:但仍然想知道什么确切地影响了正确的库加载?顺便说一下:除了 Net:DNS 之外,代码中没有 Net:: 包的显式使用定义。 - Dmitry Pismennyy
$ENV{'PERL_NET_HTTPS_SSL_SOCKET_CLASS'} = "IO::Socket::SSL"; 这行代码无法正常工作。 - Dmitry Pismennyy
1个回答

5
选择可能受到程序完全不相关的部分的影响。我建议在程序顶部附近添加以下内容:
use IO::Socket::SSL;

或者,在启动程序的过程中将变量PERL_NET_HTTPS_SSL_SOCKET_CLASS设置为IO::Socket::SSL

export PERL_NET_HTTPS_SSL_SOCKET_CLASS=IO::Socket::SSL

如果你的程序现在抛出异常,可能是因为正在使用Net::SSL。
解决方案:解决错误,或者选择不那么安全的Net::SSL(需要将环境变量PERL_LWP_SSL_VERIFY_HOSTNAME设置为0)。
如果你的程序现在可以正常运行,则说明Net::SSL已经在程序中的其他地方被加载,这扰乱了决策过程。
解决方案:继续使用其中的一个解决方案。
该消息来自于Net::HTTPS,它被LWP::Protocol::https所使用,而LWP::UserAgent和LWP::Simple(以及WWW::Mechanize)则使用了它。
下面是Net::HTTPS用来确定使用哪个SSL类的过程:
package Net::HTTPS;

use vars qw( $SSL_SOCKET_CLASS );

# Figure out which SSL implementation to use
if ($SSL_SOCKET_CLASS) {
    # somebody already set it
}
elsif ($SSL_SOCKET_CLASS = $ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS}) {
    unless ($SSL_SOCKET_CLASS =~ /^(IO::Socket::SSL|Net::SSL)\z/) {
        die "Bad socket class [$SSL_SOCKET_CLASS]";
    }
    eval "require $SSL_SOCKET_CLASS";
    die $@ if $@;
}
elsif ($IO::Socket::SSL::VERSION) {
    $SSL_SOCKET_CLASS = "IO::Socket::SSL"; # it was already loaded
}
elsif ($Net::SSL::VERSION) {
    $SSL_SOCKET_CLASS = "Net::SSL";
}
else {
    eval { require IO::Socket::SSL; };
    if ($@) {
        my $old_errsv = $@;
        eval {
            require Net::SSL;  # from Crypt-SSLeay
        };
        if ($@) {
            $old_errsv =~ s/\s\(\@INC contains:.*\)/)/g;
            die $old_errsv . $@;
        }
        $SSL_SOCKET_CLASS = "Net::SSL";
    }
    else {
        $SSL_SOCKET_CLASS = "IO::Socket::SSL";
    }
}

一般来说,如果安装了IO::Socket::SSL,Net::HTTPS将使用它,否则使用Net::SSL。

一个可能会意外覆盖的方式是在加载Net::HTTPS之前加载Net::SSL(elsif ($Net::SSL::VERSION))。

# Causes the "elsif ($Net::SSL::VERSION)" path to be taken
use Net::SSL;

换句话说,选择可能会受到程序其他部分的影响。

可以通过在加载 Net::HTTPS 之前加载 IO::Socket::SSL,或者在启动程序的进程中设置环境变量 PERL_NET_HTTPS_SSL_SOCKET_CLASSIO::Socket::SSL 来抵消此影响。

因此,请尝试将以下内容添加到程序顶部:

# Causes the "elsif ($IO::Socket::SSL::VERSION)" path to be taken
use IO::Socket::SSL;

或者在启动程序的过程中尝试执行以下操作:

# Causes the "elsif ([...]$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS})" path to be taken
export PERL_NET_HTTPS_SSL_SOCKET_CLASS=IO::Socket::SSL

更新了我的答案。 - ikegami
其他模块的不同版本。 - ikegami
我在脚本的第一行添加了"use IO::Socket::SSL",但是仍然得到相同的错误:
Crypt-SSLeay中的Net::SSL无法验证主机名;要么安装IO::Socket::SSL,要么通过将PERL_LWP_SSL_VERIFY_HOSTNAME环境变量设置为0来关闭验证,在/usr/lib64/perl5/vendor_perl/5.24.0/LWP/Protocol/http.pm的第47行。
使用常量的解决方案对我有效,但我不想为整个服务器使用这些不安全的解决方案。有什么建议吗?谢谢!
- Dmitry Pismennyy
我不认为我可以帮助你 :( 你是否有最新的Net::HTTP? - ikegami
这是我的问题:“可能会意外覆盖的一种方式是在加载Net::HTTPS之前加载Net::SSL”。 - RedSands
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接