Nagios : sonde check DNS

Boris HUISGEN October 10, 2013

administration monitoring linux nagios

Je vous joins ici la sonde Nagios que j’utilise pour vérifier des enregistrements DNS. Plusieurs serveurs DNS peuvent être interrogés et leurs réponses vérifiées. Un seuil d’alerte critique/avertissement est configurable. La sonde renvoie également des performance data pour générer des graphes pour chaque serveur interrogé.

#!/usr/bin/perl -w

#
# This plugin checks DNS nameservers resolution.
#
# Boris HUISGEN <bhuisgen@hbis.fr>
#

use strict;
use warnings;

use NetAddr::IP::Util qw( inet_ntoa inet_n2dx );
use Nagios::Plugin;
use Net::DNS::Dig qw( :forceEmu ndd_gethostbyaddr ndd_gethostbyname ndd_gethostbyname2 AF_INET AF_INET6 );
use Switch;

my $np = Nagios::Plugin->new(
    shortname => 'DNS',
    version   => '0.1',
    blurb     => "This plugin checks DNS nameservers resolution.",
    usage     => "Usage: %s -Q  -T  -S <SERVER1[,SERVER2 ...]> [-R [RDATA1[,RDATA2 ...]] [-w warn] [-c crit] [--debug]",
    timeout   => 15
);

$np->add_arg(
    spec     => 'query|Q=s',
    help     => '-Q ',
    required => 1
);

$np->add_arg(
    spec     => 'type|T=s',
    help     => '-T ',
    required => 1
);

$np->add_arg(
    spec     => 'servers|S=s',
    help     => '-S ',
    required => 1
);

$np->add_arg(
    spec     => 'rdatas|R=s',
    help     => '-R ',
    required => 0,
    default => ""
);

$np->add_arg(
    spec     => 'warn|w=i',
    help     => '-warn <time>',
    required => 0,
    default => 1000
);

$np->add_arg(
    spec     => 'crit|c=i',
    help     => '-crit <time>',
    required => 0,
    default => 1500
);

$np->add_arg(
    spec     => 'debug|d',
    help     => '--debug',
    required => 0,
    default => 0
);

$np->getopts;
alarm $np->opts->timeout;

my @servers = ("host");
my @rdatas = "";

@servers = split(",", $np->opts->servers) if (defined $np->opts->servers && $np->opts->servers ne "");

@rdatas = split(",", $np->opts->rdatas) if (defined $np->opts->rdatas && $np->opts->rdatas ne "");

my $max_time = 0;
my $index = 0;

foreach (@servers)
{
    my $server = $_;

    my $config = {
        Timeout   => 10,
        PeerAddr  => $server,
        PeerPort  => 53,
        Proto     => 'UDP',
        Recursion => 1
    };

    my $response = Net::DNS::Dig->new($config)->for($np->opts->query, $np->opts->type)
    or $np->nagios_exit(CRITICAL, $np->opts->query . "," . $np->opts->type . " - failed to resolve on server $server");

    $max_time = $response->{ELAPSED} if ($response->{ELAPSED} > $max_time);

    my (@results) = $response->rdata();
    my $found = 0;

    switch ($np->opts->type)
    {
        case "A"
        {
            foreach (@results)
            {
                my ($result) = inet_ntoa($_);
                $found++;

                if ((scalar @rdatas > 0) && ($rdatas[0] ne "") && (grep(/^$result$/, @rdatas) eq 0))
                {
                    $found = -1;
                    last;
                }
            }
        }

        case "AAAA"
        {
            foreach (@results)
            {
                my ($result) = inet_n2dx($_);
                $found++;

                if ((scalar @rdatas > 0) && ($rdatas[0] ne "") && (grep(/^$result$/, @rdatas) eq 0))
                {
                    $found = -1;
                    last;
                }
            }
        }

        else
        {
            foreach (@results)
            {
                my ($result) = $_;
                $found++;

                if ((scalar @rdatas > 0) && ($rdatas[0] ne "") && (grep(/^$result$/, @rdatas) eq 0))
                {
                    $found = -1;
                    last;
                }
            }
        }
    }

    $np->nagios_exit(CRITICAL, $np->opts->query . "," . $np->opts->type . " - unexpected rdata found on server $server") if ($found eq -1);
    $np->nagios_exit(CRITICAL, $np->opts->query . "," . $np->opts->type . " - none rdata found") if ($found eq 0);
    $np->nagios_exit(CRITICAL, $np->opts->query . "," . $np->opts->type . " - some rdatas not found") if ($found < $#rdatas);
    $np->add_perfdata(label => "server_$index", value => $response->{ELAPSED}, uom => "ms");
    $index++;

    $np->nagios_exit(CRITICAL, $np->opts->query . "," . $np->opts->type . " - slow resolution time from server $server") if ($response->{ELAPSED} >= $np->opts->crit);
    $np->nagios_exit(WARNING, $np->opts->query . "," . $np->opts->type . " - slow resolution time from server $server") if ($response->{ELAPSED} >= $np->opts->warn);
}

$np->nagios_exit(OK, $max_time . " ms maximum response time");

# END
$np->nagios_exit(UNKNOWN,"unexpected end of script");

Exemple d’utilisation :

root@muse:~# /usr/lib/nagios/plugins/check_dns -Q blog.hbis.fr -T A -S 173.246.97.2,217.70.184.40,217.70.182.20 -R 37.59.126.51 -d

DNS OK - 22 ms maximum response time | server_0=20ms;; server_1=20ms;; server_2=22ms;;

See also

Linux : règles iptables minimales
Read more
Munin-async : nettoyage des fichiers temporaires
Read more
Linux : nettoyer un répertoire contenant des milliers de fichiers
Read more