plugins/check_dns-serial
changeset 2 2d11bbd7be1e
parent 1 cff9b7e57f19
child 3 9ce7eb4a39c3
equal deleted inserted replaced
1:cff9b7e57f19 2:2d11bbd7be1e
     3 use strict;
     3 use strict;
     4 use warnings;
     4 use warnings;
     5 use Getopt::Long qw(GetOptionsFromArray);
     5 use Getopt::Long qw(GetOptionsFromArray);
     6 use Net::DNS;
     6 use Net::DNS;
     7 use Pod::Usage;
     7 use Pod::Usage;
     8 
       
     9 
     8 
    10 my %resolver;
     9 my %resolver;
    11 sub uniq { my %h; @h{@_} = (); return keys %h; }
    10 sub uniq { my %h; @h{@_} = (); return keys %h; }
    12 
    11 
    13 sub get_domains {
    12 sub get_domains {
    32 sub get_ns {
    31 sub get_ns {
    33     my ($nameserver) = map { /^\@(.*)/ } $_[0] =~ /^\@/ ? shift : '@8.8.8.8';
    32     my ($nameserver) = map { /^\@(.*)/ } $_[0] =~ /^\@/ ? shift : '@8.8.8.8';
    34     my ($domain) = @_;
    33     my ($domain) = @_;
    35     my @ns;
    34     my @ns;
    36 
    35 
    37     my $r = $resolver{$nameserver} //= Net::DNS::Resolver->new(nameservers => [$nameserver]);
    36     my $r = $resolver{$nameserver} //=
       
    37       Net::DNS::Resolver->new(nameservers => [$nameserver]);
    38     my $q = $r->query($domain, 'NS') or die $r->errorstring, "\n";
    38     my $q = $r->query($domain, 'NS') or die $r->errorstring, "\n";
    39     push @ns, map { $_->nsdname } grep { $_->type eq 'NS' } $q->answer;
    39     push @ns, map { $_->nsdname } grep { $_->type eq 'NS' } $q->answer;
    40 
    40 
    41     return sort @ns;
    41     return sort @ns;
    42 }
    42 }
    44 sub get_serial {
    44 sub get_serial {
    45     my ($nameserver) = map { /^\@(.*)/ } $_[0] =~ /^\@/ ? shift : '@8.8.8.8';
    45     my ($nameserver) = map { /^\@(.*)/ } $_[0] =~ /^\@/ ? shift : '@8.8.8.8';
    46     my ($domain) = shift;
    46     my ($domain) = shift;
    47 
    47 
    48     my $r = $resolver{$nameserver} //=
    48     my $r = $resolver{$nameserver} //=
    49     Net::DNS::Resolver->new(nameservers => [$nameserver]);
    49       Net::DNS::Resolver->new(nameservers => [$nameserver]);
    50     my $q = $r->query($domain, 'SOA') or die $r->errorstring, "\n";
    50     my $q = $r->query($domain, 'SOA') or die $r->errorstring, "\n";
    51     return (map { $_->serial } grep { $_->type eq 'SOA' } $q->answer)[0];
    51     return (map { $_->serial } grep { $_->type eq 'SOA' } $q->answer)[0];
    52 }
    52 }
    53 
    53 
    54 # - the nameservers known from the ns records
    54 # - the nameservers known from the ns records
    65 
    65 
    66     my @our = sort eval { get_ns($reference, $domain) };
    66     my @our = sort eval { get_ns($reference, $domain) };
    67     my @their = sort +get_ns($domain);
    67     my @their = sort +get_ns($domain);
    68 
    68 
    69     {
    69     {
    70 	local $" = "\0";
    70         local $" = "\0";
    71 	return 1 if "@our" eq "@their"; 
    71         return 1 if "@our" eq "@their";
    72     }
    72     }
    73 
    73 
    74     local $" = ', ';
    74     local $" = ', ';
    75     die "NS differ (our @our) vs (their @their)\n";
    75     die "NS differ (our @our) vs (their @their)\n";
    76 };
    76 }
    77 
    77 
    78 sub main {
    78 sub main {
    79     my @argv = @_;
    79     my @argv          = @_;
    80     my $opt_reference = '212.80.235.130';
    80     my $opt_reference = '212.80.235.130';
    81     my $opt_progress = -t;
    81     my $opt_progress  = -t;
    82 
    82 
    83     GetOptionsFromArray(\@argv,
    83     GetOptionsFromArray(
    84 	'reference=s' => \$opt_reference) 
    84         \@argv,
    85     and @argv or pod2usage;
    85 ## Please see file perltidy.ERR
       
    86 ## Please see file perltidy.ERR
       
    87         'reference=s' => \$opt_reference,
       
    88         'progress!'   => \$opt_progress,
       
    89         'h|help'      => sub { pod2usage(-verbose => 1, -exit => 0) },
       
    90         'm|man'       => sub {
       
    91             pod2usage(
       
    92                 -verbose   => 2,
       
    93                 -exit      => 0,
       
    94                 -noperldoc => system('perldoc -V 2>/dev/null 1>&2')
       
    95             );
       
    96         }
       
    97       )
       
    98       and @argv
       
    99       or pod2usage;
    86     my @domains = get_domains(@argv);
   100     my @domains = get_domains(@argv);
    87 
   101 
    88     my (@OK, %CRITICAL);
   102     my (@OK, %CRITICAL);
    89     foreach my $domain (@domains) {
   103     foreach my $domain (@domains) {
    90 	print STDERR "$domain " if $opt_progress;
   104         print STDERR "$domain " if $opt_progress;
    91 	eval { ns_ok('@212.80.235.130', $domain) };
   105         eval { ns_ok('@212.80.235.130', $domain) };
    92 	if ($@) { $CRITICAL{$domain} = $@ }
   106         if ($@) { $CRITICAL{$domain} = $@ }
    93 	else { push @OK, $domain }
   107         else    { push @OK, $domain }
    94 	say STDERR $@ ? 'not ok' : 'ok' if $opt_progress;
   108         say STDERR $@ ? 'not ok' : 'ok' if $opt_progress;
    95     }
   109     }
    96 
   110 
    97 #    use DDP;
   111     #    use DDP;
    98 #    p @OK;
   112     #    p @OK;
    99 #    p %CRITICAL;
   113     #    p %CRITICAL;
   100 
   114 
   101     if (my $n = keys %CRITICAL) {
   115     if (my $n = keys %CRITICAL) {
   102 	print "CRITICAL: $n of ".@domains." domains\n", map { "$_: $CRITICAL{$_}" } sort keys %CRITICAL;
   116         print "CRITICAL: $n of " . @domains . " domains\n",
   103 	return 2;
   117           map { "$_: $CRITICAL{$_}" } sort keys %CRITICAL;
       
   118         return 2;
   104     }
   119     }
   105 
   120 
   106     say 'OK: ' . @OK . ' domains checked';
   121     say 'OK: ' . @OK . ' domains checked';
   107     return 0;
   122     return 0;
   108 
   123