def dns_handler(s, peer, data): request = DNSRecord.parse(data) id = request.header.id qname = request.q.qname qtype = request.q.qtype reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q) if "secsquare.herokuapp.com" == qname: # if the query is for SecSquare server reply.add_answer(RR(qname,qtype, rdata=A(SECSQUARE_HOST_ADDRESS))) else: # if query is for any other host names label = str(qname) raw_data = urllib2.urlopen("https://secsquare.herokuapp.com/api.php?name="+label).read() data = json.loads(raw_data) results = data['results'] for entry in results: # put all results from SecSquare server into reply if 'MX' in entry['type']: reply.add_answer(RR(qname,qtype, rdata=MX(entry['target']))) elif 'AAAA' in entry['type']: reply.add_answer(RR(qname,qtype, rdata=AAAA(entry['ipv6']))) elif 'A' in entry['type']: reply.add_answer(RR(qname,qtype, rdata=A(entry['ip']))) print(reply) # print the DNS response for debugging purposes s.sendto(reply.pack(), peer)
def dns_handler(s, peer, data): request = DNSRecord.parse(data) id = request.header.id qname = request.q.qname qtype = request.q.qtype print "------ Request (%s): %r (%s)" % (str(peer), qname.label, QTYPE[qtype]) print request reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q) if qtype == QTYPE.A: reply.add_answer(RR(qname, qtype, rdata=A(IP))) if qtype == QTYPE.AAAA: reply.add_answer(RR(qname, qtype, rdata=AAAA(IPV6))) elif qtype == QTYPE['*']: reply.add_answer(RR(qname, QTYPE.A, rdata=A(IP))) reply.add_answer(RR(qname, QTYPE.MX, rdata=MX(IP))) reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG))) else: reply.add_answer(RR(qname, QTYPE.CNAME, rdata=CNAME(MSG))) print "------ Reply" print reply s.sendto(reply.pack(), peer)
def resolve(self, request, handler): reply = request.reply() value = self._resolve_request(request) if value and request.q.qtype == QTYPE.MX: reply.add_answer( RR(request.q.qname, QTYPE.MX, rdata=MX(label=value)), ) elif value and request.q.qtype == QTYPE.A: reply.add_answer(RR(request.q.qname, QTYPE.A, rdata=A(value)), ) elif value and request.q.qtype == QTYPE.TXT: reply.add_answer(RR( request.q.qname, QTYPE.TXT, rdata=TXT(value), )) elif value and request.q.qtype == QTYPE.PTR: reply.add_answer(RR( request.q.qname, QTYPE.PTR, rdata=PTR(value), )) reply.add_auth( RR(request.q.qname, QTYPE.SOA, ttl=60, rdata=SOA( "ns1.local.dev", "ns2.local.dev", (20140101, 3600, 3600, 3600, 3600), ))) reply.add_ar(RR("ns1.local.dev", ttl=60, rdata=A("127.0.0.1"))) return reply
def resolve(self, request, handler): reply = request.reply() # DNSLabel qname qname = request.q.qname if qname.matchSuffix("time.") or qname.matchSuffix("date."): utc_now = pytz.utc.localize(datetime.datetime.utcnow()) try: timezone = str(qname)[:-6].replace('.', '/') tz_now = utc_now.astimezone(pytz.timezone(timezone)) except pytz.UnknownTimeZoneError: reply.header.rcode = RCODE.REFUSED return reply if qname.matchSuffix("time."): reply.add_answer(RR(qname, QTYPE.A, ttl=0, rdata=A(tz_now.strftime("%H.%M.%S.0")))) elif qname.matchSuffix("date."): reply.add_answer(RR(qname, QTYPE.A, ttl=0, rdata=A(tz_now.strftime("%y.%m.%d.0")))) reply.add_answer(RR(qname, QTYPE.TXT, ttl=0, rdata=TXT(tz_now.strftime("%Y-%m-%d %H:%M:%S")))) reply.add_answer(RR(qname, QTYPE.AAAA, ttl=0, rdata=AAAA(tz_now.strftime("%Y:%m:%d::%H:%M:%S")))) elif qname.matchSuffix("md5."): md5 = hashlib.md5(str(qname.stripSuffix("md5."))[:-1]) hash = str(md5.hexdigest()) ipv6 = ':'.join([hash[i:i+4] for i in range(0, len(hash), 4)]) reply.add_answer(RR(qname, QTYPE.AAAA, ttl=0, rdata=AAAA(ipv6))) reply.add_answer(RR(qname, QTYPE.TXT, ttl=0, rdata=TXT(hash))) if RR() == reply.get_a(): reply.header.rcode = RCODE.NXDOMAIN return reply
def lookup(self, qtype, domain): if qtype != 'A': return tuple() if domain == 'ftp.se.debian.org.': return (A('10.32.12.1'), ) else: try: return (A(socket.gethostbyname(domain)), ) except: return tuple()
def dns_handler(s, peer, data): request = DNSRecord.parse(data) id = request.header.id qname = request.q.qname qtype = request.q.qtype print "------ Request (%s): %r (%s)" % (str(peer), qname.label, QTYPE[qtype]) print "\n".join([" %s" % l for l in str(request).split("\n")]) print ', '.join(str(x) for x in request.ar) def get_ecs_option(req): for record in request.ar: if type(record) is RR: for opt in record.rdata: if type(opt) is EDNSOption: if opt.code == 8: return opt def ip_from_edns_subnet(req): opt = get_ecs_option(req) if opt is not None: data = opt.data[4:].ljust(4, '\0') data = socket.inet_ntoa(data) subnetlen = str(ord(opt.data[2])) print "Got ECS:", data, subnetlen return [data, data + "/" + subnetlen] return ["99.99.99.99", "0/0"] [IP, MSG] = ip_from_edns_subnet(request) reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q) if qtype == QTYPE.A: reply.add_answer(RR(qname, qtype, rdata=A(IP))) elif qtype == QTYPE.AAAA: reply.add_answer(RR(qname, qtype, rdata=AAAA(IPV6))) elif qtype == QTYPE['*']: reply.add_answer(RR(qname, QTYPE.A, rdata=A(IP))) reply.add_answer(RR(qname, QTYPE.MX, rdata=MX(IP))) reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG))) else: reply.add_answer(RR(qname, QTYPE.CNAME, rdata=CNAME(MSG))) reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG))) print "------ Reply" print "\n".join([" %s" % l for l in str(reply).split("\n")]) s.sendto(reply.pack(), peer)
def resolve(self, request, handler): type_name = QTYPE[request.q.qtype] reply = request.reply() for record in self.records: if record.match(request.q): reply.add_answer(record.rr) if reply.rr: logger.info('found zone for %s[%s], %d replies', request.q.qname, type_name, len(reply.rr)) return reply # no direct zone so look for an SOA record for a higher level zone for record in self.records: if record.sub_match(request.q): reply.add_answer(record.rr) if reply.rr: logger.info('found higher level SOA resource for %s[%s]', request.q.qname, type_name) return reply logger.info('no local zone found, proxying %s[%s]', request.q.qname, type_name) proxy_resp = super().resolve(request, handler) if type_name == 'A': if (self.check_block(proxy_resp.rr)): rr = RR(proxy_resp.rr[0].get_rname(), request.q.qtype, ttl=60, rdata=A("127.0.0.1")) proxy_resp.rr = [rr] return proxy_resp return super().resolve(request, handler)
def resolve(self,request,handler): reply = request.reply() qtype = QTYPE[request.q.qtype] qname = request.q.qname # with 'exists:%{i}._ip.%{h}._domain.surfspf.net' in SPF-record of 'surf.nl' # mail from: '*****@*****.**' via 'outgoing2-ams.mf.surf.net' should result in a A-record query; # '145.0.1.5._ip.outgoing2-ams.mf.surf.net._helo.surf.nl._domain.surfspf.net.' if str(self.origin) in str(qname): if qtype == 'A': ip_version, ip_address = self.spfcheck(qname) if ip_version == -1: reply.header.rcode = RCODE.SERVFAIL elif ip_version == 4: reply.add_answer(RR(qname,QTYPE.A,ttl=self.ttl, rdata=A(ip_address))) elif ip_version == 6: reply.add_answer(RR(qname,QTYPE.AAAA,ttl=self.ttl, rdata=AAAA(ip_address))) else: reply.header.rcode = RCODE.NXDOMAIN else: reply.header.rcode = RCODE.NXDOMAIN else: reply.header.rcode = RCODE.REFUSED return reply
def resolve(self, request, handler): reply = request.reply() zone = self.zones.get(request.q.qname) if zone is not None: for zone_records in zone: rr = zone_records.try_rr(request.q) rr and reply.add_answer(rr) else: # no direct zone so look for an SOA record for a higher level zone found = False for zone_label, zone_records in self.zones.items(): if request.q.qname.matchSuffix(zone_label): try: soa_record = next(r for r in zone_records if r.is_soa) except StopIteration: continue else: reply.add_answer(soa_record.as_rr(zone_label)) found = True break if not found: reply.add_answer( RR(str(request.q.qname), QTYPE.A, rdata=A( socket.gethostbyname_ex(str( request.q.qname))[2][0]), ttl=60)) return reply
def resolve(self, request, handler): print("resolver:" + "-" * 40) reply = request.reply() qname = request.q.qname ia = ip_address(handler.client_address[0]) cmd = self.routes.get(qname) if cmd: output = getoutput(cmd).encode() reply.add_answer( RR(qname, QTYPE.TXT, ttl=self.ttl, rdata=TXT(output[:254]))) else: rqt = QTYPE.TXT rqd = TXT(f"{str(ia)}") if request.q.qtype in [QTYPE.A, QTYPE.AAAA, QTYPE.PTR]: QTR = {QTYPE.A: "A", QTYPE.AAAA: "AAAA", QTYPE.PTR: "PTR"} qt = QTR[request.q.qtype] if ia.version is 6 and request.q.qtype == QTYPE.AAAA: rqt = request.q.qtype rqd = AAAA(str(ia)) elif ia.version is 4 and request.q.qtype == QTYPE.A: rqt = request.q.qtype rqd = A(str(ia)) elif request.q.qtype == QTYPE.PTR: rqt = request.q.qtype rqd = PTR(str(ia.reverse_pointer)) else: rqt = QTYPE.TXT rqd = TXT( f"Your request for {qt} confuses me, but here is the IP as text {str(ia)}" ) reply.add_answer(RR(qname, rqt, ttl=self.ttl, rdata=rqd)) return reply
def query(self, peer, request): id = request.header.id qname = request.q.qname queryType = request.q.qtype reply = DNSRecord( DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q ) def cnameRecursion(dHost): global tmpRes # used for overwriting previous recursion value tmpData = dbTest(dHost) # First: get CNAME of desired host cnameAddress = [i[1] for i in tmpData if i[0] == 'CNAME'] tmpRes = (dHost,tmpData) if cnameAddress: newAddr = checkMacro(cnameAddress[0],dHost,peer) reply.add_answer(RR(dHost, QTYPE.CNAME, rdata=CNAME(newAddr))) # Second: get desired QTYPE from desired host printOut(peer,QTYPE.CNAME,str(dHost),newAddr) cnameRecursion(newAddr) return tmpRes qname,rData = cnameRecursion(qname) if queryType == QTYPE.TXT: # TXT rData = [i[1] for i in rData if i[0] == 'TXT'] # Add TXT Record printData = [] for tmprecord in rData: record = checkMacro(tmprecord,qname,peer) n = 255 if len(record) > 20: printData += [ record[:15]+'...(%d)' % len(record) ] else: printData = [record] if len(record) > n: record = [record[i:i+n] for i in range(0, len(record), n)] reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(record if isinstance(record,list) else [record,]))) printOut(peer,queryType,str(qname),printData) else: rData = [i[1] for i in rData if i[0] == qTypeDict[queryType]] resIP = '' if len(rData): resIP = rData elif '*' in db: #elif db.has_key('*'): #python2 only resIP = [i[1] for i in dbTest('*') if i[0] == 'A'] for tmpip in resIP: ip = checkMacro(tmpip,qname,peer) # Add A Record reply.add_answer(RR(qname, QTYPE.A, rdata=A(ip))) if resIP: printOut(peer,queryType,str(qname),', '.join(resIP)) else: printOut(peer,queryType,str(qname),'NONE') # Send To Client self.fire(write(peer, reply.pack()))
def _resolve(self, request, handler): qname = request.q.qname reply = request.reply() # TODO: # Resolve NS?, DS, SOA somehow if not qname.matchSuffix(self.domain): if self.recursor: try: return DNSRecord.parse(request.send(self.recursor, timeout=2)) except socket.error: pass except Exception as e: logger.exception('DNS request forwarding failed ({})'.format(e)) else: logger.debug('Bad domain: {} (suffix={})'.format(qname, self.domain)) reply.header.rcode = RCODE.NXDOMAIN return reply arecords = self.process(qname.stripSuffix(self.domain).idna()[:-1]) if arecords: for address in arecords: reply.add_answer(RR(qname, QTYPE.A, rdata=A(address), ttl=600)) else: reply.header.rcode = RCODE.NXDOMAIN return reply
def _A(self, name): if name.label[0] == "data": print base64.b64decode(name.label[1]), else: print name return RR(name, QTYPE.A, rdata=A(IP_ADDRESS), ttl=0)
def resolve(self,request,handler): global dns_data global dns_reply reply = request.reply() qname = request.q.qname qname_str = str(qname) enc_data = qname_str.split('.')[0] data = decode_payload(enc_data) if request.q.qtype == QTYPE.A : # The A version of the query # orig_response = gethostbyname() reply.add_answer(RR(qname,QTYPE.A,ttl=self.ttl, rdata=A('127.0.0.1'))) if request.q.qtype == QTYPE.AAAA : # The A version of the query if data : dns_data.put(data) try : data = dns_reply.get( False, 2 ) dns_reply.task_done() except Exception as e : print "Sending Random data < for '%s'" % qname_str data = urandom(16) aaaa_repl = socket.inet_ntop(socket.AF_INET6, data) reply.add_answer(RR(qname,QTYPE.AAAA,ttl=self.ttl, rdata=AAAA(aaaa_repl))) # print reply # print "Replying to query for '%s" % qname_str return reply
def respond(self, request): """Returns response containing self.ip.""" address = str(request.questions[0].qname) self.logger.log(self.parseloglevel(), "{b} - Responding to request for address:'{addr}'".format(b=str(self), addr=address)) response = request.reply() response.add_answer(RR(address, QTYPE.A, rdata=A(self.ip))) return response
def resolve(self, request, handler): qname = request.q.qname qtype = QTYPE[request.q.qtype] # Custom answer only for A (ipv4) or ANY requests if fnmatch.fnmatch(str(qname), self.match) and qtype in ('A', 'ANY'): reply = request.reply() ip = self.get_ip_from_dns(str(qname)) if len(ip) == 0: reply.header.rcode = getattr(RCODE, 'NXDOMAIN') else: reply.add_answer(RR(qname, QTYPE.A, rdata=A(ip), ttl=60)) return reply try: if handler.protocol == 'udp': proxy_r = request.send(self.address, self.port, timeout=self.timeout) else: proxy_r = request.send(self.address, self.port, tcp=True, timeout=self.timeout) reply = DNSRecord.parse(proxy_r) except socket.timeout: reply = request.reply() reply.header.rcode = getattr(RCODE, 'NXDOMAIN') return reply
def resolve_forward(self, qname, qtype, reply): """ Build a response to a forward DNS query (i.e. one that contains a hostname) :param dnslib.DNSRecord qname: The query's target. :param str qtype: The type of query (e.g. ``"SRV"``) :param dnslib.DNSRecord reply: The DNSRecord to populate with the reply. """ # Request isn't even in our domain if not qname.matchSuffix(self.domain): logging.warning("Rejecting query outside our domain: %s", qname) reply.header.rcode = RCODE.NOTAUTH return with self.lock: # Is the request for a service alias? for srv_domain, addrs in self.services.items(): if qname.matchSuffix(srv_domain): if not addrs: if (time.time() - self._startup > STARTUP_QUIET_PERIOD): logging.warning( "No instances found, returning " "SERVFAIL for %s", qname) # If there are no instances, we are unable to read from # ZK (or else the relevant service is down), so return # SERVFAIL reply.header.rcode = RCODE.SERVFAIL return for addr in addrs: reply.add_answer(RR(qname, QTYPE.A, rdata=A(addr))) return logging.warning("Unknown service: %s", qname) reply.header.rcode = RCODE.NXDOMAIN
def resolve(self, request, handler): qname = str(request.get_q().get_qname())[:-1] if qname.endswith(URL_SUFFIX) or qname.endswith( RET_SUFFIX ): # it's a DNS-encoded message (part) from our PAC script info = pac_dns_decode(qname) if info and 'data' in info and self.queue: # we have a complete message if info['tld'] == URL_SUFFIX: channel = 'url' elif info['tld'] == RET_SUFFIX: channel = 'eval' item = dict(type=channel, data=info['data'], pac_sid=info['pac_sid']) self.queue.put(item) reply = request.reply() reply.header.rcode = getattr(RCODE, 'NXDOMAIN') elif qname.startswith( 'oauthint' ): # oauthint.foo.com will resolve to IP of this server reply = request.reply() reply.add_answer(RR(qname, QTYPE.A, rdata=A(self.server_ip))) else: reply = super(PACDNSResolver, self).resolve(request, handler) return reply
def _a_page_encoder(self, data, encoder, nonce): data = encoder.encode(data, nonce, symmetric=encoder.kex_completed) length = struct.pack('B', len(data)) payload = length + data if len(payload) > 48: raise ValueError('Page size more than 45 bytes ({})'.format( len(payload))) response = [] for idx, part in enumerate( [payload[i:i + 3] for i in xrange(0, len(payload), 3)]): header = (random.randint(1, 6) << 29) idx = idx << 25 bits = (struct.unpack( '>I', '\x00' + part + chr(random.randrange(0, 255)) * (3 - len(part)))[0]) << 1 packed = struct.unpack( '!BBBB', struct.pack('>I', header | idx | bits | int(not bool(bits & 6)))) address = '.'.join(['{}'.format(int(x)) for x in packed]) response.append(RR('.', QTYPE.A, rdata=A(address), ttl=600)) return response
def craftPayload(self, msg): query = DNSRecord.parse(msg) response = query.reply() qname = query.q.qname vic_name = self.vic_name fakeip = self.fakeip if query.q.qtype == QTYPE.NS: print("[+] required NS record.") assert_ns = RR(qname, QTYPE.NS, ttl=60, rdata=NS("ns.%s" % qname)) response.add_answer(assert_ns) elif query.q.qtype == QTYPE.A: print("[+] required any A record.") cnamerr = RR(qname, QTYPE.CNAME, ttl=60, rdata=CNAME(vic_name)) fakea = RR(vic_name, QTYPE.A, ttl=86400, rdata=A(fakeip)) response.add_answer(cnamerr) response.add_answer(fakea) if response.__class__.__name__ == "DNSRecord": print("[!] Debug: print reply data") print("===============================") print(response) print("===============================") return response.pack() else: return None
def resolve(self, request, handler): reply = request.reply() qname = request.q.qname if any([qname.matchGlob(pattern) for pattern in self.bypass]): pass elif qname.matchGlob(self.zone): key = ( self.keymaker(request, handler, self.storage) if self.keymaker else str(qname) ) storage_result = self.storage.get(key) address = ( self.processor(storage_result) if self.processor else storage_result ) if address is not None: reply.add_answer( RR(qname, QTYPE.A, rdata=A(address), ttl=self.ttl) ) if self.upstream and not reply.rr: try: if handler.protocol == 'udp': proxy_r = request.send( self.upstream, port=53, timeout=60 ) else: proxy_r = request.send( self.upstream, port=53, tcp=True, timeout=60 ) reply = DNSRecord.parse(proxy_r) except socket.timeout: reply.header.rcode = getattr(RCODE, 'NXDOMAIN') return reply
def resolve(self, request, handler): assert isinstance(request, DNSRecord) reply = request.reply() qname = request.q.qname D = self.D if request.q.qtype == QTYPE.NS and qname.matchSuffix(D): reply.add_answer( RR(rname=qname, rtype=QTYPE.NS, ttl=NS_TTL, rdata=NS(D.add('ns')))) reply.add_ar( RR(D.add('ns'), QTYPE.A, ttl=self.ttl, rdata=A(self.ip))) # valid queries: data.data...data.9kw_api_key.operation.rest of domain elif request.q.qtype == QTYPE.CNAME\ and len(qname.label) >= (len(D.label) + 2)\ and qname.label[-(len(D.label) + 1)] in self.OPERATIONS\ and qname.label[-(len(D.label) + 2)] in self.allowed_keys: operation = qname.label[-(len(D.label) + 1)] api_key = qname.label[-(len(D.label) + 2)] data = qname.label[:-(len(D.label) + 2)] ret = self.OPERATIONS[operation](api_key, data) reply.add_answer(RR(qname, QTYPE.CNAME, ttl=0, rdata=CNAME(ret))) return reply
def dns_response(self, data): request = DNSRecord.parse(data) logger.debug('%s', request) reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q) qname = request.q.qname qn = str(qname) if qn.endswith('.'): qn = qn[:-1] qtype = request.q.qtype qt = QTYPE[qtype] qnhost, qndomain = qn.split('.', 1) # # OK, so we are not conformant to the standards at all, as we never # return any SOA records and stuff... # if qndomain == settings.IPAUTH_DNSSERVER_DOMAIN: if qt in ['*', 'A']: for u in User.objects.filter(iptouser__isnull=False): if qnhost == username_to_hostname(u.username): for itu in u.iptouser_set.all(): reply.add_answer( RR( rname=qname, rtype=QTYPE.A, rclass=1, ttl=self.server.command.options['ttl'], rdata=A(itu.ip_addr), )) elif qn.endswith('.in-addr.arpa'): if qt in ['*', 'PTR']: qn = qn[:-len('.in-addr.arpa')] parts = qn.split('.') if len(parts) == 4: ip = '.'.join(reversed(parts)) try: iptu = IpToUser.objects.get(ip_addr=ip) fqdn = (username_to_hostname(iptu.user.username) + '.' + settings.IPAUTH_DNSSERVER_DOMAIN + '.') reply.add_answer( RR( rname=qname, rtype=QTYPE.PTR, rclass=1, ttl=self.server.command.options['ttl'], rdata=PTR(fqdn), )) except IpToUser.DoesNotExist: pass logger.debug('%s', reply) return reply.pack()
def generate_response(self, ip, query, q_id): if type(ip) == str: record = DNSRecord( DNSHeader(id=q_id, qr=1, aa=1, ra=1), q=DNSQuestion(query), a=RR(query, rdata=A(ip)), ) return record else: record = DNSRecord( DNSHeader(id=q_id, qr=1, aa=1, ra=1), q=DNSQuestion(query), a=RR(query, rdata=A(ip[0].address)), ) for ip_obj in ip[1:]: record.add_answer(RR(query, QTYPE.A, rdata=A(ip_obj.address))) return record
def test_hosts(client, watcher): client.fire(query("localhost")) assert watcher.wait("reply", "client") assert (set(map(attrgetter("rclass", "rtype", "rdata.data"), client.a.rr)) == set([ (CLASS.IN, QTYPE.A, A("127.0.0.1").data), (CLASS.IN, QTYPE.AAAA, AAAA("::1").data) ]))
def _validate_ips(self, ips): if not isinstance(ips, list): self._fail('Missing an "ips" array') for ip in ips: try: ip = A(ip) except Exception as e: self._fail('Address parsing failed %s' % e)
def resolve(self, request, handler): reply = request.reply() qname = request.q.qname reply.add_answer(RR(qname, QTYPE.A, ttl=60, rdata=A(self.ip))) if "_acme-challenge" in str(qname).lower(): for x in TXTRECORDS: reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(x.strip()))) return reply
def handle(self): public_ip = self.server.public_ip data = self.request[0].strip() socket = self.request[1] try: d = DNSRecord.parse(data) except DNSError: log_dns("Error Bytes: %s" % (repr(data))) return try: query_label = b".".join(d.q.qname.label).decode("utf-8") except UnicodeDecodeError as err: log_dns("UnicodeDecodeError on DNS query") query_label = "" if d.header.get_opcode() != 0: log_dns("Ignoring packet because opcode %d is not supported." % (d.header.get_opcode())) elif not query_label.endswith(self.server.rebind_domain): log_dns("Mismatched domain ignored (label: %s)" % (query_label)) else: log_dns("Query %s" % (query_label)) answer = d.reply() subdomain_path = "data/domains/%s" % (query_label.split(".")[0]) target_ip_file = "%s/target.ip" % (subdomain_path) query_tag = "%s/queried" % (subdomain_path) if not exists(subdomain_path) or not exists(target_ip_file): answer.add_answer( RR(query_label, QTYPE.A, rdata=A(public_ip), ttl=1)) log_dns("Responding with public IP (domain: %s)" % (query_label)) elif exists(query_tag) and getmtime(query_tag) + 15 <= time(): ip = open(target_ip_file, "r").read() log_dns("Responding with target_ip '%s' (domain: %s)" % (ip, query_label)) answer.add_answer(RR(query_label, QTYPE.A, rdata=A(ip), ttl=1)) else: if not exists(query_tag): open(query_tag, "w").write("") log_dns("Responding with Dolos public IP '%s' (domain: %s)" % (public_ip, query_label)) answer.add_answer( RR(query_label, QTYPE.A, rdata=A(public_ip), ttl=1)) socket.sendto(answer.pack(), self.client_address)
def _replay_dns_none(self, addr: (str, int), dns_query: DNSRecord, localhost_socket: socket.socket): dns_reply = dns_query.reply() for host_query in dns_query.questions: self._logger.info('Blacklist DNS request - {}'.format( str(host_query.qname))) dns_reply.add_answer( RR(str(host_query.qname), QTYPE.A, rdata=A("0.0.0.0"), ttl=60)) localhost_socket.sendto(dns_reply.pack(), addr)
def resolve(self, request, handler): reply = request.reply() q = request.q if q.qtype == QTYPE.A: addr = self.network.nodes[self.nodename].resolve(q.qname) if addr is not None: rr = RR(q.qname, QTYPE.A, rdata=A(addr)) reply.add_answer(rr) return reply