Nagios : sonde check DNS

Boris HUISGEN
Boris HUISGEN
|

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;;
Boris HUISGEN
Boris HUISGEN
Blog owner
  • #dns
  • #nagios