summaryrefslogtreecommitdiff
path: root/dnscheck_nsd.py
diff options
context:
space:
mode:
authorJohan Lundberg <lundberg@nordu.net>2013-04-29 12:17:30 +0200
committerJohan Lundberg <lundberg@nordu.net>2013-04-29 12:17:30 +0200
commit0d121a3d3ffc5bc975cdf777b2999277f7b6370a (patch)
tree64c60471969b59d5b39b0cb8b235c2d0c0a6d31d /dnscheck_nsd.py
parent022b6e8eb56b6d42c9ea2f0e9f97213d743e8ab1 (diff)
Better error handling.
Diffstat (limited to 'dnscheck_nsd.py')
-rw-r--r--dnscheck_nsd.py82
1 files changed, 47 insertions, 35 deletions
diff --git a/dnscheck_nsd.py b/dnscheck_nsd.py
index 329fa45..ea923c5 100644
--- a/dnscheck_nsd.py
+++ b/dnscheck_nsd.py
@@ -4,7 +4,7 @@ __author__ = 'lundberg'
import sys
import argparse
import logging
-from socket import gethostbyname, gethostbyaddr, gaierror
+from socket import gethostbyname, gethostbyaddr, gaierror, herror
import dns.resolver
logger = logging.getLogger('dnscheck_nsd')
@@ -17,6 +17,7 @@ logger.addHandler(ch)
VERBOSE = False
+
def get_resolver(nameserver=None, lifetime=30):
resolver = dns.resolver.Resolver()
resolver.lifetime = lifetime
@@ -25,13 +26,14 @@ def get_resolver(nameserver=None, lifetime=30):
resolver.nameservers=[gethostbyname(nameserver)]
except gaierror:
try:
- resolver.nameservers=[nameserver] # It is an IP address
+ resolver.nameservers = [nameserver] # It is an IP address
except gaierror:
logger.error('Could not find nameserver: %s' % nameserver)
sys.exit(1)
logger.debug('Resolver instance with nameserver %s.' % resolver.nameservers[0])
return resolver
+
def compare_soa(zone, resolvers):
answers = []
for resolver in resolvers:
@@ -41,7 +43,10 @@ def compare_soa(zone, resolvers):
if resolver.nameservers[0] == '127.0.0.1' or resolver.nameservers[0] == '::1':
logger.info('NS %s: %s' % (resolver.nameservers[0], answer))
else:
- logger.info('NS %s: %s' % (gethostbyaddr(resolver.nameservers[0])[0], answer))
+ try:
+ logger.info('NS %s: %s' % (gethostbyaddr(resolver.nameservers[0])[0], answer))
+ except herror:
+ logger.info('NS %s: %s' % (resolver.nameservers[0], answer))
except dns.exception.Timeout:
logger.error('%s timed out. SOA request for %s failed.' % (gethostbyaddr(resolver.nameservers[0])[0], zone))
return 'timeout'
@@ -60,6 +65,7 @@ def compare_soa(zone, resolvers):
return 'match'
return 'no match'
+
def print_soa(zone, resolvers):
for resolver in resolvers:
try:
@@ -77,13 +83,14 @@ def print_soa(zone, resolvers):
except dns.resolver.NoNameservers:
logger.error('No non-broken nameservers are available to answer the query for %s.' % zone)
+
def check_auth(zone, resolver):
try:
nameserver = gethostbyaddr(resolver.nameservers[0])[0]
answer = resolver.query(zone, 'NS')
if VERBOSE:
logger.info('Checking if NS %s authoritative for %s...' % (nameserver, zone))
- ns_match = '%s.' % nameserver # hostname.
+ ns_match = '%s.' % nameserver # hostname.
for auth in answer:
if ns_match == auth.to_text():
if VERBOSE:
@@ -108,9 +115,10 @@ def check_auth(zone, resolver):
logger.info('NS %s is not authoritative for %s...' % (nameserver, zone))
return False
+
def parse_file(f):
result = []
- in_zone,domain,ns_address = False,'',''
+ in_zone, domain, ns_address = False, '', ''
for line in f:
if not line.startswith('#'):
if line.startswith('zone'):
@@ -119,20 +127,21 @@ def parse_file(f):
domain = line.split()[1]
if in_zone and line.find('request-xfr') != -1:
ns_address = line.split()[1]
- if not line.strip(): # Blank line
+ if not line.strip(): # Blank line
if domain:
logger.error('Misconfigured zone: %s in %s.' % (domain, f.name))
if ns_address:
logger.error('Misconfigured zone with NS address: %s in %s.' % (ns_address, f.name))
- in_zone,domain,ns_address = False,'',''
+ in_zone, domain, ns_address = False, '', ''
if in_zone and domain and ns_address:
result.append({
'domain': domain.strip('"'),
'ns_address': ns_address
- })
- in_zone,domain,ns_address = False,'',''
+ })
+ in_zone, domain, ns_address = False, '', ''
return result
+
def main():
# User friendly usage output
parser = argparse.ArgumentParser()
@@ -168,32 +177,35 @@ def main():
else:
exclude_list = []
ref_resolver = get_resolver(nameserver=args.nameserver, lifetime=args.timeout)
- for item in parse_file(args.file):
- if not item['domain'] in exclude_list:
- if not args.nochecksoa:
- resolver = get_resolver(nameserver=item['ns_address'], lifetime=args.timeout)
- soa_result = compare_soa(item['domain'], [ref_resolver, resolver])
- if soa_result == 'match' and VERBOSE:
- print 'SOA check complete for zone %s.\n' % item['domain']
- elif not soa_result:
- print 'SOA check for zone %s failed.\n' % item['domain']
- elif soa_result == 'timeout':
- print 'SOA check for zone %s timed out.\n' % item['domain']
- elif soa_result == 'no match':
- print 'SOA did not match:'
- print_soa(item['domain'], [ref_resolver, resolver])
- print ''
- if not args.nocheckauth:
- auth_result = check_auth(item['domain'], ref_resolver)
- if auth_result and VERBOSE:
- print 'Authority check complete for %s.\n' % item['domain']
- elif auth_result is None:
- print 'Authoritative check failed for %s.\n' % item['domain']
- elif not auth_result:
- print 'Reference NS is not authoritative for %s.\n' % item['domain']
- else:
- if VERBOSE:
- logger.info('Zone %s found in exclude list, skipping...' % item['domain'])
+ try:
+ for item in parse_file(args.file):
+ if not item['domain'] in exclude_list:
+ if not args.nochecksoa:
+ resolver = get_resolver(nameserver=item['ns_address'], lifetime=args.timeout)
+ soa_result = compare_soa(item['domain'], [ref_resolver, resolver])
+ if soa_result == 'match' and VERBOSE:
+ print 'SOA check complete for zone %s.\n' % item['domain']
+ elif not soa_result:
+ print 'SOA check for zone %s failed.\n' % item['domain']
+ elif soa_result == 'timeout':
+ print 'SOA check for zone %s timed out.\n' % item['domain']
+ elif soa_result == 'no match':
+ print 'SOA did not match:'
+ print_soa(item['domain'], [ref_resolver, resolver])
+ print ''
+ if not args.nocheckauth:
+ auth_result = check_auth(item['domain'], ref_resolver)
+ if auth_result and VERBOSE:
+ print 'Authority check complete for %s.\n' % item['domain']
+ elif auth_result is None:
+ print 'Authoritative check failed for %s.\n' % item['domain']
+ elif not auth_result:
+ print 'Reference NS is not authoritative for %s.\n' % item['domain']
+ else:
+ if VERBOSE:
+ logger.info('Zone %s found in exclude list, skipping...' % item['domain'])
+ except KeyboardInterrupt:
+ sys.exit(0)
return 0
if __name__ == '__main__':