######################################################## # Please file all bug reports, patches, and feature # requests under: # https://sourceforge.net/p/logwatch/_list/tickets # Help requests and discusion can be filed under: # https://sourceforge.net/p/logwatch/discussion/ ######################################################## ##################################################### ## Copyright (c) 2008 Kirk Bauer ## Covered under the included MIT/X-Consortium License: ## http://www.opensource.org/licenses/mit-license.php ## All modifications and contributions by other persons to ## this script are assumed to have been donated to the ## Logwatch project and thus assume the above copyright ## and licensing terms. If you want to make contributions ## under your own copyright or a different license this ## must be explicitly stated in the contribution an the ## Logwatch project reserves the right to not accept such ## contributions. If you have made significant ## contributions to this script and want to claim ## copyright please contact logwatch-devel@lists.sourceforge.net. ######################################################### use Logwatch ':ip'; use strict; DoLookup( ValueOrDefault($ENV{'named_ip_lookup'}, 0) ); my $Debug = ValueOrDefault($ENV{'LOGWATCH_DEBUG'}, 0); my $Detail = ValueOrDefault($ENV{'LOGWATCH_DETAIL_LEVEL'}, 0); my $FailedZoneTransferThreshold = $ENV{'failed_zone_transfer_threshold'} || 0; #Init Counters my $DebugCounter= my $StartNamed= my $ReloadNamed= my $ShutdownNamed= my $ShutdownNamedFail= 0; #Init String Containers my ( $Address, $Host, $Zone, $Addr, $CCC, $Entry, $Error, $File, $From, $Hint, $Ldom, $Line, $Log, $Name, $Net, $Problem, $Reason, $Response, $Rhost, $Server, $Channel, $Client, $ErrorText, $Message, $RR, $Rcode, $Source, $ViewName, $Way, $Master, ); #Init Arrays my @CNAMEAndOther = (); #Init Hashes my ( %AXFR, %BadZone, %ChannelAddFail, %ConnectionRefused, %DeferredZoneTransfers, %DeniedQuery, %DeniedQueryNoCache, %DeniedTCPClient, %DeniedZoneTransfers, %FailedZoneTransfers, %FormErr, %InsecUpdate, %JournalFail, %LameServer, %MasterFailure, %NetworkUnreachable, %NonAuthoritative, %RetryLimit, %UnexpRCODE, %UpdateDenied, %UpdateForwardingDenied, %ZoneExpired, %ZoneFileErrors, %ZoneLoaded, %ZoneReceivedNotify, %ZoneRefusedNotify, %ZoneRemoved, %ZoneUpdates, %Limit, %LimitDrop, %CCCommands, %CCMessages, %CCMessages2, %ConfProb, %DNSSECBadCache, %DNSSECError, %DNSSECInsec, %DNSSECInvalid, %ErrOpenFiles, %GeoIPError, %HUR, %Hints, %LimitSlip, %NError, %NUR, %NoSOA, %OtherList, %StartLog, %UnknownCCCommands, %BadCookie, %Timeout, %LoopDetected, %MissingCookie, ); # Avoid "Use of uninitialized value" warning messages. sub ValueOrDefault { my ($value, $default) = @_; return ($value ? $value : $default); } if ( $Debug >= 5 ) { print STDERR "\n\nDEBUG: Inside NAMED Filter \n\n"; $DebugCounter = 1; } while (defined(my $ThisLine = )) { if ( $Debug >= 30 ) { print STDERR "DEBUG($DebugCounter): $ThisLine"; $DebugCounter++; } if ( ($ThisLine =~ /RR negative cache entry/) or ($ThisLine =~ /ns_....: .* NS points to CNAME/) or ($ThisLine =~ /accept: connection reset by peer/) or ($ThisLine =~ /Connection reset by peer/) or # typo fixed in 2004 release ($ThisLine =~ /transfer(r)?ed serial/) or ($ThisLine =~ /There may be a name server already running/) or ($ThisLine =~ /exiting/) or ($ThisLine =~ /running/) or ($ThisLine =~ /NSTATS /) or ($ThisLine =~ /Cleaned cache of \d+ RRs/) or ($ThisLine =~ /max-cache-size .* setting to /) or ($ThisLine =~ /USAGE \d+ \d+ CPU=\d+.*/) or ($ThisLine =~ /XSTATS /) or ($ThisLine =~ /Ready to answer queries/) or ($ThisLine =~ /Forwarding source address is/) or ($ThisLine =~ /bad referral/) or ($ThisLine =~ /prerequisite not satisfied/) or ($ThisLine =~ /(rcvd|Sent) NOTIFY/) or ($ThisLine =~ /ns_resp: TCP truncated/) or ($ThisLine =~ /No possible A RRs/) or ($ThisLine =~ /points to a CNAME/) or ($ThisLine =~ /dangling CNAME pointer/) or ($ThisLine =~ /listening on/) or ($ThisLine =~ /unrelated additional info/) or ($ThisLine =~ /Response from unexpected source/) or ($ThisLine =~ /No root nameservers for class IN/) or ($ThisLine =~ /recvfrom: No route to host/) or # Be sure to catch: transfer of 'zone' from IP#53: failed to connect: timed out # not exact just triggers a full transfer ($ThisLine =~ /transfer of .*: (:?IXFR|AXFR(:?|-style IXFR) (:?started|ended)|connected using|failed while receiving responses: not exact)/) or # This will generate another error that we will catch ($ThisLine =~ /transfer of .*: resetting/) or ($ThisLine =~ /Transfer status: (:?success|up to date)/) or ($ThisLine =~ /using \d+ CPU/) or ($ThisLine =~ /loading configuration/) or ($ThisLine =~ /command channel listening/) or ($ThisLine =~ /configuring command channel from/) or ($ThisLine =~ /interface ignored/) or ($ThisLine =~ /no IPv6 interfaces found/) or ($ThisLine =~ /IPv6 socket API is incomplete; explicitly binding to each IPv6 address separately/) or ($ThisLine =~ /using \d+ UDP listeners? per interface/) or ($ThisLine =~ /^running/) or ($ThisLine =~ /^exiting/) or ($ThisLine =~ /no longer listening/) or ($ThisLine =~ /the default for the .* option is now/) or ($ThisLine =~ /stopping command channel on \S+/) or ($ThisLine =~ /Malformed response from/) or ($ThisLine =~ /client .* response from Internet for .*/) or # ($ThisLine =~ /client .+ query \(cache\) '.*' denied/) or ($ThisLine =~ /client .+(?: \([^)]+\))?: query:/) or # Do we really want to ignore these? #($ThisLine =~ /unknown logging category/) or ($ThisLine =~ /could not open entropy source/) or ($ThisLine =~ /\/etc\/rndc.key: file not found/) or ($ThisLine =~ /rpz QNAME NODATA rewrite \S+ via/) or ($ThisLine =~ /sending notifies/) or # file syntax error get reported twice and are already caught below ($ThisLine =~ /loading master file/) or ($ThisLine =~ /^ succeeded$/) or ($ThisLine =~ /\*\*\* POKED TIMER \*\*\*/) or # The message about the end of transfer is the interesting one ($ThisLine =~ /: Transfer started./) or ($ThisLine =~ /D-BUS service (disabled|enabled)./) or ($ThisLine =~ /D-BUS dhcdbd subscription disabled./) or ($ThisLine =~ /automatic empty zone/) or ($ThisLine =~ /binding TCP socket: address in use/) or ($ThisLine =~ /dbus_mgr initialization failed. D-BUS service is disabled./) or ($ThisLine =~ /dbus_svc_add_filter failed/) or ($ThisLine =~ /isc_log_open 'named.run' failed: permission denied/) or ($ThisLine =~ /weak RSASHA1 \(5\) key found \(exponent=3\)/) or ($ThisLine =~ /Bad file descriptor/) or ($ThisLine =~ /open: .*: file not found/) or ($ThisLine =~ /queries: client [\.0-9a-fA-F#:]* view localhost_resolver: query: .* IN .*/) or ($ThisLine =~ /zone .*: NS '.*' is a CNAME \(illegal\)/) or ($ThisLine =~ /skipping nameserver '.*' because it is a CNAME,/) or ($ThisLine =~ /zone .*: zone serial unchanged. zone may fail to transfer to slaves/) or ($ThisLine =~ /zone .*: loading from master file .* failed/) or ($ThisLine =~ /zone .*: NS '.*' has no address records/) or ($ThisLine =~ /zone .* \(signed\): receive_secure_serial: unchanged/) or ($ThisLine =~ /.*: not a valid number$/) or ($ThisLine =~ /^(.*: )?unexpected end of input/) or ($ThisLine =~ /too many timeouts resolving '.*' .*: disabling EDNS/) or ($ThisLine =~ /too many timeouts resolving '.*' .*: reducing the advertised EDNS UDP packet size to .* octets/) or ($ThisLine =~ /reloading zones succeeded/) or ($ThisLine =~ /generating session key/) or ($ThisLine =~ /success resolving '.*' \(in '.*'?\) after disabling EDNS/) or ($ThisLine =~ /success resolving '.*' after disabling qname minimization due to '(failure|ncache nxdomain)'/) or ($ThisLine =~ /the working directory is not writable/) or ($ThisLine =~ /using default UDP\/IPv[46] port range: \[[0-9]*, [0-9]*\]/) or ($ThisLine =~ /adjusted limit on open files from [0-9]* to [0-9]*/) or ($ThisLine =~ /using up to [0-9]* sockets/) or ($ThisLine =~ /built with/) or ($ThisLine =~ /compiled (by|with)/) or ($ThisLine =~ /linked to/) or ($ThisLine =~ /threads support is /) or ($ThisLine =~ /TTL differs in rdataset, adjusting [0-9]* -> [0-9]*/) or ($ThisLine =~ /max open files \([0-9]*\) is smaller than max sockets \([0-9]*\)/) or ($ThisLine =~ /clients-per-query (?:de|in)creased to .*/) or ($ThisLine =~ /^must-be-secure resolving '.*': .*/) or ($ThisLine =~ /^(error \()?no valid (DS|KEY|RRSIG)\)? resolving '.*': .*/) or ($ThisLine =~ /^not insecure resolving '.*': .*/) or ($ThisLine =~ /^validating \@0x[[:xdigit:]]+: .* DS: must be secure failure/) or ($ThisLine =~ /^(error \()?broken trust chain\)? resolving '.*': .*/) or ($ThisLine =~ /dumping all zones, removing journal files: success/) or ($ThisLine =~ /journal file [^ ]* does not exist, creating it/) or ($ThisLine =~ /master .* deleted from unreachable cache/) or ($ThisLine =~ /serial number \(\d+\) received from master/) or ($ThisLine =~ /zone .*: skipping zone transfer as master .* is unreachable \(cached\)/) or ($ThisLine =~ /zone .*: notify from .*: serial \d+/) or ($ThisLine =~ /zone [^:]+: serial \d+/) or ($ThisLine =~ /zone is up to date/) or ($ThisLine =~ /refresh in progress, refresh check queued/) or ($ThisLine =~ /refresh: NODATA response from master/) or ($ThisLine =~ /update with no effect/) or ($ThisLine =~ /reading built-in trusted keys from file/) or ($ThisLine =~ /reading built-in trust anchors from file/) or ($ThisLine =~ /using built-in trusted-keys/) or ($ThisLine =~ /using built-in keys instead/) or ($ThisLine =~ /set up managed keys zone/) or ($ThisLine =~ /managed-keys-zone.*[Kk]ey .*now trusted/) or ($ThisLine =~ /forwarding update for zone/) or ($ThisLine =~ /forwarded dynamic update: master [^ ]* returned: (NXRRSET|YXDOMAIN)/) or ($ThisLine =~ /using .* as GeoIP directory/) or ($ThisLine =~ /GEO-.* Build/) or ($ThisLine =~ /initializing GeoIP /) or ($ThisLine =~ /looking for GeoIP2? databases in /) or ($ThisLine =~ /opened GeoIP2? database /) or # the following seems okay since it says "success" ($ThisLine =~ /managed-keys-zone.*: No DNSKEY RRSIGs found for '.*': success/) or # the following seems to happen on startup ($ThisLine =~ /managed-keys-zone.*: Unable to fetch DNSKEY set '.*': operation canceled/) or ($ThisLine =~ /managed-keys-zone.*: Unable to fetch DNSKEY set '.*': timed out/) or ($ThisLine =~ /^sizing zone task pool based on \d+ zones/) or ($ThisLine =~ /^BIND \d+ is maintained by Internet Systems Consortium/) or ($ThisLine =~ /a non-profit 501/) or ($ThisLine =~ /corporation. Support and training for BIND \d+ are/) or ($ThisLine =~ /available at https:\/\/www.isc.org\/support/) or ($ThisLine =~ /----------------------------------------------------/) or ($ThisLine =~ /^[^ ]+ algorithms: /) or ($ThisLine =~ /^TKEY mode \d+ support /) or ($ThisLine =~ /next key event: /) or ($ThisLine =~ /reconfiguring zone keys/) or ($ThisLine =~ /using built-in DLV key/) or ($ThisLine =~ /trust-anchor-telemetry/) or ($ThisLine =~ /^adb: grow_entries /) or # ($ThisLine =~ /reading built-in trusted keys from file/) or ($ThisLine =~ /all zones loaded/) or ($ThisLine =~ /resolver priming query complete/) or ($ThisLine =~ /client .* signer .* approved/) or ($ThisLine =~ /stop limiting/) or # Previous line appears to contain the error ($ThisLine =~ /client .*: query failed .* for .* at /) or ($ThisLine =~ /increase from .* to .* RRL bins for .* entries/) or ($ThisLine =~ /flushing caches in all views succeeded/) or ($ThisLine =~ /automatic interface scanning terminated/) or # ignore this line because the following line describes the error ($ThisLine =~ /unexpected error/) ) { # Don't care about these... } elsif ( ($ThisLine =~ /starting\..*named/) or ($ThisLine =~ /starting BIND/) or ($ThisLine =~ /named startup succeeded/) ) { $StartNamed++; } elsif ( $ThisLine =~ /(reloading nameserver|named reload succeeded)/ ) { $ReloadNamed++; } elsif ( ($ThisLine =~ /shutting down/) or ($ThisLine =~ /named shutting down/ ) or ($ThisLine =~ /named shutdown succeeded/ ) ) { $ShutdownNamed++; } elsif ( $ThisLine =~ /named shutdown failed/ ) { $ShutdownNamedFail++; } elsif ( (($Host, $Zone) = ( $ThisLine =~ /client ([^\#]+)#[^\:]+: (?:view \w+: )?\s*zone transfer '(.+)' denied/ )) or (($Host, $Zone) = ( $ThisLine =~ /client ([^\#]+)#[^\:]+: (?:view \w+: )?\s*bad zone transfer request: '(.+)':/ )) ) { $DeniedZoneTransfers{$Host}{$Zone}++; } elsif ( ($Zone) = ( $ThisLine =~ /zone (.+) zone transfer deferred due to quota/ ) ) { $DeferredZoneTransfers{$Zone}++; } elsif ( ($Zone, $Host) = ( $ThisLine =~ /transfer of '(.+)' from ([^\#]+)#[^\:]+: (failed|(Transfer status|giving up): ((network|host) unreachable|timed out|connection refused|REFUSED))/ ) ) { $FailedZoneTransfers{$Host}{$Zone}++; } elsif ( ($Zone) = ( $ThisLine =~ /cache zone \"(.*)\" loaded/ ) ) { $ZoneLoaded{"cache $Zone"}++; } elsif ( ($Zone) = ( $ThisLine =~ /cache zone \"(.*)\" .* loaded/ ) ) { $ZoneLoaded{"cache $Zone"}++; } elsif ( ($Zone) = ( $ThisLine =~ /automatic empty zone: (.*)/ ) ) { $ZoneLoaded{"automatic empty zone $Zone"}++; } elsif ( ($Zone) = ( $ThisLine =~ /primary zone \"(.+)\" loaded/ ) ) { $ZoneLoaded{$Zone}++; } elsif ( ($Zone) = ( $ThisLine =~ /master zone \"(.+)\" .* loaded/ ) ) { $ZoneLoaded{$Zone}++; } elsif ( ($Zone) = ( $ThisLine =~ /secondary zone \"(.+)\" loaded/ ) ) { $ZoneLoaded{"secondary $Zone"}++; } elsif ( ($Zone) = ( $ThisLine =~ /slave zone \"(.+)\" .* loaded/ ) ) { $ZoneLoaded{"secondary $Zone"}++; } elsif ( ($Zone) = ( $ThisLine =~ /zone (.+): expired/ ) ) { $ZoneExpired{$Zone}++; } elsif ( ($Zone) = ( $ThisLine =~ /zone (.+): loaded serial/ ) ) { $ZoneLoaded{$Zone}++; } elsif ( ($Zone) = ( $ThisLine =~ /(managed-keys-zone.*): loaded serial/ ) ) { $ZoneLoaded{$Zone}++; } elsif ( (undef,$Addr,$Server) = ( $ThisLine =~ /(C|c)onnection refused\)? resolving '(.+)': (.+)/ ) ) { $ConnectionRefused{$Addr}{$Server}++; } elsif ( (undef,$Addr,undef,$Server) = ( $ThisLine =~ /ame server (on|resolving) '(.+)' \(in .+\):\s+(\[.+\]\.\d+)?\s*'?(.+)'?:?/ ) ) { $LameServer{$Addr}{$Server}++; } elsif ( (($Zone) = ( $ThisLine =~ /Zone \"(.+)\" was removed/ )) or (($Zone) = ( $ThisLine =~ /zone (.+): \(.*\) removed/ )) ) { $ZoneRemoved{$Zone}++; } elsif ( ($Zone) = ( $ThisLine =~ /received notify for zone '(.*)'/ ) ) { $ZoneReceivedNotify{$Zone}++; } elsif ( ($Zone) = ( $ThisLine =~ /zone (.+): refused notify from non-(?:master|primary)/ ) ) { $ZoneRefusedNotify{$Zone}++; # } elsif ( ($Rhost,$Ldom,$Reason) = ( $ThisLine =~ /client ([\d\.a-fA-F:]+) bad zone transfer request: '(.+)': (.+)$/ ) ) { } elsif ( ($Rhost,$Ldom,$Reason) = ( $ThisLine =~ /client ([\.0-9a-fA-F:]+)#\d+: bad zone transfer request: '(.+)': (.+)/ ) ) { $BadZone{$Reason}{"$Rhost ($Ldom)"}++; } elsif ( ($Host) = ( $ThisLine =~ /([^ ]+) has CNAME and other data \(invalid\)/ ) ) { push @CNAMEAndOther, $Host; } elsif ( ($File,$Line,$Entry,$Error) = ( $ThisLine =~ /dns_master_load: ([^:]+):(\d+): ([^ ]+): (.+)$/ ) ) { $ZoneFileErrors{$File}{"$Entry: $Error"}++; } elsif ( ($File,$Line,$Entry,$Error) = ( $ThisLine =~ /warning: ([^:]+):(\d+): (.+)$/ ) ) { $ZoneFileErrors{$File}{"file does not end with newline: $Error"}++; } elsif ( ($Way,$Host) = ( $ThisLine =~ /([^ ]+): sendto\(\[([^ ]+)\].+\): Network is unreachable/ ) ) { my $FullHost = LookupIP ($Host); $NetworkUnreachable{$Way}{$FullHost}++; } elsif ( ($Host,$Way) = ( $ThisLine =~ /client (?:\@0x[0-9a-fA-F]+ )?(.*)#\d+(?: \(.*\))?: (?:view \w+: )?\s*error ([^ ]+) response: network unreachable/ ) ) { my $FullHost = LookupIP ($Host); $NetworkUnreachable{$Way}{$FullHost}++; } elsif ( ($Zone,$Message) = ( $ThisLine =~ /client [^\#]+#[^\:]+: (?:view \w+: )?\s*updating zone '([^\:]+)': (.*)$/ ) ) { $ZoneUpdates{$Zone}{$Message}++; } elsif ( ($Zone,$Source) = ( $ThisLine =~ /transfer of '([^\']+)' (from [^\#]+)#[^\:]+: Transfer completed: / ) ) { $ZoneUpdates{$Zone}{$Source}++; } elsif ( ($Host,$Zone) = ( $ThisLine =~ /approved AXFR from \[(.+)\]\..+ for \"(.+)\"/ ) ) { my $FullHost = LookupIP ($Host); $AXFR{$Zone}{$FullHost}++; } elsif ( ($Client) = ( $ThisLine =~ /warning: client (.*) no more TCP clients/ ) ) { my $FullClient = LookupIP ($Client); $DeniedTCPClient{$FullClient}++; } elsif ( ($Client) = ( $ThisLine =~ /client (?:\@0x[0-9a-fA-F]+ )?(.*)#\d+(?: \(.*\))?: (?:view \w+: )?\s*query \(cache\) (?:'.*' )?denied/ ) ) { my $FullClient = LookupIP ($Client); $DeniedQuery{$FullClient}++; } elsif ( ($Client) = ( $ThisLine =~ /client (?:\@0x[0-9a-fA-F]+ )?([^#]*)(#\d+)?(?: \(.*\))?: query '.*' denied/ ) ) { my $FullClient = LookupIP ($Client); $DeniedQueryNoCache{$FullClient}++; } elsif ( ($Rhost, $ViewName, $Ldom) = ($ThisLine =~ /client (?:\@0x[0-9a-fA-F]+ )?([\.0-9a-fA-F:]+)#\d+: (?:view (\w+): )?update '(.*)' denied/)) { $ViewName = ($ViewName ? "/$ViewName" : ""); $UpdateDenied{"$Rhost ($Ldom$ViewName)"}++; } elsif ( ($Rhost, $Reason) = ($ThisLine =~ /client (?:\@0x[0-9a-fA-F]+ )?([\.0-9a-fA-F:]+)#\d+: (.*)/)) { $UpdateDenied{"$Rhost ($Reason)"}++; } elsif ( ($Rhost, $Ldom) = ($ThisLine =~ /client ([\d\.]+)#\d+: update forwarding '(.*)' denied/)) { $UpdateForwardingDenied{"$Rhost ($Ldom)"}++; } elsif ( ($Zone, $Master, $Reason) = ($ThisLine =~ /zone (.*): forwarded dynamic update: master (.*)#\d+ returned: (.*)/)) { $UpdateForwardingDenied{"$Zone ($Master) $Reason"}++; } elsif ( ($Zone) = ($ThisLine =~ /zone '([0-9a-zA-Z.-]+)' allows updates by IP address, which is insecure/)) { $InsecUpdate{$Zone}++; } elsif ( ($Zone) = ($ThisLine =~ /zone ([0-9a-zA-Z.\/-]+): journal rollforward failed: journal out of sync with zone/)) { $JournalFail{$Zone}++; } elsif ( ($Zone) = ($ThisLine =~ /(managed-keys-zone.*): journal file is out of date: removing journal file/)) { $JournalFail{$Zone}++; } elsif ( ($Channel,$Reason) = ($ThisLine =~ /couldn't add command channel (.+#\d+): (.*)$/)) { $ChannelAddFail{$Channel}{$Reason}++; } elsif ( ($Zone,$Host,undef,$Reason) = ($ThisLine =~ /zone ([^ ]*): refresh: failure trying master ([^ ]*)#\d+( \(source .*\))?: (.*)/) ) { $MasterFailure{"$Zone from $Host"}{$Reason}++; } elsif ( ($Zone,$Reason,$Host) = ($ThisLine =~ /zone ([^ ]*): refresh: unexpected rcode \((.*)\) from master ([^ ]*)#\d+/) ) { $MasterFailure{"$Zone from $Host"}{$Reason}++; } elsif ( ($Zone) = ($ThisLine =~ /zone ([^\/]+)\/.+: refresh: non-authoritative answer from master/)) { $NonAuthoritative{$Zone}++; } elsif ( ($Zone) = ($ThisLine =~ /zone ([^\/]+)\/.+: refresh: retry limit for master \S+ exceeded/) ) { $RetryLimit{$Zone}++; } elsif ( ($Rcode, $Zone, $Host) = ($ThisLine =~ /(?:error \()?unexpected RCODE\)? \(?(.*?)\)? resolving '(.*)': (.*)$/) ){ # Remove port number, for proper IP sorting $Host =~ s/#.*//; $UnexpRCODE{$Rcode}{$Zone}{$Host}++; } elsif ( ($Rcode, $Zone, $Host) = ($ThisLine =~ /(.*) unexpected RCODE resolving '(.*)': (.*)$/) ){ # Remove port number, for proper IP sorting $Host =~ s/#.*//; $UnexpRCODE{$Rcode}{$Zone}{$Host}++; } elsif ( ($ThisLine =~ /(?:error \()?FORMERR\)? resolving '[^ ]+: [.0-9a-fA-F:#]+/) or ($ThisLine =~ /DNS format error from [^ ]+ resolving [^ ]+( for( client)? [^ ]+)?: .*/) ) { chomp($ThisLine); $FormErr{$ThisLine}++; } elsif ( ($ThisLine =~ /found [0-9]* CPU(s)?, using [0-9]* worker thread(s)?/) ) { chomp($ThisLine); $StartLog{$ThisLine}++; } elsif ( (($File,$Line,$Problem) = ($ThisLine =~ /\/etc\/(rndc.key|named.conf):([0-9]+): (unknown option '[^ ]*')/)) or (($File,$Line,$Problem) = ($ThisLine =~ /\/etc\/(rndc.key|named.conf):([0-9]+): ('[^ ]' expected near end of file)/)) or (($File,$Line,$Problem) = ($ThisLine =~ /\/etc\/(named.*.conf):([0-9]+): (.*)/)) or (($File,$Line,$Problem) = ($ThisLine =~ /()()(could not configure root hints from '.*': file not found)/))) { $ConfProb{$File}{"$Line,$Problem"}++; } elsif ( (($ErrorText) = ($ThisLine =~ /^(RUNTIME_CHECK.*)/))or (($ErrorText) = ($ThisLine =~ /^(.* REQUIRE.* failed.*)$/)) or (($ErrorText) = ($ThisLine =~ /(.*: fatal error)/)) or (($ErrorText) = ($ThisLine =~ /(.*: out of memory)/)) ) { $NError{$ErrorText}++; } elsif ( (($ErrorText) = ($ThisLine =~ /^(GeoIP .* DB not available)/)) ) { $GeoIPError{$ErrorText}++; } elsif ( (($ErrorText) = ($ThisLine =~ /^(internal_accept: fcntl\(\) failed: Too many open files)/)) or (($ErrorText) = ($ThisLine =~ /^(socket: too many open file descriptors)/)) ) { $ErrOpenFiles{$ErrorText}++; } elsif ( ($From,$Log) = ($ThisLine =~ /invalid command from ([\.0-9a-fA-F:]*)#[0-9]*: (.*)/) ) { $CCMessages{"$From,$Log"}++; } elsif ( (($Log) = ($ThisLine =~ /(freezing .*zone.*)/)) or (($Log) = ($ThisLine =~ /(thawing .*zone.*)/)) ) { $CCMessages2{$Log}++; } elsif (($CCC) = ($ThisLine =~ /unknown control channel command '(.*)'/)) { $UnknownCCCommands{$CCC}++; } elsif (($CCC) = ($ThisLine =~ /received control channel command '(.*)'/)) { $CCCommands{$CCC}++; } elsif (($Name,$Address) = ($ThisLine =~ /(?:error \()?network unreachable\)? resolving '(.*)': (.*)/)) { $NUR{$Name}{$Address}++; } elsif (($Name,$Address) = ($ThisLine =~ /(?:error \()?host unreachable\)? resolving '(.*)': (.*)/)) { $HUR{$Name}{$Address}++; } elsif (($Client) = ($ThisLine =~ /client ([\da-fA-F.:]+)(?:#\d*:)? notify question section contains no SOA/)) { $NoSOA{$Client}++; } elsif (($Addr) = ($ThisLine =~ /bad cookie from (.*)/)) { $BadCookie{$Addr}++; } elsif (($Addr) = ($ThisLine =~ /missing expected cookie from ([\da-fA-F.:]+)(?:#\d*)?/)) { $MissingCookie{$Addr}++; } elsif (($Entry) = ($ThisLine =~ /shut down hung fetch while resolving '(.*)'/)) { $Timeout{$Entry}++; } elsif (($Entry) = ($ThisLine =~ /loop detected resolving '(.*)'/)) { $LoopDetected{$Entry}++; } elsif (($Hint) = ($ThisLine =~ /checkhints: (.*)/) ) { $Hints{$Hint}++; } elsif (($Response,$Net,$Zone) = ($ThisLine =~/limit (.+) responses to (\S+)(?: for (.+) \()?/)) { $Zone = "None" unless defined($Zone); $Limit{$Zone}{$Response}{$Net}++; } elsif (($Client,$Response,$Net,$Zone) = ($ThisLine =~/client ([^#]+)(?:#\d+)? \(.*\): (?:view \w+: )?\s*rate limit drop (.+) response to (\S+)(?: for (\S+))?/)) { $Zone = "None" unless defined($Zone); $LimitDrop{$Zone}{$Response}{$Net}{$Client}++; } elsif (($Client,$Response,$Net,$Zone) = ($ThisLine =~/client ([^#]+)(?:#\d+)? \(.*\): (?:view \w+: )?\s*rate limit slip (.+) response to (\S+)(?: for (\S+))?/)) { $Zone = "None" unless defined($Zone); $LimitSlip{$Zone}{$Response}{$Net}{$Client}++; } elsif (($Net,$Zone,$Response) = ($ThisLine =~/limit responses to (\S+)(?: for (\S+))? (.*) +\(/)) { $Zone = "None" unless defined($Zone); $Limit{$Zone}{$Response}{$Net}++; } elsif (($Client,$Net,$Zone,$Response) = ($ThisLine =~/client ([^#]+)(?:#\d+)? \(.*\): (?:view \w+: )?\s*rate limit drop response to (\S+)(?: for (\S+))? (.*) +\(/)) { $Zone = "None" unless defined($Zone); $LimitDrop{$Zone}{$Response}{$Net}{$Client}++; } elsif (($Client,$Net,$Zone,$Response) = ($ThisLine =~/client ([^#]+)(?:#\d+)? \(.*\): (?:view \w+: )?\s*rate limit slip response to (\S+)(?: for (\S+))? (.*) +\(/)) { $Zone = "None" unless defined($Zone); $LimitSlip{$Zone}{$Response}{$Net}{$Client}++; } elsif (($Zone,$RR) = ($ThisLine =~ /^(?:view \w+: )?\s*validating \@0x[[:xdigit:]]+: (.*) (\w+): got insecure response; parent indicates it should be secure/)) { $DNSSECInsec{'__Total__'}++; $DNSSECInsec{$Zone}{$RR}++; } elsif (($Zone,$RR) = ($ThisLine =~ /^(?:view \w+: )?\s*validating \@0x[[:xdigit:]]+: (.*) (\w+): no valid signature found/)) { $DNSSECInvalid{'__Total__'}++; $DNSSECInvalid{$Zone}{$RR}++; } elsif (($Zone,$RR) = ($ThisLine =~ /^(?:view \w+: )?\s*validating \@0x[[:xdigit:]]+: (.*) (\w+): bad cache hit/)) { $DNSSECBadCache{'__Total__'}++; $DNSSECBadCache{$Zone}{$RR}++; } elsif (($Zone,$RR) = ($ThisLine =~ /^(?:view \w+: )?\s*validating \@0x[[:xdigit:]]+: (.*) (\w+): verify failed due to bad signature/)) { $DNSSECInvalid{'__Total__'}++; $DNSSECInvalid{$Zone}{$RR}++; } elsif (($Zone,$RR) = ($ThisLine =~ /^(?:view \w+: )?\s*validating ([^\/]*)\/(\w+): got insecure response; parent indicates it should be secure/)) { $DNSSECInsec{'__Total__'}++; $DNSSECInsec{$Zone}{$RR}++; } elsif (($Zone,$RR) = ($ThisLine =~ /^(?:view \w+: )?\s*validating ([^\/]*)\/(\w+): no valid signature found/)) { $DNSSECInvalid{'__Total__'}++; $DNSSECInvalid{$Zone}{$RR}++; } elsif (($Zone,$RR) = ($ThisLine =~ /^(?:view \w+: )?\s*validating ([^\/]*)\/(\w+): verify failed due to bad signature/)) { $DNSSECInvalid{'__Total__'}++; $DNSSECInvalid{$Zone}{$RR}++; } elsif (($Zone,$RR) = ($ThisLine =~ /^(?:view \w+: )?\s*validating ([^\/]*)\/(\w+): bad cache hit/)) { $DNSSECBadCache{'__Total__'}++; $DNSSECBadCache{$Zone}{$RR}++; } elsif (($Error,$Host) = ($ThisLine =~ /^(?:error \()?(.*)\)? resolving '([^']+)':/)) { $DNSSECError{$Error}{'__Total__'}++; $DNSSECError{$Error}{$Host}++; } elsif ($ThisLine =~ /^samba_dlz:/) { if ( ($Rhost, $Error) = ($ThisLine =~ /disallowing update of signer=.* name=(.*) type=.* error=(.*)/ )) { $UpdateDenied{"$Rhost ($Error)"}++; } # ignore rest of samba4 dlz entries for now } else { # Report any unmatched entries... # remove PID from named messages $ThisLine =~ s/(client [\.0-9a-fA-F:]+)\S+/$1/; chomp($ThisLine); $OtherList{$ThisLine}++; } } ####################################### if ( keys %ZoneExpired ) { print "\nZones expired:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %ZoneExpired) { print " $ThisOne: $ZoneExpired{$ThisOne} Time(s)\n"; } } if ( keys %FailedZoneTransfers ) { my $first = 1; foreach my $Host (keys %FailedZoneTransfers) { my $firsthost = 1; foreach my $Zone (keys %{$FailedZoneTransfers{$Host}}) { if ($FailedZoneTransfers{$Host}{$Zone} >= $FailedZoneTransferThreshold) { if ($first) { print "\nFailed Zone Transfers"; print " (with threshold >= $FailedZoneTransferThreshold)" if $FailedZoneTransferThreshold; print ":\n"; $first = 0; } if ($firsthost) { print " $Host:\n"; $firsthost = 0; } print " $Zone: $FailedZoneTransfers{$Host}{$Zone} Time(s)\n"; } } } } if ( keys %DeniedZoneTransfers ) { print "\nDenied Zone Transfers:\n"; foreach my $Host (keys %DeniedZoneTransfers) { print " $Host:\n"; foreach my $Zone (keys %{$DeniedZoneTransfers{$Host}}) { print " $Zone: $DeniedZoneTransfers{$Host}{$Zone} Time(s)\n"; } } } if ( keys %UpdateDenied ) { print "\nZone update refused:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %UpdateDenied) { print " $ThisOne: $UpdateDenied{$ThisOne} Time(s)\n"; } } if ( keys %UpdateForwardingDenied ) { print "\nZone update forwarding refused:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %UpdateForwardingDenied) { print " $ThisOne: $UpdateForwardingDenied{$ThisOne} Time(s)\n"; } } if ( keys %InsecUpdate ) { print "\nInsecure zones (dynamic update allowed by IP address):\n"; foreach my $ThisOne (sort {$a cmp $b} keys %InsecUpdate) { print " " . $ThisOne . ": " . $InsecUpdate{$ThisOne} . " Time(s)\n"; } } if ( keys %JournalFail ) { print "\nJournal update failed:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %JournalFail) { print " " . $ThisOne . ": " . $JournalFail{$ThisOne} . " Time(s)\n"; } } if (keys %ConfProb) { print "\nErrors in configuration files\n"; foreach my $File (sort keys %ConfProb) { if ($File =~ /.+/) { print " file " . $File . "\n"; foreach (keys %{$ConfProb{$File}}) { my ($Line,$Problem) = split ","; print " " . $File . ":" . "$Line" . ": " . $Problem . ": " . $ConfProb{$File}{"$Line,$Problem"} . " Time(s)\n"; } } else { foreach (keys %{$ConfProb{$File}}) { my ($Line,$Problem) = split ","; print " " . $Problem . ": " . $ConfProb{$File}{"$Line,$Problem"} . " Time(s)\n"; } } } } if (keys %NError) { print "\nErrors:\n"; foreach my $ThisOne (keys %NError) { print " " . $ThisOne . ": " . $NError{$ThisOne} . " Time(s)\n"; } } if (keys %ErrOpenFiles) { print "\nThe following seams to be caused by the patches for CVE-2008-1447."; print "\nPlease update your bind.\n"; foreach my $ThisOne (keys %ErrOpenFiles) { print " " . $ThisOne . ": " . $ErrOpenFiles{$ThisOne} . " Time(s)\n"; } } if (keys %Limit) { print "\nRate Limiting occurred for:\n"; foreach my $Zone (keys %Limit) { print " $Zone:\n"; foreach my $Response (keys %{$Limit{$Zone}}) { print " $Response:\n"; foreach my $Net (keys %{$Limit{$Zone}{$Response}}) { print " $Net: $Limit{$Zone}{$Response}{$Net} Time(s)\n"; foreach my $Client (keys %{$LimitDrop{$Zone}{$Response}{$Net}}) { print " Dropped $Client: $LimitDrop{$Zone}{$Response}{$Net}{$Client} Time(s)\n"; } foreach my $Client (keys %{$LimitSlip{$Zone}{$Response}{$Net}}) { print " Slipped $Client: $LimitSlip{$Zone}{$Response}{$Net}{$Client} Time(s)\n"; } } } } } if ( ( $Detail >= 5 ) and (keys %GeoIPError) ) { print "\nGeoIP Errors:\n"; foreach my $ThisOne (keys %GeoIPError) { print " " . $ThisOne . ": " . $GeoIPError{$ThisOne} . " Time(s)\n"; } } if ((keys %CCMessages)){ print "\nInvalid command messages from control channel\n"; foreach (keys %CCMessages) { my ($From,$Log) = split ","; print " " . $From . ": " . $Log . ": " . $CCMessages{"$From,$Log"} . " Time(s)\n"; } } if ( ( $Detail >= 5 ) and (keys %CCMessages2)){ print "\nMessages from control channel\n"; foreach my $ThisOne (keys %CCMessages2) { print " " . $ThisOne . ": " . $CCMessages2{$ThisOne} . " Time(s)\n"; } } if ( ( $Detail >= 5 ) and ($StartNamed) ) { print "\nNamed started: $StartNamed Time(s)\n"; } if ( ( $Detail >= 5 ) and ($ReloadNamed) ) { print "Named reloaded: $ReloadNamed Time(s)\n"; } if ( ( $Detail >= 5 ) and ($ShutdownNamed) ) { print "Named shutdown: $ShutdownNamed Time(s)\n"; } if ( ( $Detail >= 5 ) and ($ShutdownNamedFail) ) { print "Named shutdown failed: $ShutdownNamedFail Time(s)\n"; } if ( ( $Detail >= 5 ) and (keys %ZoneLoaded) ) { print "\nLoaded Zones:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %ZoneLoaded) { print " $ThisOne: $ZoneLoaded{$ThisOne} Time(s)\n"; } } if ( ( $Detail >= 5 ) and (keys %ZoneReceivedNotify) ) { print "\nZones receiving notify:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %ZoneReceivedNotify) { print " $ThisOne: $ZoneReceivedNotify{$ThisOne} Time(s)\n"; } } if ( ( $Detail >= 5 ) and (keys %ZoneRefusedNotify) ) { print "\nZones refused notify:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %ZoneRefusedNotify) { print " $ThisOne: $ZoneRefusedNotify{$ThisOne} Time(s)\n"; } } if ( ($Detail >= 5) and (keys %ChannelAddFail) ) { print "\nCan't add command channel:\n"; foreach my $Channel (sort {$a cmp $b} keys %ChannelAddFail) { print " $Channel:\n"; foreach my $Reason (sort {$a cmp $b} keys %{$ChannelAddFail{$Channel}}) { print " $Reason: $ChannelAddFail{$Channel}{$Reason} Time(s)\n"; } } } if ( ($Detail >= 5) and (keys %MasterFailure) ) { print "\nFailure trying to refresh zone:\n"; foreach my $Zone (sort {$a cmp $b} keys %MasterFailure) { print " $Zone:\n"; foreach my $Reason (sort {$a cmp $b} keys %{$MasterFailure{$Zone}}) { print " $Reason: $MasterFailure{$Zone}{$Reason} Time(s)\n"; } } } if ( ( $Detail >= 5 ) and (keys %DeferredZoneTransfers) ) { print "\nDeferred Zone Transfers:\n"; foreach my $Zone (keys %DeferredZoneTransfers) { print " $Zone: $DeferredZoneTransfers{$Zone} Time(s)\n"; } } if ( ( $Detail >= 5 ) and (keys %ZoneRemoved) ) { print "\nRemoved Zones:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %ZoneRemoved) { print " $ThisOne: $ZoneRemoved{$ThisOne} Time(s)\n"; } } if ( ( $Detail >= 5 ) and (keys %AXFR) ) { print "\nZone Transfers:\n"; foreach my $ThisOne (keys %AXFR) { print " Zone: $ThisOne\n"; foreach my $Temp (keys %{$AXFR{$ThisOne}}) { print " by $Temp: $AXFR{$ThisOne}{$Temp} Time(s)\n"; } } } if ( ( $Detail >= 10 ) and (keys %BadZone) ) { print "\nBad Zone Transfer Request:\n"; foreach my $Reason (keys %BadZone) { print " Reason: $Reason\n"; foreach my $ThisOne (sort {$a cmp $b} (keys %{$BadZone{$Reason}}) ) { print " $ThisOne: $BadZone{$Reason}{$ThisOne} Time(s)\n"; } } } if ( ( $Detail >= 5 ) and (keys %DeniedTCPClient) ) { print "\nno more TCP clients warning:\n"; foreach my $ThisOne (keys %DeniedTCPClient) { print " from $ThisOne: $DeniedTCPClient{$ThisOne} Time(s)\n"; } } if ( ( $Detail >= 5 ) and (keys %DeniedQuery) ) { print "\nQueries (cached) that were denied:\n"; foreach my $ThisOne (keys %DeniedQuery) { print " from $ThisOne: $DeniedQuery{$ThisOne} Time(s)\n"; } } if ( ( $Detail >= 10 ) and (keys %DeniedQueryNoCache) ) { print "\nQueries (not cached) that were denied:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %DeniedQueryNoCache) { print " from $ThisOne: $DeniedQueryNoCache{$ThisOne} Time(s)\n"; } } if ( ( $Detail >= 10 ) and (@CNAMEAndOther) ) { print "\nThese hosts have CNAME and other data (invalid):\n"; foreach my $ThisOne (@CNAMEAndOther) { print " $ThisOne\n"; } } if ( ( $Detail >= 5 ) and (keys %ZoneFileErrors) ) { print "\nSyntax errors in zone files:\n"; for my $File (keys %ZoneFileErrors) { print " $File\n"; for my $Error ( keys %{$ZoneFileErrors{$File}} ) { print " \"$Error\" " . $ZoneFileErrors{$File}{$Error} . " Time(s)\n"; } } } if ( ( $Detail >= 10 ) and (keys %ConnectionRefused) ) { print "\nConnection refused resolving:\n"; foreach my $Addr (sort keys %ConnectionRefused) { print " $Addr:\n"; foreach my $Server (sort SortIP keys %{$ConnectionRefused{$Addr}}) { print " $Server: $ConnectionRefused{$Addr}{$Server} Time(s)\n"; } } } if ( ( $Detail >= 10 ) and (keys %LameServer) ) { print "\nThese addresses had lame server references:\n"; foreach my $Addr (sort keys %LameServer) { print " $Addr:\n"; foreach my $Server (sort SortIP keys %{$LameServer{$Addr}}) { print " $Server: $LameServer{$Addr}{$Server} Time(s)\n"; } } } if ( ( $Detail >= 10 ) and (keys %NonAuthoritative) ) { print "\nNon-authoritative answer from master for these zones:\n"; foreach my $ThisOne (keys %NonAuthoritative) { print " " . $ThisOne . ": " . $NonAuthoritative{$ThisOne} . " Time(s)\n"; } } if ( ( $Detail >= 10 ) and (keys %BadCookie) ) { print "\nBad Cookie returned from these hosts:\n"; foreach my $ThisOne (keys %BadCookie) { print " " . $ThisOne . ": " . $BadCookie{$ThisOne} . " Time(s)\n"; } } if ( ( $Detail >= 10 ) and (keys %MissingCookie) ) { print "\nMissing expected Cookie returned from these hosts:\n"; foreach my $ThisOne (keys %MissingCookie) { print " " . $ThisOne . ": " . $MissingCookie{$ThisOne} . " Time(s)\n"; } } if ( ($Detail >= 10) and (keys %RetryLimit) ) { print "\nRetry limit exceeded for these zones:\n"; foreach my $Zone (sort {$a cmp $b} keys %RetryLimit) { print " $Zone: $RetryLimit{$Zone} Time(s)\n"; } } if ( ($Detail >= 10) and (keys %NoSOA) ) { print "\nNotify question sections of these clients contained no SOA:\n"; foreach my $Client (sort {$a cmp $b} keys %NoSOA) { print " $Client: $NoSOA{$Client} Time(s)\n"; } } if ( ( $Detail >= 10 ) and (keys %NetworkUnreachable) ) { print "\nNetwork is unreachable for:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %NetworkUnreachable) { print " $ThisOne:\n"; foreach my $Host (sort {$a cmp $b} keys %{$NetworkUnreachable{$ThisOne}}) { print " $Host: $NetworkUnreachable{$ThisOne}{$Host} Time(s)\n"; } } } if ( ( $Detail >= 10 ) and (keys %NUR) ) { print "\nNetwork unreachable resolving for:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %NUR) { print " $ThisOne:\n"; foreach my $Host (sort {$a cmp $b} keys %{$NUR{$ThisOne}}) { print " $Host: $NUR{$ThisOne}{$Host} Time(s)\n"; } } } if ( ( $Detail >= 10 ) and (keys %HUR) ) { print "\nHost unreachable resolving for:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %HUR) { print " $ThisOne:\n"; foreach my $Host (sort {$a cmp $b} keys %{$HUR{$ThisOne}}) { print " $Host: $HUR{$ThisOne}{$Host} Time(s)\n"; } } } if ( ( $Detail >= 10 ) and (keys %Timeout) ) { print "\nTimeout resolving for:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %Timeout) { print " " . $ThisOne . ": " . $Timeout{$ThisOne} . " Time(s)\n"; } } if ( ( $Detail >= 10 ) and (keys %LoopDetected) ) { print "\nLoop detected resolving for:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %LoopDetected) { print " " . $ThisOne . ": " . $LoopDetected{$ThisOne} . " Time(s)\n"; } } if ( ( $Detail >= 10 ) and (keys %ZoneUpdates) ) { print "\nZone Updates:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %ZoneUpdates) { print " $ThisOne:\n"; foreach my $Message (sort {$a cmp $b} keys %{$ZoneUpdates{$ThisOne}}) { print " $Message: $ZoneUpdates{$ThisOne}{$Message} Time(s)\n"; } } } if (($Detail >= 5) and (keys %UnexpRCODE)) { print "\nUnexpected DNS RCODEs:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %UnexpRCODE) { print " " . $ThisOne . ":\n"; foreach my $Zone (sort {$a cmp $b} keys %{$UnexpRCODE{$ThisOne}}) { print " " . $Zone . ":\n"; foreach my $Host (sort SortIP keys %{$UnexpRCODE{$ThisOne}{$Zone}}) { print " " . $Host . ": " . $UnexpRCODE{$ThisOne}{$Zone}{$Host} . " Time(s)\n"; } } } } if (($Detail >= 5) and (keys %FormErr)) { print "\nIncorrect response format:\n"; foreach my $ThisOne (keys %FormErr) { print " " . $ThisOne . ": " . $FormErr{$ThisOne} . " Time(s)\n"; } } if (($Detail >= 10) and (keys %StartLog)) { print "\nNamed startup logs:\n"; foreach my $ThisOne (keys %StartLog) { print " " . $ThisOne . ": " . $StartLog{$ThisOne} . " Time(s)\n"; } } if (($Detail and (keys %CCCommands)) or (keys %UnknownCCCommands)) { print "\nReceived control channel commands\n"; foreach my $ThisOne (keys %CCCommands) { print " " . $ThisOne . ": " . $CCCommands{$ThisOne} . " Time(s)\n"; } foreach my $ThisOne (keys %UnknownCCCommands) { print " " . $ThisOne . "(unknown command): " . $CCCommands{$ThisOne} . " Time(s)\n"; } } if (keys %Hints) { print "\nCheckhints:\n"; foreach my $ThisOne (sort {$a cmp $b} keys %Hints) { print " " .$ThisOne .": $Hints{$ThisOne} Time(s)\n"; } } if (($Detail >= 5) and (keys %DNSSECInsec)) { print "\nDNSSEC Insecure Responses: " . $DNSSECInsec{'__Total__'} . " Time(s)\n"; foreach my $Zone (sort keys %DNSSECInsec) { if (($Detail >= 10) and ($Zone =~ /.+/) and ($Zone ne '__Total__')) { foreach my $RR (sort keys %{$DNSSECInsec{$Zone}}) { print " " . "$Zone/$RR: " . $DNSSECInsec{$Zone}{$RR} . " Time(s)\n"; } } } } if (($Detail >= 5) and (keys %DNSSECInvalid)) { print "\nDNSSEC No Valid Signature: " . $DNSSECInvalid{'__Total__'} . " Time(s)\n"; foreach my $Zone (sort keys %DNSSECInvalid) { if (($Detail >= 10) and ($Zone =~ /.+/) and ($Zone ne '__Total__')) { foreach my $RR (sort keys %{$DNSSECInvalid{$Zone}}) { print " " . "$Zone/$RR: " . $DNSSECInvalid{$Zone}{$RR} . " Time(s)\n"; } } } } if (($Detail >= 5) and (keys %DNSSECBadCache)) { print "\nDNSSEC Bad Cache hit: " . $DNSSECBadCache{'__Total__'} . " Time(s)\n"; foreach my $Zone (sort keys %DNSSECBadCache) { if (($Detail >= 10) and ($Zone =~ /.+/) and ($Zone ne '__Total__')) { foreach my $RR (sort keys %{$DNSSECBadCache{$Zone}}) { print " " . "$Zone/$RR: " . $DNSSECBadCache{$Zone}{$RR} . " Time(s)\n"; } } } } if (($Detail >= 5) and (keys %DNSSECError)) { print "\nDNSSEC Errors:\n"; foreach my $Error (sort keys %DNSSECError) { print " $Error: " . $DNSSECError{$Error}{'__Total__'} . " Time(s)\n"; if ($Detail >= 10) { foreach my $Host (sort keys %{$DNSSECError{$Error}}) { print " " . "$Host: " . $DNSSECError{$Error}{$Host} . " Time(s)\n" unless ($Host eq '__Total__'); } } } } if (keys %OtherList) { print "\n**Unmatched Entries**\n"; foreach my $line (sort {$a cmp $b} keys %OtherList) { print " $line: $OtherList{$line} Time(s)\n"; } } exit(0); # vi: shiftwidth=3 tabstop=3 syntax=perl et # Local Variables: # mode: perl # perl-indent-level: 3 # indent-tabs-mode: nil # End: