1

Good morning all,

Last week I decided to run the commands to upgrade packages on my 14.04 Server to ensure that I was patched for the recently found Bash vulnerabilties. Per the info here (http://www.ubuntu.com/usn/usn-2362-1/) I ran an apt-get dist-upgrade. For reference, i ran apt-get update, apt-get dist-upgrade and then apt-get upgrade to try & make sure I had everything up to the latest versions (I routinely run the apt-get upgrade though).

After successfully doing this, I found that a number of my Perl scripts were no longer functioning. For reference, I use this server for Nagios to monitor all of my other servers. The scripts in question that are now failing all connect to a system via https, log into the host and query various bits of information.

Prior to the upgrade, I was able to add a line to each of my Perl scripts to make it ignore the SSL:

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0 } 

However, after the upgrade, this seems to have no affect, and the scripts all fail because they can't verify the SSL certs (all self signed).

Here's some snips of what I'm seeing:

script execution:

    nagios@nagios:/usr/local/nagios/libexec$ ./check_esx.pl -H 192.168.22.18 -u root -p password -l cpu
CHECK_ESX.PL CRITICAL - Can't connect to 192.168.22.18:443 (certificate verify failed)

LWP::Protocol::https::Socket: SSL connect attempt failed error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed at /usr/share/perl5/LWP/Protocol/http.pm line 41.

This particular Perl script utilizes the "VMware Infrastructure (VI) Perl Toolkit" to function. The script that I'm calling, check_esx.pl is available here

Here's a snip of the file http.pm around the line referenced in the above error; line 41 is the "die" line.

sub _new_socket
{
    my($self, $host, $port, $timeout) = @_;

    local($^W) = 0;  # IO::Socket::INET can be noisy
    my $sock = $self->socket_class->new(PeerAddr => $host,
                                        PeerPort => $port,
                                        LocalAddr => $self->{ua}{local_address},
                                        Proto    => 'tcp',
                                        Timeout  => $timeout,
                                        KeepAlive => !!$self->{ua}{conn_cache},
                                        SendTE    => 1,
                                        $self->_extra_sock_opts($host, $port),
                                       );

    unless ($sock) {
        # IO::Socket::INET leaves additional error messages in $@
        my $status = "Can't connect to $host:$port";
        if ($@ =~ /\bconnect: (.*)/ ||
            $@ =~ /\b(Bad hostname)\b/ ||
            $@ =~ /\b(certificate verify failed)\b/ ||
            $@ =~ /\b(Crypt-SSLeay can't verify hostnames)\b/
        ) {
            $status .= " ($1)";
        }
        die "$status\n\n$@";
    }

    # perl 5.005's IO::Socket does not have the blocking method.
    eval { $sock->blocking(0); };

    $sock;
}

So I guess what I'm looking for here is one of two things

Either: (A) Is there a new/better/more correct way to make Perl ignore the SSL certs? or (B) Is there a way to import a self signed SSL cert from another host into Ubuntu so that the Perl script will recognize & trust it? Alternatively: (B-2) Is there a way to make Ubuntu recognize my windows active directory Cert Authority such that I could issue SSL certs from my CA to the systems in question, and have it recognized by the Perl scripts?

Thanks in advance everyone!

1

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0

This was a bug in LWP (CVE-2014-3230) which was fixed in newer versions. PERL_LWP_SSL_VERIFY_HOSTNAME is only used to omit verifying the hostname in the certificate, not the certificate chain. But, because you are using a self-signed certificate chain verification will fail.

This option was only introduced for the migration from the old Crypt::SSLeay backend to the new IO::Socket::SSL backend. Crypt::SSLeay does not support verification of the hostname (and is thus open for man-in-the-middle attacks), while IO::Socket::SSL does. With LWP version 6 the default backend is IO::Socket::SSL.

To completely disable verification of the certificate set SSL_verify_mode => SSL_VERIFY_NONE (you need to use IO::Socket::SSL to have access to the SSL_VERIFY_NONE constant, or just use 0) in the ssl_opts of LWP. There is no environment variable to do this.

Example:

use LWP::UserAgent;
use IO::Socket::SSL;
my $ua = LWP::UserAgent->new(..., ssl_opts => { SSL_verify_mode => SSL_VERIFY_NONE });
$ua->get(...); # or $ua->post(...) or $ua->request(...)

Unfortunately I cannot see any use of LWP in the script you referenced, so I don't see where to fix it there.

As for your options B:

(B) Is there a way to import a self signed SSL cert from another host into Ubuntu so that the Perl script will recognize & trust it? Alternatively: (B-2) Is there a way to make Ubuntu recognize my windows active directory Cert Authority such that I could issue SSL certs from my CA to the systems in question, and have it recognized by the Perl scripts?

You should be able to use the environment variable PERL_LWP_SSL_CA_FILE to specify a file which CAs or self-signed certificates you accept as trusted.

  • Wonderful information there. Is there any chance you could expand on how to perform this? My knowledge of Linux is still very lacking; and frankly, I so far only know how to do the various things that I've had to learn in order to keep my Nagios system working. – dceola Oct 6 '14 at 16:25
  • See example in edited answer. – Steffen Ullrich Oct 6 '14 at 16:50
  • So if I understand correctly; this needs to be done at the point in the script where the connection is being initiated? – dceola Oct 6 '14 at 16:59
  • It needs to be done where the user-agent is created. But see my edited response for how you could use instead verification by specifying your own trusted CA/certificates. This is probably simpler in your case and more secure too than switching verification off. – Steffen Ullrich Oct 6 '14 at 17:03
  • Thank you once again. It looks like all solutions involved here are going to be completely outside of my abilities. I know nothing of Perl coding in order to even look at the existing scripts and figure out what to change. I appreciate your input and I'm sure it will help someone else with this issue in the future. – dceola Oct 6 '14 at 17:09
0

I think it's a perl version issue, check what perl version did you use previously to run that script.

What I'm sure about is that Ubuntu installs the latest stable version of every software. Take for example if you have a python3 script that runs on ubuntu 12.04 it might not work on ubuntu 14.04, and the reason for that is the firs has python 3.2, when the latterhas python 3.4 version.

I assume the same happen to you perl script, check perl version, and the release note of the new version.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.