Gorby has asked for the wisdom of the Perl Monks concerning the following question:

Hello Wise Monks. I'm getting an error that I can't connect to my ip using https. Here's my code. I replaced my real ip address with "myipaddress"

$useragent=new LWP::UserAgent; $request=new HTTP::Request('GET', "https://myipaddress/somea +pps/someapp.cgi"); $result=$useragent->request($request); $placibo2[0]=$result->{_content}; if ($placibo2[0]) { print header; print $placibo2[0]; }

Should I set a value for $ENV{ HTTPS_CA_FILE }? If so, what value? I'm using a windows 2012 server to run the perl program. When I try to access https://www.google.com it works. If I try to access https://myipaddress from the browser on the server it works. When I try to access my ipaddress using https using the above code i get:

LWP::Protocol::https::Socket: SSL connect attempt failed with unknown error error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

I also tried the following: $ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0 which worked. I was able to access my ip address using the above code but this is not secure and open to man in the middle attack. What should I now do? Thank you in advance for your wisdom.

Replies are listed 'Best First'.
Re: https using lwp (WWW::Mechanize)
by Anonymous Monk on Nov 19, 2016 at 03:48 UTC
      Hi. The certificate is a self signed certificate from a private server.

        The easiest way to deal with self-signed certificates is to expect exactly this certificate. This can be done with the SSL_fingerprint argument of IO::Socket::SSL which you can set using ssl_opts in LWP. With this argument all other checks (subject matches hostname, expiration...) are disabled.
        You need at least IO::Socket::SSL version 1.980 for this (released 04/2014). See the documentation of SSL_fingerprint for details but in short:

        To get the current fingerprint analyze the servers certificate or get the fingerprint from a trusted location with:

        use IO::Socket::SSL; my $cl = IO::Socket::SSL->new( PeerAddr => "ip:port", SSL_verify_mode => 0 ); print $cl->get_fingerprint."\n"; # sha256$b64d26746ca1cd5403....

        And to use it:

        my $ua = LWP::UserAgent->new... $ua->ssl_opts(SSL_fingerprint => 'sha256$b64...');

        Hi. The certificate is a self signed certificate from a private server.

        I think that is your problem, see https://metacpan.org/pod/IO::Socket::SSL#Common-Problems-with-SSL it says

        Validation of self-signed certificate fails even if it is given with SSL_ca* argument.

        The SSL_ca* arguments do not give a general trust store for arbitrary certificates but only specify a store for CA certificates which then can be used to verify other certificates. This especially means that certificates which are not a CA get simply ignored, notably self-signed certificates which do not also have the CA-flag set.

        This behavior of OpenSSL differs from the more general trust-store concept which can be found in browsers and where it is possible to simply added arbitrary certificates (CA or not) as trusted.

        So, one path towards a solution, figure out what CA-flag is and how to set it , openssl stuff

        Or maybe you can get a free one care of mozilla Let's Encrypt - Free SSL/TLS Certificates