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 |