92 |
92 |
93 return @domains; |
93 return @domains; |
94 } |
94 } |
95 |
95 |
96 # return a list of "official" nameservers |
96 # return a list of "official" nameservers |
97 sub get_ns { |
97 sub ns { |
98 my ($nameserver) = map { /^\@(.*)/ } $_[0] =~ /^\@/ ? shift : '@8.8.8.8'; |
98 my $domain = shift; |
99 my ($domain) = @_; |
99 ### assert: @_ % 2 == 0 |
|
100 my %resflags = (nameservers => [qw/8.8.8.8/], @_); |
|
101 my $aa = delete $resflags{aa}; |
|
102 my $nameservers = $resflags{nameservers}; |
100 my @ns; |
103 my @ns; |
101 |
104 |
102 my $r = $resolver{$nameserver} //= |
105 my $r = Net::DNS::Resolver->new(%resflags); |
103 Net::DNS::Resolver->new(nameservers => [$nameserver]); |
106 my $q = $r->query($domain, 'NS') or die $r->errorstring, "\@@$nameservers\n"; |
104 my $q = $r->query($domain, 'NS') or die $r->errorstring, "\@$nameserver\n"; |
107 |
|
108 die "no aa @@$nameservers\n" if $aa and not $q->header->aa; |
105 push @ns, map { $_->nsdname } grep { $_->type eq 'NS' } $q->answer; |
109 push @ns, map { $_->nsdname } grep { $_->type eq 'NS' } $q->answer; |
106 |
110 |
107 return sort @ns; |
111 return sort @ns; |
108 } |
112 } |
109 |
113 |
110 sub get_serial { |
114 sub serial { |
111 my ($nameserver) = map { /^\@(.*)/ } $_[0] =~ /^\@/ ? shift : '@8.8.8.8'; |
115 my $domain = shift; |
112 my ($domain) = shift; |
116 my %resflags = (nameservers => [qw/8.8.8.8/], @_); |
113 |
117 my $nameservers = $resflags{nameservers}; |
114 my $r = $resolver{$nameserver} //= |
118 |
115 Net::DNS::Resolver->new(nameservers => [$nameserver]); |
119 my $r = Net::DNS::Resolver->new(%resflags); |
116 my $q = $r->query($domain, 'SOA') or die $r->errorstring, "\@$nameserver\n"; |
120 my $q = $r->query($domain, 'SOA') or die $r->errorstring, "\@@$nameservers\n"; |
117 return (map { $_->serial } grep { $_->type eq 'SOA' } $q->answer)[0]; |
121 return (map { $_->serial } grep { $_->type eq 'SOA' } $q->answer)[0]; |
118 } |
122 } |
119 |
123 |
120 # - the nameservers known from the ns records |
124 # - the nameservers known from the ns records |
121 # - from the primary master if this is not one of the |
125 # - from the primary master if this is not one of the |
125 # OK - if the serial numbers are in sync |
129 # OK - if the serial numbers are in sync |
126 # WARNING - if there is some difference |
130 # WARNING - if there is some difference |
127 # CRITICAL - if the serial cannot be found at one of the sources |
131 # CRITICAL - if the serial cannot be found at one of the sources |
128 |
132 |
129 sub ns_ok { |
133 sub ns_ok { |
130 my ($reference, $domain) = @_; |
134 my ($domain, $reference) = @_; |
131 |
135 |
132 my @our = sort eval { get_ns($reference, $domain) }; |
136 my @our = sort +ns($domain, nameservers => [$reference], aa => 1); |
133 my @their = sort +get_ns($domain); |
137 my @their = sort +ns($domain); |
134 |
138 |
135 { |
139 { |
136 local $" = "\0"; |
140 local $" = "\0"; |
137 return 1 if "@our" eq "@their"; |
141 return 1 if "@our" eq "@their"; |
138 } |
142 } |
146 my $opt_reference = '127.0.0.1'; |
150 my $opt_reference = '127.0.0.1'; |
147 my $opt_progress = -t; |
151 my $opt_progress = -t; |
148 |
152 |
149 GetOptionsFromArray( |
153 GetOptionsFromArray( |
150 \@argv, |
154 \@argv, |
151 ## Please see file perltidy.ERR |
|
152 ## Please see file perltidy.ERR |
|
153 'reference=s' => \$opt_reference, |
155 'reference=s' => \$opt_reference, |
154 'progress!' => \$opt_progress, |
156 'progress!' => \$opt_progress, |
155 'h|help' => sub { pod2usage(-verbose => 1, -exit => 0) }, |
157 'h|help' => sub { pod2usage(-verbose => 1, -exit => 0) }, |
156 'm|man' => sub { |
158 'm|man' => sub { |
157 pod2usage( |
159 pod2usage( |
166 my @domains = get_domains(@argv); |
168 my @domains = get_domains(@argv); |
167 |
169 |
168 my (@OK, %CRITICAL); |
170 my (@OK, %CRITICAL); |
169 foreach my $domain (@domains) { |
171 foreach my $domain (@domains) { |
170 print STDERR "$domain " if $opt_progress; |
172 print STDERR "$domain " if $opt_progress; |
171 eval { ns_ok('@212.80.235.130', $domain) }; |
173 eval { ns_ok($domain, $opt_reference) }; |
172 if ($@) { $CRITICAL{$domain} = $@ } |
174 if ($@) { $CRITICAL{$domain} = $@ } |
173 else { push @OK, $domain } |
175 else { push @OK, $domain } |
174 say STDERR $@ ? 'not ok' : 'ok' if $opt_progress; |
176 say STDERR $@ ? 'not ok' : 'ok' if $opt_progress; |
175 } |
177 } |
176 |
178 |