Search code examples
perlopensslcentoslwp

Why does LWP fail to connect with "500 SSL negotiation failed"?


My Perl script sends some information to a remote server.

Below is a portion of the code

#!/var/hvmail/libexec/perl

use strict;

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;

use constant HANDLER_URL => "https://www.website.com/handler.php";

$ENV{HTTPS_DEBUG} = 1;

my $ua = LWP::UserAgent->new;

# Some DB stuff, not applicable
my $row; # This is a DB row ($sth->fetchrow_hashref())   

my $req = POST ''.HANDLER_URL, [ %$row ]; 
my $res = $ua->request($req);

$res->is_success is false with $res->status_line being

500 SSL negotiation failed

We are running CentOS 6.4, Perl 5.10.1, OpenSSL 1.0.1e-fips.

Update

Here's the full output:

SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL3 alert read:fatal:handshake failure
SSL_connect:error in SSLv2/v3 read server hello A
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL3 alert read:fatal:handshake failure
SSL_connect:failed in SSLv3 read server hello A
SSL_connect:before/connect initialization
SSL_connect:SSLv2 write client hello A
SSL_connect:failed in SSLv2 read server hello A
Error: [ 500 SSL negotiation failed:  ]

Requested Command Output

Can't locate Net/SSLeay.pm
Can't locate LWP/Protocol/https.pm

Solution

  • You seem to be relying on Crypt::SSLeay. You shouldn't. It's outdated and incomplete.

    Install the latest LWP::Protocol::https which will upgrade your LWP and install the preferred SSL/TLS stack consisting of the IO::Socket::SSL and Net::SSLeay.

    A web search shows there are CentOS6 repositories with RPM packages for LWP::Protocol::https.

    The server has disabled SSLv3 support which means the negotiation fails.

    Once you install the package, if you are still seeing the same error, make sure your script is not forcing the use of Crypt::SSLeay. That is, make sure none of the following appears anywhere in your script:

    use Net::HTTPS;
    $Net::HTTPS::SSL_SOCKET_CLASS = 'Net::SSL';
    

    or

    local $ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = 'Net::SSL';
    

    or

    use Net::SSL;
    

    If you are still running into problems, make sure there is no PERL_NET_HTTPS_SSL_SOCKET_CLASS environment variable in the script's run time environment.

    Also, try

    $ /var/hvmail/libexec/perl -MNet::SSLeay -le 'print $Net::SSLeay::VERSION'
    

    and

    $ /var/hvmail/libexec/perl -MLWP::Protocol::https -le 'print $LWP::Protocol::https::VERSION`'
    

    and report the output.

    I suspect the issue is that the new packages were installed for the system's perl whereas it seems you may have a separate perl.

    If that is the case, you should install each package individually using /var/hvmail/libexec/perl. For example:

    $ curl -O https://cpan.metacpan.org/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.7043.tar.gz
    $ tar xvf App-cpanminus-1.7043.tar.gz
    $ cd App-cpanminus-1.7043
    $ /var/hvmail/libexec/perl Makefile.PL
    $ make install
    

    Figure out where cpanm was installed. I am hoping /var/hvmail/libexec.

    $ /var/hvmail/libexec/cpanm LWP::Protocol::https
    

    See also Updating all outdated Perl modules, but that may be risky on a production. Still, installing App::cpanoutdated, and seeing how outdated your Perl modules are might be useful

    Now, keep in mind that tinkering with a production install like this is risky. Make sure you have a way to undo changes in case something goes wrong.

    Finally, note that OpenSSL 1.0.1 versions are no longer supported:

    With regards to current and future releases the OpenSSL project has adopted the following policy:

    • Version 1.1.0 will be supported until 2018-08-31.
    • Version 1.0.2 will be supported until 2019-12-31 (LTS).
    • Version 1.0.1 is no longer supported.
    • Version 1.0.0 is no longer supported.
    • Version 0.9.8 is no longer supported.