Bonjour à tous,
La semaine dernière, j'ai décidé d'exécuter les commandes de mise à niveau des packages sur mon serveur 14.04 pour m'assurer que j'ai été corrigé pour les vulnérabilités de Bash récemment trouvées. Par les informations ici ( http://www.ubuntu.com/usn/usn-2362-1/ ) J'ai exécuté une mise à niveau dist apt-get. Pour référence, j'ai exécuté apt-get update, apt-get dist-upgrade puis apt-get upgrade pour essayer de m'assurer que j'avais tout à jour jusqu'aux dernières versions (je lance cependant régulièrement la mise à niveau apt-get).
Après avoir réussi cela, j'ai constaté qu'un certain nombre de mes scripts Perl ne fonctionnaient plus. Pour référence, j'utilise ce serveur pour Nagios pour surveiller tous mes autres serveurs. Les scripts en question qui échouent maintenant se connectent tous à un système via https, se connectent à l'hôte et interrogent divers bits d'informations.
Avant la mise à niveau, j'ai pu ajouter une ligne à chacun de mes scripts Perl pour lui faire ignorer le SSL:
$ENV{Perl_LWP_SSL_VERIFY_HOSTNAME} = 0 }
Cependant, après la mise à niveau, cela semble n'avoir aucun effet et les scripts échouent tous car ils ne peuvent pas vérifier les certificats SSL (tous auto-signés).
Voici quelques extraits de ce que je vois:
exécution de 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.
Ce script Perl particulier utilise le "VMware Infrastructure (VI) Perl Toolkit" pour fonctionner. Le script que j'appelle, check_esx.pl est disponible ici
Voici un extrait du fichier http.pm autour de la ligne référencée dans l'erreur ci-dessus; la ligne 41 est la ligne "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;
}
Je suppose donc que ce que je recherche ici est l'une des deux choses
Soit: (A) Existe-t-il un moyen nouveau/meilleur/plus correct de faire en sorte que Perl ignore les certificats SSL? ou (B) Existe-t-il un moyen d'importer un certificat SSL auto-signé d'un autre hôte dans Ubuntu afin que le script Perl le reconnaisse et lui fasse confiance? Alternativement: (B-2) Existe-t-il un moyen de faire reconnaître par Ubuntu mon autorité de certification Windows Active Directory de telle sorte que je puisse émettre des certificats SSL de mon autorité de certification vers les systèmes en question et le faire reconnaître par les scripts Perl?
Merci d'avance à tous!
$ ENV {Perl_LWP_SSL_VERIFY_HOSTNAME} = 0
Il s'agissait d'un bogue dans LWP (CVE-2014-3230) qui a été corrigé dans les versions plus récentes. Perl_LWP_SSL_VERIFY_HOSTNAME est uniquement utilisé pour omettre de vérifier le nom d'hôte dans le certificat, pas la chaîne de certificats. Mais, car vous utilisez une chaîne de certificats auto-signée, la vérification échouera.
Cette option a été introduite uniquement pour la migration de l'ancien backend Crypt :: SSLeay vers le nouveau backend IO :: Socket :: SSL. Crypt :: SSLeay ne prend pas en charge la vérification du nom d'hôte (et est donc ouvert aux attaques de l'homme du milieu), contrairement à IO :: Socket :: SSL. Avec LWP version 6, le backend par défaut est IO :: Socket :: SSL.
Pour désactiver complètement la vérification de l'ensemble de certificats SSL_verify_mode => SSL_VERIFY_NONE
(tu dois use IO::Socket::SSL
pour avoir accès à la constante SSL_VERIFY_NONE, ou simplement utiliser 0) dans les ssl_opts de LWP. Il n'y a pas de variable d'environnement pour cela.
Exemple:
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(...)
Malheureusement, je ne vois aucune utilisation de LWP dans le script que vous avez référencé, donc je ne vois pas où le corriger.
Quant à vos options B:
(B) Existe-t-il un moyen d'importer un certificat SSL auto-signé d'un autre hôte dans Ubuntu afin que le script Perl le reconnaisse et lui fasse confiance? Alternativement: (B-2) Existe-t-il un moyen de faire reconnaître par Ubuntu mon autorité de certification Windows Active Directory de telle sorte que je puisse émettre des certificats SSL de mon autorité de certification vers les systèmes en question et le faire reconnaître par les scripts Perl?
Vous devriez pouvoir utiliser la variable d'environnement Perl_LWP_SSL_CA_FILE pour spécifier un fichier quelles autorités de certification ou certificats auto-signés vous acceptez comme approuvés.
Je pense que c'est un problème de version Perl, vérifiez quelle version Perl avez-vous utilisée précédemment pour exécuter ce script.
Ce dont je suis sûr, c'est qu'Ubuntu installe la dernière version stable de chaque logiciel. Prenez par exemple si vous avez un script python3 qui s'exécute sur ubuntu 12.04, il pourrait ne pas fonctionner sur ubuntu 14.04, et la raison en est que le premier a python 3.2, lorsque ce dernier a python 3.4.
Je suppose que le même script Perl vous arrive, vérifiez la version Perl et la note de publication de la nouvelle version.