После выполнения apt-get dist-upgrade скрипты Perl больше не будут игнорировать недействительные сертификаты SSL на 14.04

После выполнения apt-get dist-upgrade скрипты Perl больше не будут игнорировать недействительные сертификаты SSL на 14.04

Всем доброе утро,

На прошлой неделе я решил запустить команды для обновления пакетов на моем сервере 14.04, чтобы убедиться, что я пропатчен для недавно обнаруженных уязвимостей Bash. Согласно информации здесь (http://www.ubuntu.com/usn/usn-2362-1/) Я запустил apt-get dist-upgrade. Для справки, я запустил apt-get update, apt-get dist-upgrade и затем apt-get upgrade, чтобы попытаться убедиться, что у меня все обновлено до последних версий (хотя я обычно запускаю apt-get upgrade).

После успешного выполнения этого я обнаружил, что ряд моих скриптов Perl больше не функционируют. Для справки, я использую этот сервер для Nagios, чтобы контролировать все мои другие серверы. Все скрипты, о которых идет речь, которые сейчас выходят из строя, подключаются к системе через https, входят в хост и запрашивают различные биты информации.

До обновления мне удавалось добавлять строку в каждый из моих скриптов Perl, чтобы заставить их игнорировать SSL:

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0 } 

Однако после обновления это, похоже, не оказывает никакого эффекта, и все скрипты завершаются ошибкой, поскольку они не могут проверить сертификаты SSL (все самоподписанные).

Вот некоторые фрагменты того, что я вижу:

выполнение скрипта:

    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.

Этот конкретный скрипт Perl использует "VMware Infrastructure (VI) Perl Toolkit" для работы. Скрипт, который я вызываю, check_esx.pl доступенздесь

Вот фрагмент файла http.pm вокруг строки, на которую ссылается ошибка выше; строка 41 — это строка «die».

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

Так что, я думаю, я ищу здесь одну из двух вещей:

Либо: (A) Есть ли новый/лучший/более правильный способ заставить Perl игнорировать сертификаты SSL? или (B) Есть ли способ импортировать самоподписанный сертификат SSL с другого хоста в Ubuntu, чтобы скрипт Perl распознал его и доверял ему? Либо: (B-2) Есть ли способ заставить Ubuntu распознавать мой центр сертификации Windows Active Directory, чтобы я мог выдавать сертификаты SSL из своего CA для соответствующих систем и чтобы скрипты Perl распознавали его?

Заранее спасибо всем!

решение1

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0

Это была ошибка в LWP (CVE-2014-3230), которая была исправлена ​​в новых версиях. PERL_LWP_SSL_VERIFY_HOSTNAME используется только для пропуска проверки имени хоста в сертификате, а не цепочки сертификатов. Но поскольку вы используете самоподписанную цепочку сертификатов, проверка не будет выполнена.

Эта опция была введена только для миграции со старого бэкэнда Crypt::SSLeay на новый бэкэнд IO::Socket::SSL. Crypt::SSLeay не поддерживает проверку имени хоста (и, таким образом, открыт для атак типа «человек посередине»), тогда как IO::Socket::SSL поддерживает. В LWP версии 6 бэкэнд по умолчанию — IO::Socket::SSL.

Чтобы полностью отключить проверку набора сертификатов SSL_verify_mode => SSL_VERIFY_NONE(нужно use IO::Socket::SSLиметь доступ к константе SSL_VERIFY_NONE или просто использовать 0) в ssl_opts LWP. Переменной среды для этого нет.

Пример:

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

К сожалению, я не вижу использования LWP в скрипте, на который вы ссылаетесь, поэтому не вижу, где это можно исправить.

Что касается вашего варианта Б:

(B) Есть ли способ импортировать самоподписанный SSL-сертификат с другого хоста в Ubuntu, чтобы скрипт Perl распознал его и доверял ему? Альтернативный вариант: (B-2) Есть ли способ заставить Ubuntu распознавать мой центр сертификации Windows Active Directory, чтобы я мог выдавать SSL-сертификаты из своего CA для соответствующих систем и чтобы скрипты Perl распознавали их?

Вы должны иметь возможность использовать переменную среды PERL_LWP_SSL_CA_FILE, чтобы указать файл, какие центры сертификации или самозаверяющие сертификаты вы принимаете в качестве доверенных.

решение2

Я думаю, что это проблема версии Perl. Проверьте, какую версию Perl вы использовали ранее для запуска этого скрипта.

В чем я уверен, так это в том, что Ubuntu устанавливает последнюю стабильную версию каждого программного обеспечения. Возьмем, к примеру, если у вас есть скрипт python3, который работает на ubuntu 12.04, он может не работать на ubuntu 14.04, и причина этого в том, что у первого python 3.2, а у второго — python 3.4.

Я предполагаю, что то же самое произойдет и с вашим скриптом Perl, проверьте версию Perl и примечание к выпуску новой версии.

Связанный контент