3

I am not Perl guy at all. But for circumstances I have to deploy perl script on new gentoo server. Script works nicely on several other servers that were configured by another guy. So new one server I've installed by myself and have different versions for some packages. As result with given perl script I have an issue:

Net::SSL from Crypt-SSLeay can't verify hostnames; either install IO::Socket::SSL or turn off verification by setting the PERL_LWP_SSL_VERIFY_HOSTNAME environment variable to 0

Actually it is installed.

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

Why it does not see installed module. And what can I do on new server to fix issue without modification script? Is version difference so important? new server Perl version: 5.24.0 old server Perl version: 5.22.1

New server:

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

Old server: 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

  • Versions might matter. Verified connections are the default since LWP v6.00. Does it work if you just [slap an `$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;` at the beginning of the script](http://www.linuxquestions.org/questions/linux-newbie-8/how-to-set-perl_lwp_ssl_verify_hostname-to-0-a-869836/)? – mob May 25 '16 at 21:58
  • @mob, Is it really working if you disable security checks to allow it to run... – ikegami May 25 '16 at 22:27
  • I dunno. Was it working before when the security checks weren't being made? – mob May 25 '16 at 22:32
  • If it is about version: what exact difference between servers affects on this? It looks not major version diff and I wonder if minor versions break BC so heavy. Actually, I still thinking it is not about version, but unfortunately very limited in debug options cause lack of Perl's bag. – Dmitry Pismennyy May 26 '16 at 05:52
  • Seems usage $ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0; works for me. I got another error which is fine for now. Important in this error I see mention Net::SSL. On other servers with close error I see mention IO::Socket::SSL. So I will try explicit use definition instead of constant: but still wonder what exactly affects on correct library loading? BTW: there is no explicit use definitions for Net:: packages in code except Net:DNS. – Dmitry Pismennyy May 26 '16 at 06:12
  • $ENV{'PERL_NET_HTTPS_SSL_SOCKET_CLASS'} = "IO::Socket::SSL"; Does not work. – Dmitry Pismennyy May 26 '16 at 09:30

1 Answers1

5

The choice can be affected by completely unrelated parts of your programs. I recommend adding the following near the top of your program:

use IO::Socket::SSL;

Alternatively, set var PERL_NET_HTTPS_SSL_SOCKET_CLASS to IO::Socket::SSL in the process that launches your program.

export PERL_NET_HTTPS_SSL_SOCKET_CLASS=IO::Socket::SSL
  • If your program now throws an exception, this could be why Net::SSL was being used.

    Solution: Solve that error, or settle for the less secure Net::SSL (which requires setting env var PERL_LWP_SSL_VERIFY_HOSTNAME to 0).

  • If your program now runs perfectly, then Net::SSL is being loaded elsewhere in your program, and this is skewing the decision process.

    Solution: Keep using one of the two solution.


Detailed version

That message comes from Net::HTTPS, which is used by LWP::Protocol::https, which is used by LWP::UserAgent and LWP::Simple (and thus WWW::Mechanize).

The following is the process used by Net::HTTPS to determine which SSL class to use:

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";
    }
}

Generally speaking, Net::HTTPS will use IO::Socket::SSL if installed, and Net::SSL otherwise.

One way in which this could be accidentally overridden is by loading Net::SSL before loading Net::HTTPS (elsif ($Net::SSL::VERSION)).

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

In other words, the choice can be affected by other parts of your programs.

This can be counteracted by loading IO::Socket::SSL before loading Net::HTTPS, or by setting env var PERL_NET_HTTPS_SSL_SOCKET_CLASS to IO::Socket::SSL in the process that launches your program.

So try adding the folowing to the top of your program:

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

Or try doing the following in the process that launches your program:

# 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
  • 367,544
  • 15
  • 269
  • 518
  • Updated my answer. – ikegami May 25 '16 at 22:27
  • Speaking about loading, I don't see any obvious declaration of ant Net::XXXX package in script except Net::DNS. I will play with explicit use declaration. But I wonder why this script works on other services as-is? – Dmitry Pismennyy May 26 '16 at 05:48
  • Different versions of other modules. – ikegami May 26 '16 at 06:16
  • I added use IO::Socket::SSL as first line in script but got same error: >Net::SSL from Crypt-SSLeay can't verify hostnames; either install IO::Socket::SSL or turn off verification by setting the PERL_LWP_SSL_VERIFY_HOSTNAME environment variable to 0 at /usr/lib64/perl5/vendor_perl/5.24.0/LWP/Protocol/http.pm line 47. Solution with constant works for me, but I don't want to use those unsecure solution fr whole servers. Any advices, thx? – Dmitry Pismennyy May 26 '16 at 08:23
  • $ENV{'PERL_NET_HTTPS_SSL_SOCKET_CLASS'} = "IO::Socket::SSL"; Does not work also! – Dmitry Pismennyy May 26 '16 at 09:29
  • I don't think I can help you :( Do you have the latest Net::HTTP? – ikegami May 26 '16 at 14:30
  • This was my issue: "One way in which this could be accidentally overridden is by loading Net::SSL before loading Net::HTTPS" – RedSands Oct 13 '16 at 01:59