示例#1
0
 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
示例#2
0
    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
示例#3
0
    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()
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
 def rr(self, rname):
     return RR(rname=DNSLabel(rname),
               rtype=QTYPE.A,
               rdata=dns.A(self._ip),
               ttl=300)
示例#7
0
 def set_ip(self, ip):
     if self._rtype == QTYPE.A:
         self.rr.rdata = dns.A(ip)