Depois de executar o apt-get dist-upgrade, os scripts Perl não irão mais ignorar certificados SSL inválidos em 14.04

1

Bom dia a todos,

Na semana passada, decidi executar os comandos para atualizar os pacotes no meu servidor 14.04 para garantir que eu fosse corrigido para as vulnerabilidades Bash encontradas recentemente. Por informações aqui ( link ) eu executei um apt-get dist-upgrade. Para referência, eu corri o apt-get update, o apt-get dist-upgrade e então o apt-get upgrade para tentar o & amp; Certifique-se que eu tinha tudo para as versões mais recentes (eu rotineiramente executar o upgrade do apt-get embora).

Depois de fazer isso com sucesso, descobri que vários dos meus scripts Perl não estavam mais funcionando. Para referência, eu uso este servidor para o Nagios para monitorar todos os meus outros servidores. Os scripts em questão que agora estão falhando, todos se conectam a um sistema via https, fazem login no host e consultam vários bits de informações.

Antes da atualização, consegui adicionar uma linha a cada um dos meus scripts Perl para ignorar o SSL:

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0 } 

No entanto, após a atualização, isso parece não ter efeito, e todos os scripts falham porque não podem verificar os certificados SSL (todos auto-assinados).

Veja alguns recortes do que estou vendo:

Execução do script

:

    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.

Este script Perl utiliza o "VMware Infrastructure (VI) Perl Toolkit" para funcionar. O script que estou chamando, check_esx.pl está disponível aqui

Aqui está um recorte do arquivo http.pm ao redor da linha referenciada no erro acima; a linha 41 é a linha "morrer".

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

Então, acho que o que estou procurando aqui é uma das duas coisas

 (A) Existe uma maneira nova / melhor / mais correta de fazer o Perl ignorar os certificados SSL? ou  (B) Existe uma maneira de importar um certificado SSL autoassinado de outro host para o Ubuntu para que o script Perl reconheça & amp; confia? Alternativamente:  (B-2) Existe uma maneira de fazer com que o Ubuntu reconheça meu Active Directory do Windows como Autoridade de Certificação, de modo que eu possa emitir certificados SSL da minha CA para os sistemas em questão e tê-los reconhecidos pelos scripts Perl?

Obrigado antecipadamente a todos!

    
por dceola 06.10.2014 / 15:44

2 respostas

1

% bl0ck_qu0te%

Este foi um bug no LWP (CVE-2014-3230) que foi corrigido em versões mais recentes. PERL_LWP_SSL_VERIFY_HOSTNAME é usado apenas para omitir a verificação do nome do host no certificado, não na cadeia de certificados. Mas, como você está usando uma verificação de cadeia de certificados auto-assinada, a verificação falhará.

Esta opção foi introduzida apenas para a migração do antigo backend Crypt :: SSLeay para o novo backend IO :: Socket :: SSL. Crypt :: SSLeay não suporta a verificação do nome do host (e, portanto, é aberto para ataques man-in-the-middle), enquanto IO :: Socket :: SSL. Com o LWP versão 6, o backend padrão é IO :: Socket :: SSL.

Para desabilitar completamente a verificação do conjunto de certificados SSL_verify_mode => SSL_VERIFY_NONE (você precisa use IO::Socket::SSL para ter acesso à constante SSL_VERIFY_NONE ou apenas usar 0) no ssl_opts do LWP. Não há uma variável de ambiente para fazer isso.

Exemplo:

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(...)

Infelizmente, não vejo nenhum uso de LWP no script que você mencionou, por isso não vejo onde corrigi-lo.

Quanto às suas opções B:

% bl0ck_qu0te%

Você deve conseguir usar a variável de ambiente PERL_LWP_SSL_CA_FILE para especificar um arquivo que CAs ou certificados auto-assinados aceitam como confiáveis.

    
por Steffen Ullrich 06.10.2014 / 16:10
0

Eu acho que é um problema de versão do perl, verifique qual versão do perl você usou anteriormente para executar esse script.

O que eu tenho certeza é que o Ubuntu instala a última versão estável de cada software. Tome por exemplo, se você tem um script python3 que roda no Ubuntu 12.04 pode não funcionar no Ubuntu 14.04, e a razão para isso é o primeiro que tem python 3.2, quando o último tem versão 3.4 python.

Presumo que o mesmo aconteça com o seu script perl, verifique a versão do perl e a nota de lançamento da nova versão.

    
por Ghassen Telmoudi 07.10.2014 / 15:37