def query(domain, qtype, qclass, server, flags): """Run a query and return results.""" if len(server) == 0: resolver = ldnsx.resolver() else: resolver = ldnsx.resolver(str(server)) myDict = dict() qrySect = dict() queSect = dict() ansList = [] autList = [] addList = [] #FIXME qrySect['Versions'] = "Dyn DNS Looking Glass 1.0.0" # qrySect['Description'] = "" #FIXME try: #configure the resolver #flags are the same options used for drill -o on the command line pkt = resolver.query(str(domain), str(qtype), str(qclass), flags, 1) if not pkt is None: for rr in pkt.question(): queSect['Qname'] = rr.owner() queSect['Qtype'] = rr.rr_type() queSect['Qclass'] = rr.rr_class() for rr in pkt.additional(): addList.append(decode_rr(rr)) for rr in pkt.authority(): autList.append(decode_rr(rr)) for rr in pkt.answer(): ansList.append(decode_rr(rr)) qrySect['ServerIP'] = pkt.answer_from() qrySect['Duration'] = pkt.query_time() myDict['ReturnCode'] = pkt.rcode() except IOError, e: if not pkt is None: myDict['ReturnCode'] = pkt.rcode() else: myDict['ReturnCode'] = "TIMEOUT"
def walk(domain): res = ldnsx.resolver("193.110.157.136", dnssec=True) pkt = res.query(domain, 666) try: nsec_rr = pkt.authority(rr_type="NSEC")[0] except: print "no NSEC found, domain is not signed or using NSEC3" sys.exit() for rr_type in nsec_rr[5].split(' ')[:-1]: for rr in ldnsx.get_rrs(domain, rr_type): print str(rr)[:-1] next_rec = nsec_rr[4] if (next_rec != domain) and (next_rec[-len(domain):] == domain): walk(next_rec)
def tracens(domain): """Traces domain from the root down, notifying delegation and glue errors""" my_res = ldnsx.resolver("j.root-servers.net") result = my_res.query(domain, "NS", flags=[]) if result is None: print "Error: root name server failure" sys.exit() referrals = list() while result.answer() == []: my_res.drop_nameservers() for ns in result.authority(rr_type='NS'): my_res.add_nameserver(ns[4]) #print "Referral:\n{}\nGLUES:\n{}\n****".format(result.authority(), # result.additional()) referrals.append(result.authority()) checkglues(result.additional()) result = my_res.query(domain, "NS", flags=[]) if result is None: print "Error: No data for {} !".format(domain) if referrals: print "Last referral was\n{}\n".format(referrals.pop()) break if result: lastref = referrals.pop() #print "Delegation:\n{}".format(lastref) #print "Final:\n{}".format(result.answer()) if lastref[0].owner() == result.answer()[0].owner(): delegation = rrtoset(lastref) final = rrtoset(result.answer()) missing_delegations = final - delegation extra_delegations = delegation - final if missing_delegations: print "Missing delegations for {}: {}".format( domain, ", ".join(missing_delegations)) if extra_delegations: print "Extra delegations for {}: {}".format( domain, ", ".join(extra_delegations))
def tracens(domain): """Traces domain from the root down, notifying delegation and glue errors""" my_res = ldnsx.resolver("j.root-servers.net"); result = my_res.query(domain, "NS", flags=[]); if result is None: print "Error: root name server failure" sys.exit() referrals = list(); while result.answer() == []: my_res.drop_nameservers() for ns in result.authority(rr_type='NS'): my_res.add_nameserver(ns[4]) #print "Referral:\n{}\nGLUES:\n{}\n****".format(result.authority(), # result.additional()) referrals.append(result.authority()) checkglues(result.additional()) result = my_res.query(domain, "NS", flags=[]); if result is None: print "Error: No data for {} !".format(domain) if referrals: print "Last referral was\n{}\n".format(referrals.pop()) break if result: lastref = referrals.pop() #print "Delegation:\n{}".format(lastref) #print "Final:\n{}".format(result.answer()) if lastref[0].owner() == result.answer()[0].owner(): delegation = rrtoset(lastref) final = rrtoset(result.answer()) missing_delegations = final - delegation extra_delegations = delegation - final if missing_delegations: print "Missing delegations for {}: {}".format(domain, ", ".join(missing_delegations)) if extra_delegations: print "Extra delegations for {}: {}".format(domain, ", ".join(extra_delegations))
import ldnsx resolver = ldnsx.resolver() pkt = resolver.query("nic.cz", "MX") if (pkt): mx = pkt.answer() if (mx): mx.sort() print mx
#!/usr/bin/python # -*- coding: utf-8 -*- import ldnsx import sys debug = True if len(sys.argv) < 2: print "Usage:", sys.argv[0], "domain [resolver_addr]" sys.exit(1) name = sys.argv[1] # Create resolver resolver = ldnsx.resolver(dnssec=True) # Custom resolver if len(sys.argv) > 2: # Clear previous nameservers resolver.set_nameservers(sys.argv[2:]) # Resolve DNS name pkt = resolver.query(name, "A") if pkt and pkt.answer(): # Debug if debug: print "NS returned:", pkt.rcode(), "(AA: %d AD: %d)" % ( "AA" in pkt.flags(), "AD" in pkt.flags())
import ldnsx resolver = ldnsx.resolver() pkt = resolver.query("nic.cz", "MX") if pkt: mx = pkt.answer() if mx: mx.sort() print mx
#!/usr/bin/python # -*- coding: utf-8 -*- import ldnsx import sys debug = True if len(sys.argv) < 2: print "Usage:", sys.argv[0], "domain [resolver_addr]" sys.exit(1) name = sys.argv[1] # Create resolver resolver = ldnsx.resolver(dnssec=True) # Custom resolver if len(sys.argv) > 2: # Clear previous nameservers resolver.set_nameservers(sys.argv[2:]) # Resolve DNS name pkt = resolver.query(name, "A") if pkt and pkt.answer(): # Debug if debug: print "NS returned:", pkt.rcode(), "(AA: %d AD: %d)" % ( "AA" in pkt.flags(), "AD" in pkt.flags() ) # SERVFAIL indicated bogus name
def tracens(server, domain): """ Traces domain from the root down, watches for non delageted zones. Returns boolean status if zone should be removed from server config. False...zone should be kept in server config True ...zone should be deleted """ if domain == ".": #Questions regarding root zone would not lead to a refferal answer return True res = ldnsx.resolver() my_res = ldnsx.resolver("j.root-servers.net"); result = my_res.query(domain, "NS", flags=[]); if result is None: print "Error: root name server failure" sys.exit() loopcount = 0 referrals = list(); while result and not result.answer(): #print "AUTHORITY\n{}\nADDITIONAL\n{}\n\n".format(result.authority(), result.additional()) referral = result.authority(rr_type='NS') referrals.append(referral) if result.rcode() == "NXDOMAIN": print "{}: delegation ends at {}".format(domain, result.authority().pop().owner()) result = None; break result=None loopcount += 1 if loopcount > 20: print "{}: Looping detected".format(domain) break #Iterate through referrals to find the longest chain for ns_rr in referral: ns = ns_rr[4] nsip4 = res.query(ns, 'A'); nsip6 = res.query(ns, 'AAAA'); if ( (not nsip4.answer(rr_type='A')) and (not nsip6.answer(rr_type='AAAA')) ): print "{}: Invalid delegation to {}".format(domain,ns) continue my_res.drop_nameservers() my_res.add_nameserver(ns) r = my_res.query(domain, "NS", flags=[]); if not r: print "{}: Query failed on server {}".format(domain, ns) elif r.rcode() not in ("NOERROR", "NXDOMAIN"): print "{}: RCODE {} from server {}".format(domain, r.rcode(), ns) #Prefer refferals instead of final answers, if chain is not too long elif (result is None) or (result.answer() and (not r.answer()) and loopcount < 10 ): result=r if not result.answer(): break #We have a referral already if result: lastref = referrals.pop() #print "Delegation:\n{}".format(lastref) #print "Final:\n{}".format(result.answer()) if lastref[0].owner() == result.answer()[0].owner(): delegation = rrtoset(lastref) final = rrtoset(result.answer()) if server not in (delegation | final): print "{}: server {} not in delegation nor zone apex".format(domain, server) return True elif server not in delegation: print "{}: server {} in zone apex, but not in the delegation".format(domain, server) elif server not in final: print "{}: server {} delegated, but not in zone apex".format(domain, server) else: if server not in rrtoset(result.answer()): print "{}: subdomain on same server, {} not in apex".format(domain, server) return True #Result would be None if delegation chain is broken return False if result else True;
#!/usr/bin/env python2 # vim: expandtab tabstop=4 # DNS Delegation checker # Copyright Ondrej Caletka, CESNET 2014 # Licence: GNU GPLv2 from collections import defaultdict import ldnsx import sys system_res = ldnsx.resolver(); def name2ipset(name): """Returns a set of IPv4 and IPv6 addresses associated with a name""" arecords = system_res.query(name, 'A').answer(rr_type="A") aaaarecords = system_res.query(name, 'AAAA').answer(rr_type="AAAA") results = set() for record in arecords: results.add(record['ip']) for record in aaaarecords: results.add(record['ip']) return results def analyzeglues(gluename, glueips): """Analyze difference between GLUE records and actual values from DNS.""" dnsips = name2ipset(gluename); #print "Glues for {}:\n{}\nDNS set for {}:\n{}\n".format(gluename, glueips, gluename, dnsips); missing_glues = dnsips - glueips; extra_glues = glueips - dnsips;