apt-get dist-upgrade を実行すると、Perl スクリプトは 14.04 で無効な SSL 証明書を無視しなくなります。

apt-get dist-upgrade を実行すると、Perl スクリプトは 14.04 で無効な SSL 証明書を無視しなくなります。

みんなおはよう、

先週、最近発見された Bash の脆弱性に対するパッチが適用されていることを確認するために、14.04 サーバーのパッケージをアップグレードするコマンドを実行することにしました。ここの情報によると (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;
}

私がここで探しているのは2つのうちの1つだと思います

どちらか: (A) Perl が SSL 証明書を無視するようにする新しい/より良い/より正しい方法はありますか? または (B) Perl スクリプトがそれを認識して信頼するように、別のホストから自己署名 SSL 証明書を Ubuntu にインポートする方法はありますか? あるいは: (B-2) Ubuntu が私の Windows Active Directory 証明書機関を認識し、私の CA から問題のシステムに SSL 証明書を発行し、それを 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_NONEuse IO::Socket::SSLLWP の ssl_opts で SSL_VERIFY_NONE 定数にアクセスするか、0 を使用します。これを行うための環境変数はありません。

例:

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 Active Directory 証明書機関を認識させて、自分の CA から問題のシステムに SSL 証明書を発行し、それを Perl スクリプトで認識できるようにする方法はありますか?

環境変数 PERL_LWP_SSL_CA_FILE を使用して、信頼できるものとして受け入れる CA または自己署名証明書のファイルを指定することができます。

答え2

これは Perl バージョンの問題だと思います。以前そのスクリプトを実行するために使用した Perl バージョンを確認してください。

私が確信しているのは、Ubuntu がすべてのソフトウェアの最新の安定バージョンをインストールするということです。たとえば、Ubuntu 12.04 で実行される python3 スクリプトがある場合、Ubuntu 14.04 では動作しない可能性があります。その理由は、前者は python 3.2 で、後者は python 3.4 バージョンだからです。

あなたの Perl スクリプトでも同じことが起こると想定しています。Perl のバージョンと新しいバージョンのリリース ノートを確認してください。

関連情報