1#!/usr/bin/perl 2# 3# $Id: Consistency.pm 749 2009-03-20 09:22:13Z calle $ 4# 5# Copyright (c) 2007 .SE (The Internet Infrastructure Foundation). 6# All rights reserved. 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions 10# are met: 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 21# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28# 29###################################################################### 30 31package DNSCheck::Test::Consistency; 32 33require 5.008; 34use warnings; 35use strict; 36 37our $SVN_VERSION = '$Revision: 749 $'; 38 39use base 'DNSCheck::Test::Common'; 40 41use Net::IP 1.25; 42use Digest::SHA1 qw(sha1 sha1_hex sha1_base64); 43 44###################################################################### 45 46sub test { 47 my $self = shift; 48 my $zone = shift; 49 50 my $parent = $self->parent; 51 my $qclass = $self->qclass; 52 my $logger = $self->logger; 53 my $errors = 0; 54 55 return unless $parent->config->should_run; 56 57 $logger->module_stack_push(); 58 $logger->auto("CONSISTENCY:BEGIN", $zone); 59 60 my %serial_counter; 61 my %digest_counter; 62 my %nameservers = (); 63 64 # fetch all nameservers, both from parent and child 65 my @ns_parent = $parent->dns->get_nameservers_at_parent($zone, $qclass); 66 my @ns_child = $parent->dns->get_nameservers_at_child($zone, $qclass); 67 68 foreach my $ns (@ns_parent, @ns_child) { 69 foreach my $address ($parent->dns->find_addresses($ns, $qclass)) { 70 my $ip = new Net::IP($address); 71 72 if ($ip->version == 4 and $parent->config->get("net")->{ipv4}) { 73 $nameservers{$address} = $address; 74 } 75 76 if ($ip->version == 6 and $parent->config->get("net")->{ipv6}) { 77 $nameservers{$address} = $address; 78 } 79 } 80 } 81 82 foreach my $address (keys %nameservers) { 83 my $packet = 84 $parent->dns->query_explicit($zone, $qclass, "SOA", $address); 85 86 next unless ($packet); 87 88 foreach my $rr ($packet->answer) { 89 next unless ($rr->type eq "SOA"); 90 91 my $serial = $rr->serial; 92 93 my $digest = sha1_hex( 94 join(':', 95 $rr->mname, $rr->rname, $rr->refresh, 96 $rr->retry, $rr->expire, $rr->minimum) 97 ); 98 99 $logger->auto("CONSISTENCY:SOA_SERIAL_AT_ADDRESS", 100 $address, $serial); 101 $logger->auto("CONSISTENCY:SOA_DIGEST_AT_ADDRESS", 102 $address, $digest); 103 104 $serial_counter{$serial}++; 105 $digest_counter{$digest}++; 106 } 107 } 108 109 my $unique_serials = scalar keys %serial_counter; 110 my $unique_digests = scalar keys %digest_counter; 111 112 if ($unique_serials > 1) { 113 $logger->auto("CONSISTENCY:SOA_SERIAL_DIFFERENT", $unique_serials); 114 } else { 115 $logger->auto("CONSISTENCY:SOA_SERIAL_CONSISTENT"); 116 } 117 118 if ($unique_digests > 1) { 119 $logger->auto("CONSISTENCY:SOA_DIGEST_DIFFERENT", $unique_digests); 120 } else { 121 $logger->auto("CONSISTENCY:SOA_DIGEST_CONSISTENT"); 122 } 123 124 DONE: 125 $logger->auto("CONSISTENCY:END", $zone); 126 $logger->module_stack_pop(); 127 128 return 0; 129} 130 1311; 132 133__END__ 134 135 136=head1 NAME 137 138DNSCheck::Test::Consistency - Test zone consistency 139 140=head1 DESCRIPTION 141 142Test zone consistency. The following tests are made: 143 144=over 4 145 146=item * 147The serial number of the zone must be the same at all listed name servers. 148 149=back 150 151=head1 METHODS 152 153=over 154 155=item ->test($zonename) 156 157Check that the SOA records retrieved from all nameservers for the zone contain 158the same information (that is, the same serial number and the same timeout 159values). 160 161=back 162 163=head1 EXAMPLES 164 165=head1 SEE ALSO 166 167L<DNSCheck>, L<DNSCheck::Logger> 168 169=cut 170