added local: option for named-checkconf -p
authorHeiko Schlittermann (JUMPER) <hs@schlittermann.de>
Tue, 30 Dec 2014 12:24:43 +0100
changeset 4 ebada07bb701
parent 3 9ce7eb4a39c3
child 5 2e27cfdf85ea
added local: option for named-checkconf -p
plugins/check_dns-serial
--- a/plugins/check_dns-serial	Tue Dec 30 09:42:07 2014 +0100
+++ b/plugins/check_dns-serial	Tue Dec 30 12:24:43 2014 +0100
@@ -1,5 +1,6 @@
 #! /usr/bin/perl
 # © 2014 Heiko Schlittermann <hs@schlittermann.de>
+
 =head1 NAME
 
  check_dns-serial - check the dns serial number from multiple sources
@@ -15,6 +16,26 @@
 
 Domains we are not responsible for are marked as B<critical>.
 
+The list of domains may consist of the following items:
+
+=over
+
+=item I<domain>
+
+A plain domain name.
+
+=item B<file://>I<file>
+
+A file name containing the domains, line by line.
+
+=item B<local:>
+
+This item uses the output of C<named-checkconf -p> to get the list of
+master/slave zones. The 127.in-addr.arpa, 168.192.in-addr.arpa, and
+0.in-addr.arpa, and 127.in-addr.arpa zones are suppressed.
+
+=back
+
 =cut
 
 use 5.014;
@@ -27,6 +48,28 @@
 my %resolver;
 sub uniq { my %h; @h{@_} = (); return keys %h; }
 
+# return a list of the zones known to the local
+# bind
+sub get_local_zones {
+    my @conf;
+    open(my $z, '-|', 'named-checkconf -p');
+    while (<$z>) {
+        state $line;
+        s/^\s*(.*?)\s*$/$1 /;
+        chomp($line .= $_);    # continuation line
+        if (/\A\}/) {          # config item done
+            $line =~ s/\s$//;
+            push @conf, $line;
+            $line = '';
+        }
+    }
+    return grep { 
+	# FIXME: 172.0 .. 172.31 is missing
+	not /^\b(?:0|127|10|168\.192|255)\.in-addr\.arpa$/ and
+	not /^localhost$/;
+    } map { /zone\s"(\S+)"\s/ } grep { /type (?:master|slave)/ } @conf;
+}
+
 sub get_domains {
     my @sources = @_;
     my @domains = ();
@@ -39,6 +82,11 @@
             next;
         }
 
+        if ($src =~ m{^local:}) {
+            push @domains, get_local_zones;
+            next;
+        }
+
         push @domains, $src;
     }
 
@@ -53,7 +101,7 @@
 
     my $r = $resolver{$nameserver} //=
       Net::DNS::Resolver->new(nameservers => [$nameserver]);
-    my $q = $r->query($domain, 'NS') or die $r->errorstring, "\n";
+    my $q = $r->query($domain, 'NS') or die $r->errorstring, "\@$nameserver\n";
     push @ns, map { $_->nsdname } grep { $_->type eq 'NS' } $q->answer;
 
     return sort @ns;
@@ -65,7 +113,7 @@
 
     my $r = $resolver{$nameserver} //=
       Net::DNS::Resolver->new(nameservers => [$nameserver]);
-    my $q = $r->query($domain, 'SOA') or die $r->errorstring, "\n";
+    my $q = $r->query($domain, 'SOA') or die $r->errorstring, "\@$nameserver\n";
     return (map { $_->serial } grep { $_->type eq 'SOA' } $q->answer)[0];
 }