def create_change_request(record_type): """Function to parse zone data and create a change XML record for specific record type (A, AAAA, CNAME .....)""" records = zone.iterate_rdatas(record_type) """ Create a list of unquie records so we can group commom requests together""" name_list = [] for (name, ttl, rdata) in records: name_list.append(name) """ Remove duplicates """ name_list = unquie(name_list) """ This little nested loop takes care of multiple <ResourceRecord> values for a given <Name> """ for n in name_list: print (" <Change>") print (" <Action>CREATE</Action>") print (" <ResourceRecordSet>") print (" <Name>%s</Name>" % (n)) print (" <Type>%s</Type>" % (record_type)) print (" <TTL>%s</TTL>" % (ttl)) print (" <ResourceRecords>") for (name, ttl, rdata) in zone.iterate_rdatas(record_type): if n == name: print (" <ResourceRecord>") print (" <Value>%s</Value>" % (rdata)) print (" </ResourceRecord>") print (" </ResourceRecords>") print (" </ResourceRecordSet>") print (" </Change>")
def check_domain_for_zone_transfer(domain): kraken.log(kraken.LOG_LVL_INFO, "getting NS records for " + domain) try: answers = dns.resolver.query(domain, 'NS') except dns.resolver.NoAnswer: return nameservers = map(str, answers) zone = None for nameserver in nameservers: kraken.log(kraken.LOG_LVL_INFO, "trying a zone transfer for " + domain + " from name server " + nameserver) try: zone = dns.zone.from_xfr(dns.query.xfr(nameserver, domain)) kraken.log(kraken.LOG_LVL_INFO, "successful tranfser for " + domain + " on server " + nameserver) except (DNSException, socket.error, EOFError): kraken.log(kraken.LOG_LVL_INFO, "transfer failed on server: " + nameserver) continue if zone == None: return names_to_ips = {} for (name, ttl, rdata) in zone.iterate_rdatas('A'): if name.is_wild(): continue if not name.is_absolute(): name = name.concatenate(zone.origin) name = name.to_text().rstrip('.') ip = str(rdata) kraken.host_manager.set_host_details({'ipv4_addr':ip, 'names':name}) if not name in names_to_ips: names_to_ips[name] = [] names_to_ips[name].append(ip) for (name, ttl, rdata) in zone.iterate_rdatas('CNAME'): if name.is_wild(): continue if not name.is_absolute(): name = name.concatenate(zone.origin) cname = name.to_text().rstrip('.') if rdata.target.is_absolute(): target = rdata.target.to_text().rstrip('.') else: target = rdata.target.concatenate(zone.origin).to_text().rstrip('.') if target in names_to_ips: for ip in names_to_ips[target]: kraken.host_manager.set_host_details({'ipv4_addr':ip, 'names':[target, cname]}) else: try: dnsresp = socket.gethostbyname_ex(target) except: continue # probably a "herror: [Errno 4] No address associated with name" error if ip in dnsresp[2]: kraken.host_manager.add_hostname(ip, [target, cname]) return
def check_rdtype(zone, nss, rdtype): for (name, ttl, rdata) in zone.iterate_rdatas(rdtype): name = name.to_text() if name == "sitespect.mozilla.com": pdb.set_trace() results = [] for ns in nss: res = resolve(name, ns, rdclass=rdtype) if res.strip('\n').find("unused") != -1: continue results.append(res) if len(set(results)) > 1: if results[0] != "": the_rest_are_empty = True for result in results[1:]: if result: the_rest_are_empty = False if the_rest_are_empty: # We don't care that our nameserver has more info than the # others. We only care if the data is different or our NS # has _less_ info. continue print "------------------------------------" print "Found differences for {0} {1}:".format(rdtype, name) for ns, result in itertools.izip(nss, results): print "{0} returned:\n-->\n{1}\n<--".format(ns, result.strip('\n'))
def get_zone(zone_name): """ Query a DNS zone file and get every record and return it in JSON format """ records = {} if not zone_name.endswith('.'): zone_name = zone_name + '.' if zone_name not in VALID_ZONES: return jsonify({'error': 'zone file not permitted'}) try: zone = dns.zone.from_xfr(dns.query.xfr(DNS_SERVER, zone_name)) except dns.exception.FormError: return jsonify({'fail': zone_name}) for (name, ttl, rdata) in zone.iterate_rdatas(): if rdata.rdtype != SOA: if records.get(str(name), False): records[str(name)] = records[str(name)] + [{'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl}] else: records[str(name)] = [{'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl}] return jsonify({zone_name: records})
def migrate_TXT(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('TXT'): name = name.to_text().strip('.') print str(name) + " TXT " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = name.split('.')[1:] domain = ensure_domain('.'.join(domain_name), force=True) data = rdata.to_text().strip('"') if TXT.objects.filter(label=label, domain=domain, txt_data=data).exists(): txt = TXT.objects.get(label=label, domain=domain, txt_data=data) else: txt = TXT(label=label, domain=domain, txt_data=data, description=rdata.comment, ttl=ttl) txt.full_clean() txt.save() for view in views: txt.views.add(view) txt.save()
def migrate_CNAME(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('CNAME'): name = name.to_text().strip('.') print str(name) + " CNAME " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = name.split('.')[1:] domain = ensure_domain('.'.join(domain_name), force=True) data = rdata.target.to_text().strip('.') if CNAME.objects.filter(label=label, domain=domain, target=data).exists(): cn = CNAME.objects.get(label=label, domain=domain, target=data) else: cn = CNAME(label=label, domain=domain, target=data, description=rdata.comment, ttl=ttl) cn.full_clean() cn.save() for view in views: cn.views.add(view) cn.save()
def migrate_MX(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('MX'): name = name.to_text().strip('.') print str(name) + " MX " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(domain_name, force=True) priority = rdata.preference server = rdata.exchange.to_text().strip('.') if MX.objects.filter(label=label, domain=domain, server=server, priority=priority): mx = MX.objects.get( label=label, domain=domain, server=server, priority=priority, ) else: mx = MX.objects.create(label=label, domain=domain, server=server, priority=priority, ttl=ttl, description=rdata.comment) for view in views: mx.views.add(view) mx.save()
def get_zone(zone_name): """ Query a DNS zone file and get every record and return it in JSON format """ records = {} if not zone_name.endswith('.'): zone_name = zone_name + '.' if zone_name not in VALID_ZONES: return jsonify({'error': 'zone file not permitted'}) try: zone = dns.zone.from_xfr(dns.query.xfr(DNS_SERVER, zone_name)) except dns.exception.FormError: return jsonify({'fail': zone_name}) for (name, ttl, rdata) in zone.iterate_rdatas(): if rdata.rdtype != SOA: if records.get(str(name), False): records[str( name)] = records[str(name)] + [{ 'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl }] else: records[str(name)] = [{ 'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl }] return jsonify({zone_name: records})
def get_zone(zone_name): config = parse_config('config.ini') records = {} if not zone_name.endswith('.'): zone_name = zone_name + "." try: zone = dns.zone.from_xfr(dns.query.xfr(config['nameserver'], zone_name)) except dns.exception.FormError: return jsonify({'error': zone_name}) for (name, ttl, rdata) in zone.iterate_rdatas(): if rdata.rdtype != SOA: if records.get(str(name), 0): records[str( name)] = records[str(name)] + [{ 'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl }] else: records[str(name)] = [{ 'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl }] return jsonify({zone_name: records})
def migrate_AAAA(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('AAAA'): name = name.to_text().strip('.') print str(name) + " AAAA " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] if label.startswith('unused'): continue domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(domain_name, force=True) ip_upper, ip_lower = ipv6_to_longs(rdata.to_text()) if AddressRecord.objects.filter(label=label, domain=domain, ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6').exists(): a = AddressRecord.objects.get(label=label, domain=domain, ip_type='6', ip_upper=ip_upper, ip_lower=ip_lower) else: a = AddressRecord(label=label, domain=domain, ip_str=rdata.to_text(), ip_type='6') a.clean() a.save() for view in views: a.views.add(view) a.save()
def get_zone(zone_name): """ Query a DNS zone file and get every record and return it in JSON format """ config = parse_config('config.ini') record_types = ['A', 'AAAA', 'CNAME', 'MX', 'NS', 'TXT', 'SOA'] valid_zones = config['zones'] records = {} if not zone_name.endswith('.'): zone_name = zone_name + '.' if zone_name not in valid_zones: return jsonify({'error': 'zone file not permitted'}) try: zone = dns.zone.from_xfr(dns.query.xfr(config['nameserver'], zone_name)) except dns.exception.FormError: return jsonify({'fail': zone_name}) for (name, ttl, rdata) in zone.iterate_rdatas(): if rdata.rdtype != SOA: if records.get(str(name), 0): records[str(name)] = records[str(name)] + [{'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl}] else: records[str(name)] = [{'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl}] return jsonify({zone_name: records})
def migrate_CNAME(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('CNAME'): name = name.to_text().strip('.') print str(name) + " CNAME " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = name.split('.')[1:] domain = ensure_domain('.'.join(domain_name), force=True) data = rdata.target.to_text().strip('.') if CNAME.objects.filter(label=label, domain=domain, target=data).exists(): cn = CNAME.objects.get( label=label, domain=domain, target=data ) else: cn = CNAME( label=label, domain=domain, target=data, description=rdata.comment, ttl=ttl ) cn.full_clean() cn.save() for view in views: cn.views.add(view) cn.save()
def test_create_zone(self, execute): zone = self._create_dnspy_zone('example.org.') self.backend.create_zone(zone) # Ensure denominator called for each record (except SOA) # plus one to update zone data self.assertEqual(len(list(zone.iterate_rdatas())), execute.call_count)
def migrate_MX(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('MX'): name = name.to_text().strip('.') print str(name) + " MX " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(domain_name, force=True) priority = rdata.preference server = rdata.exchange.to_text().strip('.') if MX.objects.filter(label=label, domain=domain, server=server, priority=priority): mx = MX.objects.get( label=label, domain=domain, server=server, priority=priority, ) else: mx = MX.objects.create( label=label, domain=domain, server=server, priority=priority, ttl=ttl, description=rdata.comment ) for view in views: mx.views.add(view) mx.save()
def migrate_TXT(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('TXT'): name = name.to_text().strip('.') print str(name) + " TXT " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = name.split('.')[1:] domain = ensure_domain('.'.join(domain_name), force=True) data = rdata.to_text().strip('"') if TXT.objects.filter(label=label, domain=domain, txt_data=data).exists(): txt = TXT.objects.get( label=label, domain=domain, txt_data=data ) else: txt = TXT( label=label, domain=domain, txt_data=data, description=rdata.comment, ttl=ttl ) txt.full_clean() txt.save() for view in views: txt.views.add(view) txt.save()
def migrate_A(zone, root_domain, soa, views): names = [] for (name, ttl, rdata) in zone.iterate_rdatas('A'): names.append((name.to_text().strip('.'), rdata)) sorted_names = list(sorted(names, cmp=lambda n1, n2: -1 if len(n1[0].split('.')) > len(n2[0].split('.')) else 1)) for name, rdata in sorted_names: print str(name) + " A " + str(rdata) if name.startswith("unusedspace"): print "Skipping {0} A {1}".format(name, rdata) continue exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(domain_name, force=True) a, _ = AddressRecord.objects.get_or_create(label=label, domain=domain, ip_str=rdata.to_text(), ip_type='4') for view in views: a.views.add(view) a.save()
def migrate_A(zone, root_domain, soa, views): names = [] for (name, ttl, rdata) in zone.iterate_rdatas('A'): names.append((name.to_text().strip('.'), rdata)) sorted_names = list( sorted(names, cmp=lambda n1, n2: -1 if len(n1[0].split('.')) > len(n2[0].split('.')) else 1)) for name, rdata in sorted_names: print str(name) + " A " + str(rdata) if name.startswith("unusedspace"): print "Skipping {0} A {1}".format(name, rdata) continue exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(domain_name, force=True) a, _ = AddressRecord.objects.get_or_create(label=label, domain=domain, ip_str=rdata.to_text(), ip_type='4') for view in views: a.views.add(view) a.save()
def load_reverse_records(zone, record_type, zone_type): global debug, trace, no_dns, warning, arg_allow_dns_lookups ## for the given zone, load all records of the requested type (PTR) into the global dictionary ## modifies global reverse_records[] !!! ## as this will be called for ALL zones being loaded, we can also check for reverse ## records that might be in a forward zone record_count = 0 #make sure we aren't trying to load non-PTR records into the reverse dictionary #which would be a parameter error if (record_type != 'PTR'): print('load_reverse_records: invalid record type %s' % record_type) sys.exit() for (qname, ttl, rdata) in zone.iterate_rdatas(record_type): # this is already a full address since we used relativize=False if (debug): print ('load_reverse_records: qname %s target %s' % (qname, str(rdata.target))) # if the zone type isn't a reverse zone, then we shouldn't see any PTR records if (zone_type != 'reverse'): print() print('BADREC: reverse record %s/%s found in forward zone' % (qname,rdata.target)) continue # append the target we just found to the list of targets for this qname reverse_records[qname].append(rdata.target) record_count += 1 return record_count
def makePutContext(self, name, zone): return aadict( name = name, zone = zone, records = self.getRecords(name), newrecords = [Record.from_rdata(rdata) for rdata in zone.iterate_rdatas()], )
def load_forward_records(zone, record_type, zone_type): global debug, trace, no_dns, warning, arg_allow_dns_lookups ## for the given zone, load all records of the requested type (A or AAAA) into the global dictionary ## modifies global forward_records[] !!! ## as this will be called for ALL zones being loaded, we can also check for forward ## records that might be in a reverse zone record_count = 0 # make sure we aren't trying to load non A or AAAA records into the forward dictionary # (parameter error) if ( (record_type != 'A') and (record_type != 'AAAA')): print('load_forward_records: invalid record type %s' % record_type) sys.exit() # search through the zone file looking for A/AAAA for (fqdn, ttl, rdata) in zone.iterate_rdatas(record_type): # this is already a FQDN since we used relativize=False #special case to get rid of the self-reference record if (not fqdn): continue if (debug): print ('fqdn <%s> zone <%s>' % (fqdn, zone)) # if the zone type isn't a forward zone, then we should not see any forward records, emit warning if (zone_type != 'forward'): print() print('BADREC: forward record %s/%s found in reverse zone' % (fqdn,rdata.address)) continue addr = ipaddress.ip_address(rdata.address) if (debug): print ('fqdn %s IP %s' % (fqdn, str(addr))) # append the address we just found to the list of addresses for this FQDN forward_records[fqdn].append(addr) record_count += 1 return record_count
def modify_dns(new_IP): domain = "cap.com" zoneFile = "/etc/bind/zones/db.cap.com" zone = dns.zone.from_file(zoneFile, domain) change = "www" rdataset = zone.find_rdataset(change, rdtype='A') req_reload = False for rdata in rdataset: if rdata.address != new_IP: req_reload = True rdata.address = new_IP if req_reload: for (name, ttl, rdata) in zone.iterate_rdatas('SOA'): serial = rdata.serial + 1 rdata.serial = serial zone.to_file(zoneFile) proc = Popen(["rndc", "reload", "cap.com"], stdout = PIPE, stderr = PIPE) out,err = proc.communicate() if err: print err else: pass #print "DNS zone modification complete" else: pass
def migrate_SRV(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('SRV'): target = rdata.target.to_text().strip('.') if target == "": target = "." port = rdata.port weight = rdata.weight prio = rdata.priority name = name.to_text().strip('.') print str(name) + " SRV " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = name.split('.')[1:] domain = ensure_domain('.'.join(domain_name), force=True) if not SRV.objects.filter(label=label, domain=domain, target=target, port=port, weight=weight, priority=prio).exists(): srv = SRV(label=label, domain=domain, target=target, port=port, weight=weight, priority=prio) srv.full_clean() srv.save() for view in views: srv.views.add(view) srv.save()
def makePutContext(self, name, zone): return aadict( name=name, zone=zone, records=self.getRecords(name), newrecords=[ Record.from_rdata(rdata) for rdata in zone.iterate_rdatas() ], )
def parseRecordFromFile(the_file, origin): regex = re.compile(r'.*\.$') zone = dns.zone.from_file(the_file, origin) record_list = [(str(name), str(ttl), RRTYPE_LIST[str(rdata.rdtype)], _renovateRdata(regex, origin, rdata.rdtype, str(rdata)), '1') for (name, ttl, rdata) in zone.iterate_rdatas() if rdata.rdtype is not 6] return record_list
def makePutContext(self, name, zone): ret = super(Driver, self).makePutContext(name, zone) ret.zoneid = self._zones()[name] for name, ttl, rdata in zone.iterate_rdatas(): if dns.rdataclass.to_text(rdata.rdclass) != 'IN': raise api.UnsupportedRecordType( _('PowerdDNS does not support non-"IN" record classes: {!r}', (name, ttl, rdata))) return ret
def remove_dnssec_from_zone(zone, only_remove_sigs): for record in list(zone.iterate_rdatas()): zone.delete_rdataset(record[0], dns.rdatatype.RRSIG, covers=record[2].rdtype) zone.delete_rdataset(record[0], dns.rdatatype.NSEC) zone.delete_rdataset(record[0], dns.rdatatype.NSEC3) if (not only_remove_sigs): zone.delete_rdataset(record[0], dns.rdatatype.NSEC3PARAM) zone.delete_rdataset(record[0], dns.rdatatype.DNSKEY)
def dnszone (account): zone_file = "/etc/bind/db.local" domain = "localhost" try: zone = dns.zone.from_file(zone_file, domain) for (name, ttl, rdata) in zone.iterate_rdatas(SOA): print rdata serial = rdata.serial new_serial = datetime.now().strftime("%Y%m%d%H%M%S") print "Changing SOA serial from %s to %s" % (serial, new_serial) rdata.serial = int(new_serial) rdata.mname = dns.name.Name(("ns1", "codeless-hosting", "co", "")) print "Adding record of type A:", account.domain NS_add = "@" target = dns.name.Name(("ns1", "codeless-hosting", "co", "")) print "Adding record of type NS:", NS_add rdataset = zone.find_rdataset(NS_add, rdtype=NS, create=True) rdata = dns.rdtypes.ANY.NS.NS(IN, NS, target) rdataset.add(rdata, ttl=86400) rdataset = zone.find_rdataset("www", rdtype=A, create=True) rdata = dns.rdtypes.IN.A.A(IN, A, address="192.168.1.30") rdataset.add(rdata, ttl=86400) new_zone_file = "/etc/bind/zones/db.%s" % account.domain zone.to_file(new_zone_file) except DNSException, e: print e
def getCurrentSerial(zoneName): try: zone = dns.zone.from_file(getZoneFile(zoneName), zoneName) except: return "0000000000" for (name, ttl, rdata) in zone.iterate_rdatas(dns.rdatatype.SOA): try: serial = str(rdata.serial) + "0000000000"; except: serial = "0000000000"; return serial[0:10]
def migrate_NS(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('NS'): name = name.to_text().strip('.') print str(name) + " NS " + str(rdata) domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(name, force=True) ns, _ = Nameserver.objects.get_or_create( domain=domain, server=rdata.target.to_text().strip('.')) for view in views: ns.views.add(view) ns.save()
def domain_exists_in_catalogzone(self, **params): try: zone = dns.zone.from_xfr( dns.query.xfr(params['nameserver'], params['catzone_name'], lifetime=params['timeout'])) for (_, _, rdata) in zone.iterate_rdatas("PTR"): if rdata.to_text() == ('%s%s' % (params['zone_name'], '.')): return params['zone_name'] except: return None
def migrate_NS(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('NS'): name = name.to_text().strip('.') print str(name) + " NS " + str(rdata) domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(name, force=True) ns, _ = Nameserver.objects.get_or_create(domain=domain, server=rdata.target.to_text().strip('.')) for view in views: ns.views.add(view) ns.save()
def getreverseMap(zones): res = {} for k, v in Zone.getZones().iteritems(): try: zone = dns.zone.from_file(v['file'], os.path.basename(v['file']), relativize=False) for (name, ttl, rdata) in zone.iterate_rdatas('A'): value = res.get(rdata.address, []) value.append({ 'file':v['file'], 'domain':name.to_text().rstrip('.')}) res[rdata.address] = value except NoSOA: continue return res
def domain_exists_in_bind_cache(self, **params): try: zone = dns.zone.from_xfr( dns.query.xfr(params['nameserver'], params['zone_name'], lifetime=params['timeout'])) for (name, _, _) in zone.iterate_rdatas("SOA"): if name.to_text() == ( '%s%s' % (params['zone_name'], '.')) or name.to_text() == '@': return params['zone_name'] except: return None
def migrate_PTR(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('PTR'): fqdn = rdata.target.to_text().strip('.') if fqdn.find('unused') != -1: print "Skipping " + name.to_text() + " " + fqdn continue # 4.3.2.1.IN-ADDR.ARPA. --> 1.2.3.4 name = name.to_text().lower().strip('.') if name.endswith('.in-addr.arpa'): ip_type = '4' ip_str = name.replace('.in-addr.arpa', '') ip_str = '.'.join(list(reversed(ip_str.split('.')))) ip_upper, ip_lower = 0, ipaddr.IPv4Address(ip_str) elif name.endswith('.ip6.arpa'): ip_type = '6' ip_str = name.replace('.ip6.arpa', '') chunks = [ ''.join(ip_str.split('.')[i:i + 4]) for i in xrange(0, len(ip_str.split('.')), 4) ] ip_str = ':'.join(chunks)[::-1] ip_upper, ip_lower = ipv6_to_longs(ip_str) else: print "We so f****d. Lol" pdb.set_trace() continue if ip_str == '10.2.171.IN': print "Skipping " + ip_str + " " + fqdn continue print str(name) + " PTR " + str(fqdn) ptr = PTR.objects.filter(name=fqdn, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type) if ptr: ptr = ptr[0] else: ptr = PTR(name=fqdn, ip_str=ip_str, ip_type=ip_type, description=rdata.comment) ptr.full_clean() ptr.save() if views: for view in views: ptr.views.add(view) ptr.save()
def getMap(zones): res = {} for k, v in Zone.getZones().iteritems(): try: zone = dns.zone.from_file(v['file'], os.path.basename(v['file']), relativize=False) for (name, ttl, rdata) in zone.iterate_rdatas('A'): key = name.to_text().rstrip('.') val = res.get(key, []) if not {'ip':rdata.address, 'file':v['file']} in val: val.append({'ip':rdata.address, 'file':v['file']}) res[key] = val except NoSOA: continue return res
def getreverseMap(zones): res = {} for k, v in Zone.getZones().items(): try: zone = dns.zone.from_file( v['file'], os.path.basename(v['file']), relativize=False) for (name, ttl, rdata) in zone.iterate_rdatas('A'): value = res.get(rdata.address, []) value.append( {'file': v['file'], 'domain': name.to_text().rstrip('.')}) res[rdata.address] = value except NoSOA: continue return res
def _get_hosts_from_dns(config): """Does a DNS zone transfer off the SOA for a given domain to get a list of hosts that can be pushed to.""" try: soa_answer = dns.resolver.query(config.dns.domain, "SOA", tcp=True) master_answer = dns.resolver.query(soa_answer[0].mname, "A", tcp=True) xfr_answer = dns.query.xfr(master_answer[0].address, config.dns.domain) zone = dns.zone.from_xfr(xfr_answer) return sorted_nicely([name.to_text() for name, ttl, rdata in zone.iterate_rdatas("A")]) except dns.exception.DNSException, e: raise HostLookupError("host lookup by dns failed: %r" % e)
def getMap(zones): res = {} for k, v in Zone.getZones().items(): try: zone = dns.zone.from_file( v['file'], os.path.basename(v['file']), relativize=False) for (name, ttl, rdata) in zone.iterate_rdatas('A'): key = name.to_text().rstrip('.') val = res.get(key, []) if not {'ip': rdata.address, 'file': v['file']} in val: val.append({'ip': rdata.address, 'file': v['file']}) res[key] = val except NoSOA: continue return res
def sync(domain, zone, serial): print("avahi-publisher: Pushing zone %s [serial %s] to Avahi" % (domain, serial)) keep = dict() for name, ttl, rdata in zone.iterate_rdatas(): type_ = rdata.rdtype if type_ == dns.rdatatype.SOA: continue elif type_ == dns.rdatatype.NS: continue key = '%s,%s,%d,%s' % (name, domain, rdata.rdtype, rdata.to_text(name)) d = avahi_groups.get(domain, None) if d is None: d = dict() avahi_groups[domain] = d group = d.get(key, None) if group is None: group = avahi_daemon.newGroup() d[key] = group if DEBUG is not None: print( 'avahi-publisher:\t+ %s\t%d\t%s\t%s\t%s' % (name, ttl, dns.rdataclass.to_text(rdata.rdclass), dns.rdatatype.to_text(rdata.rdtype), rdata.to_text(name))) group.AddRecord(avahi.IF_UNSPEC, avahi.PROTO_INET, 0, str(name), rdata.rdclass, rdata.rdtype, ttl if ttl > 0 else DEFAULT_TTL, rdata2avahi(rdata)) group.Commit() keep[key] = group d = avahi_groups.get(domain, None) if d is None: d = dict() avahi_groups[domain] = d keys = list(d.keys()) for k in keys: if k in keep: continue if DEBUG is not None: print('avahi-publisher:\t- %s' % k) d[k].Free() del d[k]
def update_domain(domain, zonefile, secret): ''' Updates the given domain with the new ACME secret. ''' zone = dns.zone.from_file(zonefile, domain) # updata soa serial for (_, _, rdata) in zone.iterate_rdatas(SOA): rdata.serial += 1 # update the acme challenge acme_record = zone.find_rdataset('_acme-challenge', rdtype=TXT) for rdata in acme_record: rdata.strings = [secret.encode("utf8")] zone.to_file(zonefile)
def get_all_hosts(self): """Pull all hosts from DNS by doing a zone transfer.""" try: soa_answer = dns.resolver.query(self.domain, "SOA", tcp=True) soa_host = soa_answer[0].mname master_answer = dns.resolver.query(soa_host, "A", tcp=True) master_addr = master_answer[0].address xfr_answer = dns.query.xfr(master_addr, self.domain) zone = dns.zone.from_xfr(xfr_answer) return [name.to_text() for name, ttl, rdata in zone.iterate_rdatas("A")] except dns.exception.DNSException, e: raise HostLookupError("host lookup by dns failed: %r" % e)
def is_catalogzone_exists(self, **params): try: zone = dns.zone.from_xfr( dns.query.xfr(params['nameserver'], params['catzone_name'], lifetime=params['timeout'])) for (_, _, _) in zone.iterate_rdatas("SOA"): return None # if rdata.to_text() == ('%s%s' % (params['zone_name'], '.')): # return params['zone_name'] except: self._module.exit_json( changed=False, result= 'Catalog zone - Add skipped. Catalog Zones %s is not yet configured.' % params['catzone_name'])
def migrate_PTR(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('PTR'): fqdn = rdata.target.to_text().strip('.') if fqdn.find('unused') != -1: print "Skipping "+name.to_text()+" "+fqdn continue # 4.3.2.1.IN-ADDR.ARPA. --> 1.2.3.4 name = name.to_text().lower().strip('.') if name.endswith('.in-addr.arpa'): ip_type = '4' ip_str = name.replace('.in-addr.arpa','') ip_str = '.'.join(list(reversed(ip_str.split('.')))) ip_upper, ip_lower = 0, ipaddr.IPv4Address(ip_str) elif name.endswith('.ip6.arpa'): ip_type = '6' ip_str = name.replace('.ip6.arpa','') chunks = [''.join(ip_str.split('.')[i:i+4]) for i in xrange(0, len(ip_str.split('.')), 4)] ip_str = ':'.join(chunks)[::-1] ip_upper, ip_lower = ipv6_to_longs(ip_str) else: print "We so f****d. Lol" pdb.set_trace() continue if ip_str == '10.2.171.IN': print "Skipping "+ip_str+" "+fqdn continue print str(name) + " PTR " + str(fqdn) ptr = PTR.objects.filter(name=fqdn, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type) if ptr: ptr = ptr[0] else: ptr = PTR( name=fqdn, ip_str=ip_str, ip_type=ip_type, description=rdata.comment ) ptr.full_clean() ptr.save() if views: for view in views: ptr.views.add(view) ptr.save()
def import_zone(zone): names = cassandranames.CassandraNames() for (fqdn, ttl, rdata) in zone.iterate_rdatas(): fqdn = str(fqdn).rstrip(".") data = None preference = None if rdata.rdtype == A: data = rdata.address elif rdata.rdtype == MX: data = str(rdata.exchange) preference = rdata.preference elif rdata.rdtype == CNAME: data = str(rdata.target) elif rdata.rdtype == NS: data = str(rdata.target) if data is not None: names.insert(fqdn, rdata.rdtype, data, ttl=ttl, preference=preference)
def get_all_hosts(self): """Pull all hosts from DNS by doing a zone transfer.""" try: soa_answer = dns.resolver.query(self.domain, "SOA", tcp=True) soa_host = soa_answer[0].mname master_answer = dns.resolver.query(soa_host, "A", tcp=True) master_addr = master_answer[0].address xfr_answer = dns.query.xfr(master_addr, self.domain) zone = dns.zone.from_xfr(xfr_answer) return [ name.to_text() for name, ttl, rdata in zone.iterate_rdatas("A") ] except dns.exception.DNSException, e: raise HostLookupError("host lookup by dns failed: %r" % e)
def migrate_soa(zone, root_domain_name): for (name, ttl, rdata) in zone.iterate_rdatas('SOA'): print str(name) + " SOA " + str(rdata) exists = SOA.objects.filter(minimum=rdata.minimum, contact=rdata.rname.to_text().strip('.'), primary=rdata.mname.to_text().strip('.'), comment="SOA for" " {0}".format(root_domain_name)) if exists: soa = exists[0] else: soa = SOA(serial=rdata.serial, minimum=rdata.minimum, contact=rdata.rname.to_text().strip('.'), primary=rdata.mname.to_text().strip('.'), comment="SOA for" " {0}".format(root_domain_name)) soa.clean() soa.save() return soa
def migrate_soa(zone, root_domain_name): for (name, ttl, rdata) in zone.iterate_rdatas('SOA'): print str(name) + " SOA " + str(rdata) exists = SOA.objects.filter(minimum=rdata.minimum, contact=rdata.rname.to_text().strip('.'), primary=rdata.mname.to_text().strip('.'), description="SOA for" " {0}".format(root_domain_name)) if exists: soa = exists[0] else: new_serial = int(datetime.datetime.now().strftime("%Y%m%d01")) soa = SOA(serial=new_serial, minimum=rdata.minimum, contact=rdata.rname.to_text().strip('.'), primary=rdata.mname.to_text().strip('.'), description="SOA for" " {0}".format(root_domain_name)) soa.clean() soa.save() return soa
def migrate_SRV(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('SRV'): target = rdata.target.to_text().strip('.') port = rdata.port weight = rdata.weight prio = rdata.priority name = name.to_text().strip('.') print str(name) + " SRV " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] domain_name = name.split('.')[1:] domain = ensure_domain('.'.join(domain_name), force=True) if SRV.objects.filter(label=label, domain=domain, target=target, port=port, weight=weight, priority=prio).exists(): srv = SRV.objects.get(label=label, domain=domain, target=target, port=port, weight=weight, priority=prio) else: srv = SRV(label=label, domain=domain, target=target, port=port, weight=weight, priority=prio, description=rdata.comment, ttl=ttl) srv.full_clean() srv.save() for view in views: srv.views.add(view) srv.save()
def get_record_xfr(self): self.__record_axfr = [] try: for record_ns in self.__record_NS: try: ip = record_ns[-1:][0] zone = dns.zone.from_xfr(dns.query.xfr(ip, self.__domain)) self.__record_axfr.append(zone) for z in zone.iterate_rdatas(1): z_transfer = [domain, servicio, ttl, ip] = self.__domain, str(z[0]), str( z[1]), str(z[2]) self.__record_axfr.append(z_transfer) except dns.query.TransferError: self.__record_axfr.append( 'El servidor NS denego la solicitud de zona de transferencia: ' + record_ns[3]) continue except dns.exception.FormError: self.__record_axfr.append( 'El servidor NS denego la solicitud de zona de transferencia: ' + record_ns[3]) continue except EOFError: self.__record_axfr.append( 'Error de consulta de registro AXFR: paquete dañado: ' + record_ns[3]) except dns.resolver.Timeout: self.__record_axfr.append( 'Se agoto el tiempo de espera de registro AXFR: ' + record_ns[3]) continue except TimeoutError: self.__record_axfr.append( 'Se agoto el tiempo de espera de registro AXFR: ' + record_ns[3]) continue except TypeError: raise TypeError( 'No existen registro para realizar zona de transferencia') return self.__record_axfr
def read_zone(self, zone_name, filter_dnssec=True): """ Use dnspython to read in a Zone from the DNS server Returns a Zone Instance based on the read in data. NOTE: This is not from the DB! """ xfr_generator = dns.query.xfr(self.server, zone_name, port=self.port) try: zone = dns.zone.from_xfr(xfr_generator) except dns.exception.FormError as exc: zone = None finally: del xfr_generator # Unlink exception chaining if (not zone): raise NoSuchZoneOnServerError(zone_name, self.server_name, self.port) # Filter out dnssec if requested. dnssec_types = settings['dnssec_filter'].split() dnssec_rdtypes = [dns.rdatatype.from_text(x) for x in dnssec_types] nsec3param_rdtype = dns.rdatatype.from_text(RRTYPE_NSEC3PARAM) dnskey_rdtype = dns.rdatatype.from_text(RRTYPE_DNSKEY) # Need to find items to delete before deleting them, or # else zone data structure is corrupted. rr_delete_list = [] dnskey_flag = False nsec3param_flag = False for rdata in zone.iterate_rdatas(): if not dnskey_flag: dnskey_flag = (rdata[2].rdtype == dnskey_rdtype) if not nsec3param_flag: nsec3param_flag = (rdata[2].rdtype == nsec3param_rdtype) if rdata[2].rdtype in dnssec_rdtypes: rr_delete_list.append((rdata[0], rdata[2].rdtype, rdata[2].covers(),)) # Finally delete all unwanted records if filter_dnssec: for (name, rdtype, covers) in rr_delete_list: zone.delete_rdataset(name, rdtype, covers) # Finally, an unclutered zone without DNSSEC return (zone, dnskey_flag, nsec3param_flag)
def migrate_NS(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('NS'): name = name.to_text().strip('.') print str(name) + " NS " + str(rdata) domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(name, force=True) if Nameserver.objects.filter(domain=domain, server=rdata.target.to_text().strip('.')): ns = Nameserver.objects.get( domain=domain, server=rdata.target.to_text().strip('.'), ) else: ns = Nameserver.objects.create( domain=domain, server=rdata.target.to_text().strip('.'), description=rdata.comment, ttl=ttl ) for view in views: ns.views.add(view) ns.save()
def get_zone(zone_name): """ Query a DNS zone file and get every record and return it in JSON format """ config = parse_config('config.ini') record_types = ['A', 'AAAA', 'CNAME', 'MX', 'NS', 'TXT', 'SOA'] valid_zones = config['zones'] records = {} if not zone_name.endswith('.'): zone_name = zone_name + '.' if zone_name not in valid_zones: return jsonify({'error': 'zone file not permitted'}) try: zone = dns.zone.from_xfr(dns.query.xfr(config['nameserver'], zone_name)) except dns.exception.FormError: return jsonify({'fail': zone_name}) for (name, ttl, rdata) in zone.iterate_rdatas(): if rdata.rdtype != SOA: if records.get(str(name), 0): records[str( name)] = records[str(name)] + [{ 'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl }] else: records[str(name)] = [{ 'Answer': str(rdata), 'RecordType': rdata.rdtype, 'TTL': ttl }] return jsonify({zone_name: records})
def migrate_NS(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('NS'): name = name.to_text().strip('.') print str(name) + " NS " + str(rdata) domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(name, force=True) if Nameserver.objects.filter(domain=domain, server=rdata.target.to_text().strip('.')): ns = Nameserver.objects.get( domain=domain, server=rdata.target.to_text().strip('.'), ) else: ns = Nameserver.objects.create( domain=domain, server=rdata.target.to_text().strip('.'), description=rdata.comment, ttl=ttl) for view in views: ns.views.add(view) ns.save()