plugins/check_dns-delegation
changeset 15 bb7b3ae76cc8
parent 14 8da9e81acf82
child 16 6d401297850b
equal deleted inserted replaced
14:8da9e81acf82 15:bb7b3ae76cc8
    67     sub new {
    67     sub new {
    68         my $class = shift;
    68         my $class = shift;
    69         state %cache;
    69         state %cache;
    70         return $cache{freeze \@_} //= $class->SUPER::new(@_);
    70         return $cache{freeze \@_} //= $class->SUPER::new(@_);
    71     }
    71     }
       
    72 }
       
    73 
       
    74 sub read_override {    # YEAH! :) black magic
       
    75     local @ARGV = shift;
       
    76     return map { (shift $_, $_) } grep { @$_ > 1 } map { [split] } map { s/#.*//r } <>;
    72 }
    77 }
    73 
    78 
    74 # return a list of the zones known to the local
    79 # return a list of the zones known to the local
    75 # bind
    80 # bind
    76 sub get_local_zones {
    81 sub get_local_zones {
   120 sub ns {
   125 sub ns {
   121     my $domain = shift;
   126     my $domain = shift;
   122     ### assert: @_ % 2 == 0
   127     ### assert: @_ % 2 == 0
   123     my %resflags = (nameservers => \@extns, @_);
   128     my %resflags = (nameservers => \@extns, @_);
   124     my $aa = delete $resflags{aa};
   129     my $aa = delete $resflags{aa};
       
   130     my $override = delete $resflags{override};
   125     my $nameservers = join ',' => @{$resflags{nameservers}};
   131     my $nameservers = join ',' => @{$resflags{nameservers}};
   126     my @ns;
   132     my @ns;
       
   133 
       
   134     return sort @{$override->{$domain}} if exists $override->{$domain};
   127 
   135 
   128     my $r = Net::DNS::Resolver->new(%resflags);
   136     my $r = Net::DNS::Resolver->new(%resflags);
   129     my $q;
   137     my $q;
   130 
   138 
   131     for (my $i = 3; $i; --$i) {
   139     for (my $i = 3; $i; --$i) {
   163 # OK - if the serial numbers are in sync
   171 # OK - if the serial numbers are in sync
   164 # WARNING - if there is some difference
   172 # WARNING - if there is some difference
   165 # CRITICAL - if the serial cannot be found at one of the sources
   173 # CRITICAL - if the serial cannot be found at one of the sources
   166 
   174 
   167 sub ns_ok {
   175 sub ns_ok {
   168     my ($domain, $reference) = @_;
   176     my ($domain, $reference, $override) = @_;
   169 
   177 
   170     my (@errs, @ns);
   178     my (@errs, @ns);
   171     my @our = eval { sort +ns($domain, nameservers => [$reference], aa => 1) };
   179     my @our = eval { sort +ns($domain, nameservers => [$reference], aa => 1, override => $override) };
   172     push @errs, $@ if $@;
   180     push @errs, $@ if $@;
   173 
   181 
   174     my @their = eval { sort +ns($domain) };
   182     my @their = eval { sort +ns($domain) };
   175     push @errs, $@ if $@;
   183     push @errs, $@ if $@;
   176 
   184 
   179         die join(', ' => @errs) . "\n";
   187         die join(', ' => @errs) . "\n";
   180     }
   188     }
   181     
   189     
   182     if ("@our" ne "@their") {
   190     if ("@our" ne "@their") {
   183         local $" = ', ';
   191         local $" = ', ';
   184         die "NS differ (our @our) vs (their @their)\n";
   192         die sprintf "NS differ (%s @our) vs (public @their)\n",
       
   193             $override->{$domain} ? 'override' : 'our';
   185     }
   194     }
   186 
   195 
   187     @ns = uniq sort @our, @their;
   196     @ns = uniq sort @our, @their;
   188     ### @ns
   197     ### @ns
   189     return @ns;
   198     return @ns;
   204 
   213 
   205 sub main {
   214 sub main {
   206     my @argv          = @_;
   215     my @argv          = @_;
   207     my $opt_reference = '127.0.0.1';
   216     my $opt_reference = '127.0.0.1';
   208     my $opt_progress  = -t;
   217     my $opt_progress  = -t;
       
   218     my ($opt_override)= grep { -f } '/etc/bind/zones.override';
       
   219                         
   209 
   220 
   210     GetOptionsFromArray(
   221     GetOptionsFromArray(
   211         \@argv,
   222         \@argv,
   212         'reference=s' => \$opt_reference,
   223         'reference=s' => \$opt_reference,
   213         'progress!'   => \$opt_progress,
   224         'progress!'   => \$opt_progress,
       
   225         'override=s'  => \$opt_override,
   214         'h|help'      => sub { pod2usage(-verbose => 1, -exit => 0) },
   226         'h|help'      => sub { pod2usage(-verbose => 1, -exit => 0) },
   215         'm|man'       => sub {
   227         'm|man'       => sub {
   216             pod2usage(
   228             pod2usage(
   217                 -verbose   => 2,
   229                 -verbose   => 2,
   218                 -exit      => 0,
   230                 -exit      => 0,
   221         }
   233         }
   222       )
   234       )
   223       and @argv
   235       and @argv
   224       or pod2usage;
   236       or pod2usage;
   225     my @domains = get_domains(@argv);
   237     my @domains = get_domains(@argv);
       
   238     my %override = read_override($opt_override) if defined $opt_override;
   226 
   239 
   227     my (@OK, %CRITICAL);
   240     my (@OK, %CRITICAL);
   228     foreach my $domain (@domains) {
   241     foreach my $domain (@domains) {
   229         print STDERR "$domain " if $opt_progress;
   242         print STDERR "$domain " if $opt_progress;
   230 
   243 
   231         my @ns = eval { ns_ok($domain, $opt_reference) };
   244         my @ns = eval { ns_ok($domain, $opt_reference, \%override) };
   232 	if ($@) { 
   245 	if ($@) { 
   233             $CRITICAL{$domain} = $@;
   246             $CRITICAL{$domain} = $@;
   234             say STDERR 'fail(ns)' if $opt_progress;
   247             say STDERR 'fail(ns)' if $opt_progress;
   235             next;
   248             next;
   236         }
   249         }
   276 
   289 
   277 =item B<--progress>
   290 =item B<--progress>
   278 
   291 
   279 Tell about the progress. (default: on if input is connected to a terminal)
   292 Tell about the progress. (default: on if input is connected to a terminal)
   280 
   293 
   281 =item B<--additional>
   294 =item B<--override>=I<override file>
   282 
   295 
   283 Domains from this list are
   296 This file lists NS names for domains. Instead of trusting our own server
       
   297 we use the NS listed as the authoritive ones. This is primarly useful for
       
   298 some of these domains that are held on the "pending" servers of joker.
   284 
   299 
   285 =back
   300 =back
       
   301 
       
   302 =head2 Format
       
   303 
       
   304  # comment
       
   305  <domain> <ns> ... # comment
       
   306 
   286 
   307 
   287 =head1 PERMISSIONS
   308 =head1 PERMISSIONS
   288 
   309 
   289 No special permissions are necessary, except for the domain-list URL F<local:>, since
   310 No special permissions are necessary, except for the domain-list URL F<local:>, since
   290 the output of C<named-checkconf -p> is read. This may fail, depending on the configuration of 
   311 the output of C<named-checkconf -p> is read. This may fail, depending on the configuration of