Re: axfr bringing my dns config error to light
Matthew Dempsky <[email protected]> Tue, 6 Apr 2010 21:27:00 -0700
| Newsgroups | gmane.network.djbdns |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Apr 6, 2010 at 6:02 PM, Jeremy Kister <[email protected]> wrote: > any ideas on how to differentiate 'essential' records from not ? Are the extra records actually problematic for you? But assuming they are, you could pipe the resulting file through a script like the Python script I wrote below. It's really only flexible enough to handle the output of axfr-get, but the general idea is how I'd tackle it. Also, if you want to support DNSSEC, you'll need to tweak the 'keep' function to keep DS records at zone cuts (and their RRSIGs). import sys def inzone(n1, n2): return n1[-(1 + len(n2)):] == '.' + n2 zone = None nsrecords = dict() # First pass through the zone file just to collect the NS records (and # the SOA record to determine what zone we're looking at). for line in sys.stdin: line = line.rstrip(' \t\n') if line == '': continue if line[0] not in 'Z&': continue fields = line[1:].split(':') if line[0] == 'Z': zone = fields[0] else: nsrecords.setdefault(fields[0], set()).add(fields[2].rstrip('.')) if not zone: print 'No SOA record?' sys.exit(1) # Don't worry about NS records for the zone itself. if zone in nsrecords: del nsrecords[zone] zonecuts = set() gluenames = set() # Go through NS records and discard grandchildren records. E.g., if # we're processing example.com and there are NS records for both # foo.example.com and bar.foo.example.com, we only want # foo.example.com. for n1, ns in nsrecords.items(): for n2 in nsrecords.keys(): if inzone(n1, n2): break else: zonecuts.add(n1) gluenames.update(ns) def keep(name, rtype): # Keep A and AAAA records for names used in NS records. if name in gluenames and rtype in ['+', 28]: return True for zone in zonecuts: # If a name is at a zone cut, only keep it if it's an NS record. if name == zone: return rtype == '&' # Discard any other records within the zone cut. if inzone(name, zone): return False # Keep everything else. return True sys.stdin.seek(0) # Loop through the file a second time, only printing out records for # names that we've decided to keep. for line in sys.stdin: line = line.rstrip(' \t\n') if line == '': continue if line[0] in '-#': print line continue fields = line[1:].split(':') if keep(fields[0], line[0] == ':' and int(fields[1]) or line[0]): print line