equal
deleted
inserted
replaced
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 |