После выполнения 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-скрипт использует "Perl Toolkit VMware Infrastructure (VI)" для работы. Сценарий, который я вызываю, 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 таким образом, чтобы я мог выдавать сертификаты SSL от моего ЦС для рассматриваемых систем и распознавать ли это сценарии Perl?
Спасибо всем заранее!
2 ответа
$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 поддерживает. В версии 6 LWP по умолчанию используется интерфейс 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:
(B) Есть ли способ импортировать самоподписанный сертификат SSL с другого хоста в Ubuntu, чтобы скрипт Perl распознал и доверял ему? В качестве альтернативы: (B-2) Есть ли способ заставить Ubuntu распознавать центр сертификации моего активного каталога Windows таким образом, чтобы я мог выдавать сертификаты SSL от моего ЦС для рассматриваемых систем и распознавать ли это сценарии Perl?
Вы должны иметь возможность использовать переменную среды PERL_LWP_SSL_CA_FILE, чтобы указать файл, которые CA или самозаверяющие сертификаты вы принимаете в качестве доверенных.
Я думаю, что это проблема версии Perl, проверьте, какую версию Perl вы использовали ранее для запуска этого скрипта.
В чем я уверен, так это в том, что Ubuntu устанавливает последнюю стабильную версию каждого программного обеспечения. Возьмем, к примеру, если у вас есть скрипт python3, который работает на Ubuntu 12.04, он может не работать на Ubuntu 14.04, и причина этого в том, что у первых есть Python 3.2, когда последняя имеет версию Python 3.4.
Я предполагаю, что то же самое случится с вами Perl-скрипт, проверить версию Perl и примечание к выпуску новой версии.