def handle_request(data, QDCOUNT, CONFIG, id, options): ind = 12 name, QTYPE, _, ind = getName(data, ind) answer = b'' try: z = easyzone.zone_from_file(name, CONFIG + 'example.com.conf') l = z.root.records(types[QTYPE]).items answer += struct.pack('!H', id) answer += struct.pack('!H', 33920) answer += struct.pack('!H', 0) answer += struct.pack('!H', len(l)) answer += struct.pack('!H', 0) answer += struct.pack('!H', 0) for elem in l: answer += dec(name) answer += struct.pack('!H', QTYPE) answer += struct.pack('!H', 1) answer += struct.pack('!I', 0) res = decodeData(elem, QTYPE) answer += struct.pack('!H', len(res)) answer += res except: if (name, QTYPE) in cache: return struct.pack("!H", id) + cache[(name, QTYPE)][2:] sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) _, res = get_address(('198.41.0.4', 53), name, sock) cache[(name, QTYPE)] = struct.pack("!H", id) + res[2:] return struct.pack("!H", id) + res[2:] return answer
def run_dns_server(configpath): # your code here #print(configpath) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((ip, port)) print("Listening on UDP {}:{}".format(*sock.getsockname())) while True: query_original, address_original = sock.recvfrom(buffer_size) query_original_in_shorts = unpack("!1H2B4H", query_original[0:12]) header_fields = parse_dns_header(query_original_in_shorts) fields = parse_dns_question(query_original[12:]) name = fields["domain_name"] exists = os.path.isfile('./zone_files/' + name + "conf") if (exists): zone = easyzone.zone_from_file(name, './zone_files/' + name + "conf") ips = zone.names[name].records('A').items #p = zone.names["www."].items info = {"ttl": zone.names[name].ttl, "ip": ips[0]} print("file is in the zone\n") resp = build_responce_A(query_original, info, name) sock.sendto(resp, address_original) else: print("start iterative search\n") iterative_query(query_original, sock, address_original, fields["domain_name"], header_fields["id"])
def read_zone_files(directory): zones = [] zone_files = listdir(directory) for zone_filename in zone_files: zone = easyzone.zone_from_file( zone_filename.split('conf')[0], directory + zone_filename) zones.append(zone) return zones
def makeResponse(data, config): #Transaction id tranID = bytes(data[0:2]) # Flags reqflags = data[2:4] responseFlags = getRespFlags(reqflags) # QDCOUNT one = 1 qdcount = one.to_bytes(2, 'big') # NSCOUNT AND ARCOUNT zero = 0 nscount = zero.to_bytes(2, 'big') arcount = zero.to_bytes(2, 'big') # Domain and Question type (domain, qtype) = getDomainAndQType(data) try: z = easyzone.zone_from_file(domain, config + 'example.com.conf') # finish dns header ancount = len(z.root.records(qtypeValue(qtype)).items).to_bytes( 2, 'big') header = tranID + responseFlags + qdcount + ancount + nscount + arcount # build question question = b'' question += getDomainbytes(domain) print(';; QUESTION SECTION:') print(domain + ' IN ' + qtypeValue(qtype)) #add qtype and class question += qtype question += one.to_bytes(2, 'big') #build body body = b'' print(';; ANSWER SECTION:') for item in z.root.records(qtypeValue(qtype)).items: body += b'\xc0\x0c' body += qtype body += one.to_bytes(2, 'big') ttl = 1800 body += (ttl).to_bytes(4, 'big') body += lengthAndData(item, qtypeValue(qtype), ttl, domain) return header + question + body except: pass return recSearchResult(data, rootDnsServers, rootDnsServers)[0]
def read_conf(): if os.path.isdir(path): for filename in os.listdir(path): full_path = path + "/" + filename if os.path.isfile(full_path): domain_name = filename[:filename.rfind(".")] zone = easyzone.zone_from_file(domain_name, full_path) local_zones.append(zone) else: print("Not directory") exit(1)
def getZoneFiles(CONFIG): zFiles = [] try: filenames = os.listdir(CONFIG) for zone in filenames: curZone = easyzone.zone_from_file( zone.split('.conf')[0], os.path.join(CONFIG, zone)) zFiles.append(curZone) # print(curZone.names['example.com.'].records('A').items) except Exception: print('Error reading zonefiles\n') return zFiles
def getLocalAnswers(questions, CONFIG): answers = [] unansweredQuestions = [] isAuthoritative = 0 ttl = 0 zoneFiles = [easyzone.zone_from_file('example.com', CONFIG + 'example.com.conf'), easyzone.zone_from_file('example2.com', CONFIG + 'example2.com.conf'), easyzone.zone_from_file('FreeUniCN19.com', CONFIG + 'FreeUniCN19.com.conf')] for question in questions: answerLen = len(answers) qName = question['domainName'] for zoneFile in zoneFiles: zoneDomainNames = zoneFile.get_names() if qName in zoneDomainNames: recordType = typeConstants[question['QTYPE']] if zoneDomainNames[qName].soa: isAuthoritative = 1 ttl = zoneDomainNames[qName].ttl answer = [record for record in zoneDomainNames[qName].records(recordType)] answers.append(answer) break if answerLen == len(answers): unansweredQuestions.append(question) return answers, isAuthoritative, ttl, unansweredQuestions
def __init__(self, path) : self.cache, self.zones = {}, list(map(lambda zone: easyzone.zone_from_file(zone.split('.conf')[0], path + zone), listdir(path))) # Iterate over every zone for zone in self.zones : # Extract its domains and possible values for domain, name_obj in zone.get_names().items() : # Check for every single record type for record_type in types.values() : record = name_obj.records(record_type) #If we have any record for given type, add it to the cache if record is not None : Cache.checkAndAdd(self, (domain, record_type), record.get_items())
def generate_query(requested_domain, requested_record, question_query, message): path = os.sys.argv[1] files = list() for filename in os.listdir(path): files.append(filename) print("Trying to find {} record on {}".format(requested_record, requested_domain)) try: zone = easyzone.zone_from_file(requested_domain, '{}/{}'.format(path, requested_domain + '.conf')) if requested_record == 'CNAME': requested_record = 'SOA' header = generate_header(len(zone.root.records(requested_record).items)) body = question_query + generate_body(requested_domain, requested_record, zone) print("Found {} record locally".format(requested_record)) except: header, body = find_recursively(requested_domain, message) return header, body
def main(): if len(sys.argv) != 3: usage() hostname, zonename = sys.argv[1].split('.', 1) zonefile = '/srv/ns/zones/%s.zone' % zonename z = easyzone.zone_from_file(zonename, zonefile) r = '%s.' % sys.argv[1] try: a = z.names[r].records('A') except KeyError: print 'error: %s record not found in %s' % (hostname, zonefile) exit(1) a.delete(a.items[0]) a.add(sys.argv[2]) z.save(autoserial=True) call('sudo /etc/init.d/nsd3 rebuild', shell=True) call('sudo /etc/init.d/nsd3 restart', shell=True)
# Python 'Module' object has no Attribute Error - Imported module from easyzone import easyzone z = easyzone.zone_from_file('example.com', '/var/namedb/example.com')
def setUp(self): zone_file = os.path.join(os.path.dirname(__file__), 'files', 'example.com') self.zone = zone_from_file('example.com', zone_file)
def check_domain(): data = request.json try: message = rsa.decrypt( binascii.a2b_base64(data['message'].encode('utf8')), pkey) payload = json.loads(message.decode('utf8')) except rsa.pkcs1.DecryptionError as e: response = app.response_class(status=400) return response except binascii.Error: response = app.response_class(status=400) return response except TypeError: response = app.response_class(status=400) return response else: print('im in') domain = payload['domain'] subdomains = payload['subdomains'] signature = binascii.a2b_base64(data['signature']) pubkey = rsa.PublicKey.load_pkcs1( open(WORKDIR + 'rsa/' + domain, 'r').read()) ip = request.remote_addr try: verify = rsa.verify(message, signature, pubkey) except rsa.pkcs1.VerificationError: response = app.response_class(status=400) return response else: if verify: print('in verify') zone = easyzone.zone_from_file(domain, ZONEDIR + domain + '.db') names = zone.get_names() zone_change = False for dom in subdomains: print(dom + domain + '.') print(names) if dom == '': subdom = domain + '.' else: subdom = dom + '.' + domain + '.' try: print(names[subdom]) this = names[subdom] except KeyError: pass else: if this.records('A').items[0] != ip: this.records('A').delete( this.records('A').items[0]) this.records('A').add(ip) zone_change = True if zone_change is True: zone.save() r = ZoneReload(rndc='/usr/sbin/rndc') r.reload(domain) print('Reload') response = app.response_class(status=200) print('pre return') return response
import os from easyzone import easyzone from Cookie import SimpleCookie form = cgi.FieldStorage() #form is Dnsmanager.py dnsname = form.getlist("dname") dnsname = str(dnsname) dnsname = dnsname.strip("[']") zoneNS = [] C = SimpleCookie() C["Current-domain-name"] = dnsname # Explicit variable name PLEASE!!!111oneoneone try: #Standard notation of open doesn't work for easyzone.zone_from_file zonename = "%s" % dnsname filename = "/var/cache/bind/%s" % dnsname f = easyzone.zone_from_file(zonename, filename) except : #Todo : Make a real error message and a real error handling print "content-type:text/html" print print '<html>' print '<head>' print '</head>' print '<body>' print "The dev was too lazy to narrow the error type so... error!" print "prout<br>" print dnsname + "test" print "file name is " print '</body>' print '</html>' #f is the file opened by zone_from_file... yeah yeah i know, very explicit variable name
def updateSoa(cbot_json): z = easyzone.zone_from_file(myDomain(cbot_json), myUnsignedRefFname(cbot_json, '.ref.soa')) print(z.root.soa.serial) z.save(autoserial=True)
def handle(self, filename, zonename, keyfile, checkzone, *args, **options): if not filename: print "Must supply valid filename" exit(-1) if not zonename: print "Must supply valid zonename" exit(-1) if zonename[-1] != '.': zonename += '.' # Check the zone c = ZoneCheck(checkzone=checkzone) if not c.isValid(zonename, filename): print "Invalid zone" exit(-1) z = easyzone.zone_from_file(zonename, filename) if len(DNSZone.objects.filter(zonename=zonename)) == 0: dnsz = DNSZone() dnsz.zonename = zonename dnsz.ttl = z.root.soa.minttl dnsz.rndckey = keyfile #fk email to a user? dnsz.email = '*****@*****.**' dnsz.serial = z.root.soa.serial dnsz.refresh = z.root.soa.refresh dnsz.retry = z.root.soa.retry dnsz.expire = z.root.soa.expire dnsz.minimum = z.root.soa.minttl dnsz.save() else: dnsz = DNSZone.objects.get(zonename=zonename) #We want to populate the A and AAAA records first, else we wont have integrity for the other records. for rtype in ('A', 'AAAA', 'MX', 'PTR', 'TXT', 'SRV', 'CNAME', 'NS', 'HINFO'): for r in z.names: try: for rec in z.names[r].records(rtype).items: #Check if the record exists or not if len(DNSRecord.objects.filter(type=rtype,record=rec,fqdn=r)) == 0: dr = DNSRecord() dr.zone = dnsz dr.type = rtype if rtype == 'MX': rec = '%s %s' % rec if rtype not in ('A', 'AAAA'): dr.record = rec dr.active= True dr.ttl = dnsz.ttl dr.fqdn = r if rtype in ('A', 'AAAA'): try: a = Address.objects.get(address=rec) except Address.DoesNotExist: a = Address() a.host = None a.type = 6 if rtype == 'A': a.type = 4 a.vlan = 0 a.hwid = None a.address = rec a.save() dr.address = a dr.save() print dr # TODO We should check if a DNAME to relate to a different zone .... ? if rtype in ('MX', 'CNAME', 'NS', 'PTR', 'TXT', 'SRV'): test = rec.split(' ')[-1] #We should also split the rec if possible - last field is our related name in SRV / MX related = DNSRecord.objects.filter(Q(fqdn=test) , Q(type='A') | Q(type='AAAA')) for x in related: dr.dnsrecord.add(x) dr.save() #Check if this object exists in our model (host, address and type) #If we find a host by this FQDN, tie the address to it. Else skip and add address / record. except ValueError as e: # #pass print 'EXCEPTION ON:' + r + ':' + rtype + ' ;;ValueError; ' + e.message except AttributeError as e: pass except TypeError as e: print 'EXCEPTION ON:' + r + ':' + rtype + ' ;;TypeError; ' + e.message print traceback.print_tb(sys.exc_info()[2] )
from easyzone import easyzone from os import listdir from os.path import isfile, join import time #Run other script to append static.* zones to the end of db.* zones mergedZonesPath = "./mergedzones/" allZones = [ f for f in listdir(mergedZonesPath) if isfile(join(mergedZonesPath, f)) ] #import each zone then update serial and rname for currentZoneFile in allZones: ez = easyzone.zone_from_file(currentZoneFile, mergedZonesPath + currentZoneFile) ez.root.soa.serial = time.strftime('%Y%m%d00') ez.root.soa.rname = currentZoneFile ez.save()
def parse_config_files(self, path, file_name): ind = file_name.find(".conf") domain = file_name[:ind] self.config_data[domain] = easyzone.zone_from_file( domain, path + file_name)
def fill_from_config_files(config_path: str, dns_retriever: DnsRetriever): for filename in os.listdir(config_path): domain_name = filename[:-4] dns_retriever.zone_files[domain_name] = easyzone.zone_from_file( domain_name, config_path + "/" + filename)
def run_dns_server(CONFIG, IP, PORT): sock = createSocket() sock.bind((IP, int(PORT))) idx = 0 CACHER = dict() ROOT = ['198.41.0.4', '199.7.91.13'] while True: data, address = sock.recvfrom(4096) print('starting up on {} port {}'.format(IP, PORT)) s = struct.unpack('! H 5h', data[:12]) ID, QR = s[0], s[1] QN, ANS = s[2], s[3] questions = data[12:] QName, questions, tot = readQName(data, questions) QType, questions = struct.unpack('!h', questions[:2])[0], questions[2:] QClass, questions = struct.unpack('!h', questions[:2])[0], questions[2:] print('QUESTION SECTION: {} Type:{} 128 IN {}'.format( QName, QType, IP)) key = (QName, QType) if key in CACHER: RESP = data[:2] + CACHER[key] sock.sendto(RESP, address) continue local = True RESPONSE, ALL_ANSWERS = b'', b'' try: ez = easyzone.zone_from_file(QName[:-1], CONFIG + QName + 'conf') except: local = False if QType == 1: #A if local: for ip in ez.root.records('A').items: RDATA = ipaddress.IPv4Address(ip).packed ANSWER, ANS = make_answer(QName, QType, QClass, 0, RDATA, ANS) ALL_ANSWERS += ANSWER else: RESPONSE = askRoot(data, ROOT[idx], createSocket()) CACHER[key] = RESPONSE[2:] sock.sendto(RESPONSE, address) continue elif QType == 2: #NS if local: for ns in ez.root.records('NS').items: RDATA = make_off_sets(ns) ANSWER, ANS = make_answer(QName, QType, QClass, 128, RDATA, ANS) ALL_ANSWERS += ANSWER else: RESPONSE = askRoot(data, ROOT[idx], createSocket()) CACHER[key] = RESPONSE[2:] sock.sendto(RESPONSE, address) continue elif QType == 5: #CName if local: for cn in ez.root.records('CNAME').items: RDATA = make_off_sets(cn) ANSWER, ANS = make_answer(QName, QType, QClass, 10, RDATA, ANS) ALL_ANSWERS += ANSWER else: RESPONSE = askRoot(data, ROOT[idx], createSocket()) CACHER[key] = RESPONSE[2:] sock.sendto(RESPONSE, address) continue elif QType == 6: #SOA if local: soa = ez.root.records('SOA').items[0].split(' ') RDATA = make_off_sets(soa[0]) RDATA += make_off_sets(soa[1]) RDATA += int(soa[2]).to_bytes(4, 'big') RDATA += int(soa[3]).to_bytes(4, 'big') RDATA += int(soa[4]).to_bytes(4, 'big') RDATA += int(soa[5]).to_bytes(4, 'big') RDATA += int(soa[6]).to_bytes(4, 'big') ANSWER, ANS = make_answer(QName, QType, QClass, 10, RDATA, ANS) ALL_ANSWERS += ANSWER else: RESPONSE = askRoot(data, ROOT[idx], createSocket()) CACHER[key] = RESPONSE[2:] sock.sendto(RESPONSE, address) continue elif QType == 15: #MX if local: for mx in ez.root.records('MX').items: RDATA = mx[0].to_bytes(2, 'big') RDATA += make_off_sets(mx[1]) ANSWER, ANS = make_answer(QName, QType, QClass, 10, RDATA, ANS) ALL_ANSWERS += ANSWER else: RESPONSE = askRoot(data, ROOT[idx], createSocket()) CACHER[key] = RESPONSE[2:] sock.sendto(RESPONSE, address) continue elif QType == 16: #TXT if local: txt = ez.root.records('TXT').items[0].encode() RDATA = len(txt).to_bytes(1, 'big') + txt ANSWER, ANS = make_answer(QName, QType, QClass, 10, RDATA, ANS) ALL_ANSWERS += ANSWER else: RESPONSE = askRoot(data, ROOT[idx], createSocket()) CACHER[key] = RESPONSE[2:] sock.sendto(RESPONSE, address) continue elif QType == 28: #AAAA if local: for ip in ez.root.records('AAAA').items: RDATA = ipaddress.IPv6Address(ip).packed ANSWER, ANS = make_answer(QName, QType, QClass, 10, RDATA, ANS) ALL_ANSWERS += ANSWER else: RESPONSE = askRoot(data, ROOT[idx], createSocket()) sock.sendto(RESPONSE, address) CACHER[key] = RESPONSE continue if local: QR = 33920 else: QR = 33792 RESPONSE += data[:2] RESPONSE += struct.pack('!H', QR) RESPONSE += struct.pack('!h', QN) RESPONSE += struct.pack('!h', ANS) RESPONSE += data[8:] RESPONSE = RESPONSE[:(16 + tot)] RESPONSE += ALL_ANSWERS if data: CACHER[key] = RESPONSE[2:] sent = sock.sendto(RESPONSE, address) print('sent {} bytes back to {}'.format(sent, address)) pass