【问题标题】:Crypt-SSLeay can't verify hostnamesCrypt-SSLeay 无法验证主机名
【发布时间】:2016-05-25 21:31:37
【问题描述】:

我根本不是 Perl 人。但在某些情况下,我必须在新的 gentoo 服务器上部署 perl 脚本。脚本在其他几个由另一个人配置的服务器上运行良好。因此,我自己安装了一台新服务器,并且某些软件包具有不同的版本。作为给定 perl 脚本的结果,我有一个问题:

来自 Crypt-SSLeay 的 Net::SSL 无法验证主机名;安装 IO::Socket::SSL 或通过将 PERL_LWP_SSL_VERIFY_HOSTNAME 环境变量设置为 0 来关闭验证

其实已经安装好了。

perl -MIO::Socket::SSL -e 'print "$IO::Socket::SSL::VERSION\n"' 2.024

为什么它没有看到已安装的模块。在没有修改脚本的情况下,我可以在新服务器上做什么来解决问题?版本差异有那么重要吗? 新服务器 Perl 版本:5.24.0 旧服务器 Perl 版本:5.22.1

新服务器:

perl -v

这是为 x86_64-linux 构建的 perl 5,版本 24,subversion 0 (v5.24.0)

perl -MCrypt::SSLeay -e 'print "$Crypt::SSLeay::VERSION\n"'

0.72

perl -MIO::Socket::SSL -e 'print "$IO::Socket::SSL::VERSION\n"'

2.024

环境 | grep PERL_LWP_SSL_VERIFY_HOSTNAME

旧服务器: perl -v

这是为 x86_64-linux 构建的 perl 5,版本 22,subversion 1 (v5.22.1)

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

环境 | grep PERL_LWP_SSL_VERIFY_HOSTNAME

【问题讨论】:

  • 版本可能很重要。自 LWP v6.00 起,已验证连接是默认连接。如果你只是slap an $ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0; at the beginning of the script,它可以工作吗?
  • @mob,如果您禁用安全检查以使其运行,它真的有效吗...
  • 我不知道。在没有进行安全检查之前它是否有效?
  • 如果是关于版本:服务器之间的确切差异对此有何影响?它看起来不是主要版本差异,我想知道次要版本是否会严重破坏 BC。实际上,我仍然认为这与版本无关,但不幸的是调试选项非常有限,导致缺少 Perl 的包。
  • 似乎用法 $ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;为我工作。我遇到了另一个错误,目前还可以。在这个错误中我看到提到 Net::SSL 很重要。在其他有关闭错误的服务器上,我看到提到 IO::Socket::SSL。所以我会尝试显式使用定义而不是常量:但仍然想知道正确的库加载到底有什么影响?顺便说一句:除了 Net:DNS 之外,代码中没有对 Net:: 包的明确使用定义。

标签: perl ssl gentoo


【解决方案1】:

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

use IO::Socket::SSL;

或者,在启动程序的过程中将 var 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";
    }
}

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

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

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

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

这可以通过在加载 Net::HTTPS 之前加载 IO::Socket::SSL 来抵消,或者在启动程序的过程中将 env var PERL_NET_HTTPS_SSL_SOCKET_CLASS 设置为 IO::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

【讨论】:

  • 更新了我的答案。
  • 说到加载,除了Net::DNS,我在脚本中没有看到任何明显的ant Net::XXXX包声明。我将使用显式使用声明。但我想知道为什么这个脚本可以按原样在其他服务上运行?
  • 其他模块的不同版本。
  • 我在脚本的第一行添加了 use IO::Socket::SSL 但得到了同样的错误: >Net::SSL from Crypt-SSLeay can't verify hostnames;安装 IO::Socket::SSL 或通过在 /usr/lib64/perl5/vendor_perl/5.24.0/LWP/Protocol/http.pm 第 47 行将 PERL_LWP_SSL_VERIFY_HOSTNAME 环境变量设置为 0 来关闭验证。具有常量的解决方案适用于我,但我不想在整个服务器上使用那些不安全的解决方案。有什么建议吗,谢谢?
  • $ENV{'PERL_NET_HTTPS_SSL_SOCKET_CLASS'} = "IO::Socket::SSL";也不行!
猜你喜欢
  • 1970-01-01
  • 2014-12-30
  • 2019-08-27
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 2010-09-30
  • 2015-10-18
  • 2021-08-19
相关资源
最近更新 更多