我根本不是 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, version 24, subversion 0 (v5.24.0)
perl -MCrypt::SSLeay -e '打印“$Crypt::SSLeay::VERSION\n”'
0.72
perl -MIO::Socket::SSL -e '打印“$IO::Socket::SSL::VERSION\n”'
2.024
环境 | grep PERL_LWP_SSL_VERIFY_HOSTNAME
旧服务器:perl -v
这是为 x86_64-linux 构建的 perl 5, version 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
选择可能会受到程序中完全不相关的部分的影响。我建议在程序顶部附近添加以下内容:
use IO::Socket::SSL;
Run Code Online (Sandbox Code Playgroud)
或者,在启动程序的过程中将 var 设置PERL_NET_HTTPS_SSL_SOCKET_CLASS为IO::Socket::SSL。
export PERL_NET_HTTPS_SSL_SOCKET_CLASS=IO::Socket::SSL
Run Code Online (Sandbox Code Playgroud)
如果您的程序现在抛出异常,这可能就是使用 Net::SSL 的原因。
解决方案:解决该错误,或解决安全性较低的 Net::SSL(需要将 env var 设置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";
}
}
Run Code Online (Sandbox Code Playgroud)
一般来说,如果安装了 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;
Run Code Online (Sandbox Code Playgroud)
换句话说,选择可能会受到程序其他部分的影响。
这可以通过在加载 Net::HTTPS 之前加载 IO::Socket::SSL 或通过在启动程序的过程中设置 env varPERL_NET_HTTPS_SSL_SOCKET_CLASS来抵消IO::Socket::SSL。
因此,请尝试将以下内容添加到程序的顶部:
# Causes the "elsif ($IO::Socket::SSL::VERSION)" path to be taken
use IO::Socket::SSL;
Run Code Online (Sandbox Code Playgroud)
或者尝试在启动程序的过程中执行以下操作:
# Causes the "elsif ([...]$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS})" path to be taken
export PERL_NET_HTTPS_SSL_SOCKET_CLASS=IO::Socket::SSL
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4714 次 |
| 最近记录: |