def resolve(self, request, handler): if request.q.qtype != QTYPE.A: # Only IPv4 is supported reply = request.reply() reply.header.rcode = getattr(RCODE, 'NXDOMAIN') return reply hostname = str(request.q.qname) if hostname.endswith(".local."): reply = request.reply() address = address = self._mdns_resolver.resolve(hostname) if address: rr = RR(rname=request.q.qname, rtype=request.q.qtype, rdata=dns.A(address), ttl=300) reply.add_answer(rr) else: reply.header.rcode = getattr(RCODE, 'NXDOMAIN') return reply else: 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(self, request, handler): reply = request.reply() qname = request.q.qname # ! qtype = QTYPE[request.q.qtype] # Try to resolve locally unless on skip list if not any([qname.matchGlob(s) for s in self.skip]): for name, rtype, rr in self.zone: if qname.matchGlob(name) and (qtype in (rtype, 'ANY', 'CNAME')): a = copy.copy(rr) a.rname = qname reply.add_answer(a) # Check for NXDOMAIN if any([qname.matchGlob(s) for s in self.nxdomain]): reply.header.rcode = getattr(RCODE, 'NXDOMAIN') return reply # Otherwise proxy if not reply.rr: 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.header.rcode = getattr(RCODE, 'NXDOMAIN') for addr, ip in self.overwrite.items(): if qname.matchGlob(addr): a = copy.copy(reply.get_a()) a.rdata = dns.A(ip) new_reply = DNSRecord(reply.header, reply.questions, [a], reply.q, None, reply.auth, None) reply = new_reply # Name: facebook.com # Address: 31.13.81.36 # Name: facebook.com # Address: 2a03:2880:f116:83:face:b00c:0:25de return reply
def handle_ipv4(self, domain: str, record): record.add_question(dns.DNSQuestion(domain, qtype=1)) ip = dnsmanager.SecureDNS.get_ip_from_cache(domain) if ip is None: ip = self.dns_servers[self.dns_to_use].resolveIPV4(domain) # try again if ip is None: self.change_server() ip = self.dns_servers[self.dns_to_use].resolveIPV4(domain) # many servers if ip is not None and len(ip) > 0: for ans in ip: a = dns.A(ans) record.add_answer(RR(domain, QTYPE.A, ttl=360, rdata=a)) # if ip is None: dnsmanager.SecureDNS.add_url_to_cache(domain, "0.0.0.0") print("@@@@@@ Failed ipv4 query for " + domain) self.change_server()
def resolve(self, request, handler): global TXT_RECORDS reply = request.reply() name = request.q.qname logger.info("query %s", request.q.qname) # handle the main domain if (name == confs.BASE_DOMAIN or name == '_acme-challenge.' + confs.BASE_DOMAIN): r = RR(rname=request.q.qname, rdata=dns.A(confs.LOCAL_IPV4), rtype=QTYPE.A, ttl=60 * 60) reply.add_answer(r) if self.SOA: r = RR(rname=request.q.qname, rdata=self.SOA, rtype=QTYPE.SOA, ttl=60 * 60) reply.add_answer(r) if len(self.NS): for i in self.NS: r = RR(rname=request.q.qname, rdata=i, rtype=QTYPE.NS, ttl=60 * 60) reply.add_answer(r) if confs.LOCAL_IPV6: r = RR(rname=request.q.qname, rdata=dns.AAAA(confs.LOCAL_IPV6), rtype=QTYPE.AAAA, ttl=60 * 60) reply.add_answer(r) if len(TXT_RECORDS): r = RR(rname=request.q.qname, rdata=dns.TXT([ '{1}'.format(k, v) for k, v in TXT_RECORDS.items() ]), rtype=QTYPE.TXT) reply.add_answer(r) return reply # handle subdomains elif name.matchSuffix(confs.BASE_DOMAIN): # fnmatch labelstr = str(request.q.qname) logger.info("requestx: %s, %s", labelstr, confs.ONLY_PRIVATE_IPS) subdomains = labelstr.split('.') if len(subdomains) == 4: # TODO: dynamic ip = None try: ip = ipaddress.ip_address(subdomains[0].replace('-', '.')) except: pass try: if ip == None: ip = ipaddress.ip_address(subdomains[0].replace( '-', ':')) except: logger.info('invalid ip %s', labelstr) return reply # check if we only want private ips if not ip.is_private and confs.ONLY_PRIVATE_IPS: return reply if ip.is_reserved and confs.NO_RESERVED_IPS: return reply # check if it's a valid ip for a machine if ip.is_multicast or ip.is_unspecified: return reply if type(ip) == ipaddress.IPv4Address: ipv4 = subdomains[0].replace('-', '.') logger.info("ip is ipv4 %s", ipv4) r = RR(rname=request.q.qname, rdata=dns.A(ipv4), rtype=QTYPE.A, ttl=24 * 60 * 60) reply.add_answer(r) elif type(ip) == ipaddress.IPv6Address: ipv6 = subdomains[0].replace('-', ':') logger.info("ip is ipv6 %s", ipv6) r = RR(rname=request.q.qname, rdata=dns.AAAA(ipv6), rtype=QTYPE.AAAA, ttl=24 * 60 * 60) reply.add_answer(r) else: return reply logger.info('found zone for %s, %d replies', request.q.qname, len(reply.rr)) return reply elif self.address == "": return reply return super().resolve(request, handler)
def resolve(self, request, handler): global TXT_RECORDS reply = request.reply() name = request.q.qname logger.info("query %s", request.q.qname) # handle the main domain if (name == confs.BASE_DOMAIN or name == '_acme-challenge.' + confs.BASE_DOMAIN): r = RR(rname=request.q.qname, rdata=dns.A(confs.LOCAL_IPV4), rtype=QTYPE.A, ttl=60 * 60) reply.add_answer(r) if self.SOA: r = RR(rname=request.q.qname, rdata=self.SOA, rtype=QTYPE.SOA, ttl=60 * 60) reply.add_answer(r) if len(self.NS): for i in self.NS: r = RR(rname=request.q.qname, rdata=i, rtype=QTYPE.NS, ttl=60 * 60) reply.add_answer(r) if confs.LOCAL_IPV6: r = RR(rname=request.q.qname, rdata=dns.AAAA(confs.LOCAL_IPV6), rtype=QTYPE.AAAA, ttl=60 * 60) reply.add_answer(r) if len(TXT_RECORDS): r = RR(rname=request.q.qname, rdata=dns.TXT([ '{1}'.format(k, v) for k, v in TXT_RECORDS.items() ]), rtype=QTYPE.TXT) reply.add_answer(r) return reply # handle subdomains elif name.matchSuffix(confs.BASE_DOMAIN): # fnmatch labelstr = str(request.q.qname) logger.info("request: %s", labelstr) mv4 = re.match( '^([0-9]{1,3}-[0-9]{1,3}-[0-9]{1,3}-[0-9]{1,3})\.' + confs.BASE_DOMAIN + '\.$', labelstr) if mv4: ipv4 = mv4.group(1).replace('-', '.') # check if valid ip ipv4parts = [int(x) for x in ipv4.split('.')] if ((ipv4parts[0] == 192 and ipv4parts[1] == 168 and ipv4parts[2] == 0 and ipv4parts[3] <= 255) or (ipv4parts[0] == 172 and 0 <= ipv4parts[1] <= 31 and ipv4parts[2] <= 255 and ipv4parts[3] <= 255) or (ipv4parts[0] == 10 and 0 <= ipv4parts[1] <= 255 and ipv4parts[2] <= 255 and ipv4parts[3] <= 255)): logger.info("ip is %s", ipv4) r = RR(rname=request.q.qname, rdata=dns.A(ipv4), rtype=QTYPE.A, ttl=24 * 60 * 60) reply.add_answer(r) else: logger.info('invalid ipv4 %s', labelstr) else: mv6 = re.match( '^(fe80-[0-9a-f\-]{0,41})\.' + confs.BASE_DOMAIN + '\.$', labelstr) if mv6: ipv6 = mv6.group(1).replace('-', ':') try: ipaddress.ip_address(ipv6) # validate IP r = RR(rname=request.q.qname, rdata=dns.AAAA(ipv6), rtype=QTYPE.AAAA, ttl=24 * 60 * 60) reply.add_answer(r) except: # invalid ip logger.info('invalid ipv6 %s', labelstr) pass logger.info('found zone for %s, %d replies', request.q.qname, len(reply.rr)) return reply return super().resolve(request, handler)
def rr(self, rname): return RR(rname=DNSLabel(rname), rtype=QTYPE.A, rdata=dns.A(self._ip), ttl=300)
def set_ip(self, ip): if self._rtype == QTYPE.A: self.rr.rdata = dns.A(ip)