Exemplo n.º 1
0
 def validate(cls, v):
     try:
         RR.fromZone(v)
     except Exception as e:
         msg = str(e)
         raise ValueError(f"could not cast record: {msg}")
     return v
Exemplo n.º 2
0
    def resolve(self, request, handler):
        type_name = QTYPE[request.q.qtype]
        reply = request.reply()

        try:
            response = socket.gethostbyname_ex(str(request.q.qname))

            print(reply.header.rcode)

            if len(response[2]) > 0:
                for answer in response[2]:
                    if ipaddress.ip_address(answer).version == 4:
                        reply.add_answer(*RR.fromZone(
                            str(request.q.qname) + " 60 A " + answer))

                    else:
                        reply.add_answer(*RR.fromZone(
                            str(request.q.qname) + " 60 AAAA " + answer))

                return reply

        except:  # covers socket.gaierror and OSError
            reply.add_answer(
                *RR.fromZone(str(request.q.qname) + " 60 A " + fallback_ipv4))
            reply.add_answer(*RR.fromZone(
                str(request.q.qname) + " 60 AAAA " + fallback_ipv6))
            return reply
Exemplo n.º 3
0
    def from_zone(cls, zone):
        records = []
        logger.info(
            f"[email protected] - Loading zone: {zone.domain}/{zone.ip} ({zone.id})"
        )
        dns_records = zone.dns_records or []
        # if the zone has no records, create some default ones
        if not dns_records:
            logger.warning(
                f"[email protected] - Zone has no dns_records. loading defaults: {zone.domain}/{zone.ip} ({zone.id})"
            )
            rrs = RR.fromZone(
                ZONE_TEMPLATE.format(domain_name=zone.domain, domain_ip=zone.ip)
            )
            zone_records = [Record.make(zone, rr) for rr in rrs]
            for zr in zone_records:
                # TODO: make this clean on output
                rrstr = str(dedent(str(zr.rr)))
                logger.debug(f"[email protected] - Loading record entry: {rrstr}")
                logger.debug(
                    "[email protected] - Loaded record details - name: {} | rtype: {} | rr: {}".format(
                        str(zr.rr.rname), str(QTYPE[zr.rr.rtype]), str(zr.rr)
                    )
                )
        else:
            # loop over each dns_record of the zone and convert it to RR record
            dns_records = sorted(dns_records, key=lambda x: x.sort)
            zone_records = []
            for dns_record in dns_records:
                try:
                    rrs = RR.fromZone(dns_record.record)
                    _zone_records = [Record.make(zone, rr) for rr in rrs]
                    for zr in _zone_records:
                        rrstr = str(dedent(str(zr.rr)))
                        logger.debug(
                            f"[email protected] - Loading record: {str(dns_record.record)}"
                        )
                        logger.debug(
                            f"[email protected] - Loading record entry: {rrstr}"
                        )
                        logger.debug(
                            "[email protected] - Loaded record details - name: {} | rtype: {} | rr: {}".format(
                                str(zr.rr.rname), str(QTYPE[zr.rr.rtype]), str(zr.rr)
                            )
                        )
                    zone_records = zone_records + _zone_records
                except Exception as e:
                    logger.critical(
                        f'[email protected] - Error processing line ({e.__class__.__name__}: {e}) "{dns_record.id}:{dns_record.record}" '
                    )
                    raise e

        # add the records for the zone to the rest of the records
        records = records + zone_records
        return cls(records)
Exemplo n.º 4
0
 def resolve(self, request, handler):
     reply = request.reply()
     qname = str(request.q.qname)
     if qname[:len(ACME_PREFIX)] == ACME_PREFIX:  # ACME dns-01 verification
         reply.add_answer(
             *RR.fromZone(qname + " 300 IN TXT " +
                          str(shared_dict['key_authorization'])))
     else:
         reply.add_answer(*RR.fromZone(qname + " 300 A " + str(IP_ADDRESS)))
     reply.header.rcode = 0
     #print("reply:\n" + str(reply))
     return reply
Exemplo n.º 5
0
 def __init__(self,address,port,ttl,intercept,skip,nxdomain,forward,all_qtypes,timeout=0):
     """
         address/port    - upstream server
         ttl             - default ttl for intercept records
         intercept       - list of wildcard RRs to respond to (zone format)
         skip            - list of wildcard labels to skip
         nxdomain        - list of wildcard labels to return NXDOMAIN
         forward         - list of wildcard labels to forward
         all_qtypes      - intercept all qtypes if qname matches.
         timeout         - timeout for upstream server(s)
     """
     self.address = address
     self.port = port
     self.ttl = parse_time(ttl)
     self.skip = skip
     self.nxdomain = nxdomain
     self.forward = []
     for i in forward:
         qname, _, upstream = i.partition(':')
         upstream_ip, _, upstream_port = upstream.partition(':')
         self.forward.append((qname, upstream_ip, int(upstream_port or '53')))
     self.all_qtypes = all_qtypes
     self.timeout = timeout
     self.zone = []
     for i in intercept:
         if i == '-':
             i = sys.stdin.read()
         for rr in RR.fromZone(i,ttl=self.ttl):
             self.zone.append((rr.rname,QTYPE[rr.rtype],rr))
Exemplo n.º 6
0
    def resolve(self, request, handler):
        reply = request.reply(
        )  # the object that this function will return in the end, with modifications
        qname = request.q.qname  # the domain that was looked up

        burrow_log("Request for " + str(DNSLabel(qname.label[-5:])), 0)

        # First, we make sure the domain ends in burrow.tech.
        # If not, we return an NXDOMAIN result.
        if not qname.matchSuffix("burrow.tech"):
            reply.header.rcode = RCODE.NXDOMAIN
            return reply

        # Next, we try to look up the domain in our list of fixed test records.
        found_fixed_rr = False
        for rr in self.fixedrrs:
            a = copy.copy(rr)
            if (a.rname == qname):
                found_fixed_rr = True
                LOG("Found a fixed record for " + str(a.rname))
                reply.add_answer(a)
        if found_fixed_rr:
            return reply

        # Alright, if we've gotten here it must be a Transmission API message!
        assert (not found_fixed_rr)
        response_dict = self.handle_transmission_api_message(qname)
        zone = generate_TXT_zone(str(qname), dict_to_attributes(response_dict))
        rrs = RR.fromZone(zone)
        for rr in rrs:
            reply.add_answer(rr)
        return reply
Exemplo n.º 7
0
 def __init__(self,
              address,
              port,
              ttl,
              intercept,
              skip,
              nxdomain,
              timeout=0):
     """
         address/port    - upstream server
         ttl             - default ttl for intercept records
         intercept       - list of wildcard RRs to respond to (zone format)
         skip            - list of wildcard labels to skip 
         nxdomain        - list of wildcard labels to retudn NXDOMAIN
         timeout         - timeout for upstream server
     """
     self.address = address
     self.port = port
     self.ttl = parse_time(ttl)
     self.skip = skip
     self.nxdomain = nxdomain
     self.timeout = timeout
     self.zone = []
     for i in intercept:
         if i == '-':
             i = sys.stdin.read()
         for rr in RR.fromZone(i, ttl=self.ttl):
             self.zone.append((rr.rname, QTYPE[rr.rtype], rr))
Exemplo n.º 8
0
 def resolve(self, request, handler):
     reply = request.reply()
     qname = request.q.qname
     cc_record = "in." + domain + "."
     qstr = str(qname)
     if cc_record in qstr:
         try:
             command_txt = q_commands.get(block=False, timeout=None)
         except queue.Empty:
             command_txt = ""
         reply.add_answer(*RR.fromZone(
             "{} 0 IN TXT \"{}\"".format(qname, base58.b58encode(command_txt.encode("utf-8")).decode("ascii"))))
     elif request.q.qtype == 1 and ("out." + domain + ".") in qstr:
         self.__parse_out(qstr)
         reply.add_answer(*RR.fromZone("{} 0 IN A {}".format(qname, "127.255.255.255")))
     return reply
Exemplo n.º 9
0
    def resolve(self,request,handler):
        reply = request.reply()  # the object that this function will return in the end, with modifications
        qname = request.q.qname  # the domain that was looked up

        burrow_log("Request for " + str(DNSLabel(qname.label[-5:])), 0)

        # First, we make sure the domain ends in burrow.tech.
        # If not, we return an NXDOMAIN result.
        if not qname.matchSuffix("burrow.tech"):
            reply.header.rcode = RCODE.NXDOMAIN
            return reply
       
        # Next, we try to look up the domain in our list of fixed test records.
        found_fixed_rr = False
        for rr in self.fixedrrs:
            a = copy.copy(rr)
            if (a.rname == qname):
                found_fixed_rr = True
                LOG("Found a fixed record for " + str(a.rname))
                reply.add_answer(a)
        if found_fixed_rr:
            return reply

        # Alright, if we've gotten here it must be a Transmission API message!
        assert(not found_fixed_rr)
        response_dict = self.handle_transmission_api_message(qname)
        zone = generate_TXT_zone(str(qname), dict_to_attributes(response_dict))
        rrs = RR.fromZone(zone)
        for rr in rrs:
            reply.add_answer(rr)
        return reply
Exemplo n.º 10
0
 def __init__(self):
     fixed_zone = open("fixed_zone/primary.txt").read() + open("fixed_zone/tests.txt").read()
     self.fixedrrs = RR.fromZone(fixed_zone)
     self.active_transmissions = {}  # Dictionary of Transmission objects.
                                     # Their ID's are the keys, for easy/quick lookup.
     self.cache = ExpiringDict(max_len=100000, max_age_seconds=70)
     self.transmission_handler_lock = multiprocessing.Lock()
Exemplo n.º 11
0
    def resolve_mdns(self, request, handler, rewrite=None):

        sock = get_mdns_socket()
        d = DNSRecord(DNSHeader(id=0, bitmap=0), q=request.q)
        sock.sendto(d.pack(), (nameserver4, 5353))
        # sock.sendto(d.pack(), (nameserver6, 5353))
        qname = request.q.qname
        if rewrite:
            request.q.qname = rewrite
        reply = request.reply()

        while True:
            buf, remote = sock.recvfrom(8192)
            d = DNSRecord.parse(buf)
            success = False
            if (d.header.aa == 1) and (d.header.a > 0):
                for response in d.rr:
                    if str(response.rname) == qname:
                        success = True
                        response.rclass = CLASS.IN

                        # These two lines can be deleted if we dont want the original response
                        reply.add_answer(response)
                        response = RR.fromZone(response.toZone())[0]

                        if rewrite:
                            response.rname = rewrite
                            reply.add_answer(response)
                        # print(reply)
            if success:
                break
        return reply
Exemplo n.º 12
0
 def __init__(self,zone=False):
     # add zone if supplied
     self.zone = []
     if zone:
         for rr in RR.fromZone(zone):
             if not self.exist(rr):
                 self.add_record(rr) 
Exemplo n.º 13
0
    def resolve(self, request, handler):
        reply = request.reply()

        if request.q.qtype != QTYPE.A:
            log.error("Unsupported query qtype: `{}`".format(request.q.qtype))
            reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
            return reply

        query = str(request.q.qname)
        if query not in self._records:
            log.error("qname `{}` not present in DB".format(query))
            reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
            return reply

        log.info(
            "DNS query for `{}`, type `{}`, reply `{}`, ttl `{}`".format(
                query,
                request.q.qtype,
                self._records[query]['ip'],
                self._records[query]['ttl'])
        )

        reply.add_answer(
            *RR.fromZone("{} {} A {}".format(
                query,
                self._records[query]['ttl'],
                self._records[query]['ip'],
                )
            )
        )

        return reply
Exemplo n.º 14
0
    def resolve(self, request, handler):
        qname = request.q.qname
        qtype = QTYPE[request.q.qtype]

        qname = str(qname).split('.')
        if qname[-1] == '':
            qname.pop(-1)
        if qname[-1] == 'novalocal' and qtype in ['A', 'AAAA', 'MX']:
            reply = request.reply()
            servername = qname[-2]
            if len(qname) == 2:
                query = 'fixed'
            elif len(qname) == 3:
                query = qname[0]
            else:
                return reply
            if query not in ['fixed', 'floating']:
                return reply

            print(qname)
            for server in CachedNovaLookup.get_list():
                if server.name == servername:
                    for interface in server.addresses.values():
                        for ip in interface:
                            if ip['OS-EXT-IPS:type'] == query and qtype == 'A':
                                ans = RR.fromZone('{} 60 IN A {}'.format(
                                    request.q.qname, ip['addr']))[0]
                                print(ans)
                                ans.rname = request.q.qname
                                reply.add_answer(ans)

            return reply
        else:
            return super(NovaResolver, self).resolve(request, handler)
Exemplo n.º 15
0
def DNSGuard(ip, port, blacklist):
    octetsize = 512
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((ip, port))
    data = None
    addr = None
    R = resolver.Resolver()
    logging.debug("DNSGuard SERVER ACTIVE ON {}:{}".format(ip, port))
    while True:
        data, addr = sock.recvfrom(octetsize)
        packet = DNSRecord.parse(data)
        question = packet.get_q()
        fqdn = FQDN(question)
        logging.debug("Query: {}".format(str(packet)))
        if allowed(fqdn, blacklist):
            try:
                zones = R.resolveZone([fqdn])
                logging.debug("Allowed: {}".format(zones))
                reply = packet.reply()
                for zone in zones:
                    reply.add_answer(*RR.fromZone(zone))
                    sock.sendto(DNSRecord.pack(reply), addr)
            except Exception as e:
                logging.error("Error: {}".format(e))
            pass
    pass
Exemplo n.º 16
0
 def manufactory_DNS(self):
     response_packet = DNSRecord()
     response_packet.header.id = self.query_id
     response_packet.add_question(DNSQuestion(self.qname, self.qtype))
     related_rr = filter(lambda rr: self.qname in rr, intercept_rr)
     for answer in related_rr:
         response_packet.add_answer(*RR.fromZone(answer))
     self.response_packet = response_packet.pack().__str__()
Exemplo n.º 17
0
 def __init__(self):
     fixed_zone = open("fixed_zone/primary.txt").read() + open(
         "fixed_zone/tests.txt").read()
     self.fixedrrs = RR.fromZone(fixed_zone)
     self.active_transmissions = {}  # Dictionary of Transmission objects.
     # Their ID's are the keys, for easy/quick lookup.
     self.cache = ExpiringDict(max_len=100000, max_age_seconds=70)
     self.transmission_handler_lock = multiprocessing.Lock()
Exemplo n.º 18
0
    def resolve(self,request,handler):
        reply = request.reply()
        qname = request.q.qname
        qtype = QTYPE[request.q.qtype]
        # Try to resolve locally

        rtype = 'A' #Default to returning an A record unless otherwise specified
        rdata = '0.0.0.0' #Default IP to return(what would be best here?)
        if "aws.dns" in str(qname):
            subdomain = str(qname).strip('.').split('.')[:-2]
            service = subdomain.pop()
            if "ec2" in service:
                type = subdomain.pop()
                if "ip" in type:
                    rtype = 'A'

                elif "cname" in type:
                    rtype = 'CNAME'

                net = subdomain.pop()

                #Grab the instance object
                id = subdomain.pop()
                ec2 = boto3.resource('ec2', region_name="us-west-2")    #TODO: some region setting somewhere
                instance = ec2.Instance(id)
                if "private" in net:
                    if "ip" in type:
                        rdata = str(instance.private_ip_address)
                    elif 'cname' in type:
                        rdata = str(instance.private_dns_name)
                elif "public" in net:
                    if "ip" in type:
                        rdata = str(instance.public_ip_address)
                    elif 'cname' in type:
                        rdata = str(instance.public_dns_name)
                    print(rdata)
            #Check we have a reply:
            if rdata == 'None' or rdata == '':
                reply.header.rcode = getattr(RCODE,'NXDOMAIN')
                return reply
            #Build an send the reply
            rr = RR.fromZone("{} IN {} {}".format(str(qname), rtype, rdata))[0]
            reply.add_answer(rr)

        # 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')

        return reply
Exemplo n.º 19
0
 def __init__(self,zone,glob=False):
     """
         Initialise resolver from zone file. 
         Stores RRs as a list of (label,type,rr) tuples
         If 'glob' is True use glob match against zone file 
     """
     self.zone = [(rr.rname,QTYPE[rr.rtype],rr) for rr in RR.fromZone(zone)]
     self.glob = glob
     self.eq = 'matchGlob' if glob else '__eq__'
Exemplo n.º 20
0
 def __init__(self, zone, glob=False):
     """
     Initialise resolver from zone file.
     Stores RRs as a list of (label,type,rr) tuples
     If 'glob' is True use glob match against zone file
     """
     self.zone = [(rr.rname, QTYPE[rr.rtype], rr) for rr in RR.fromZone(zone)]
     self.glob = glob
     self.eq = "matchGlob" if glob else "__eq__"
Exemplo n.º 21
0
 def resolve(self, request, handler):
     reply = request.reply()
     qname = request.q.qname
     ip = self.get_ip(f'{qname}'[:-1])
     if ip:
         reply.add_answer(*RR.fromZone(f'{qname} 60 A {ip}'))
     else:
         reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
     return reply
Exemplo n.º 22
0
 def load_rules(cls, rules):
     for rule in rules:
         zone = None
         try:
             zone = RR.fromZone(rule)
         except Exception:
             print('[e] Malformed rule -- {rule}'.format(rule=rule))
             continue
         domain = rule.split()[0]
         cls._rules_tables[domain] = zone
Exemplo n.º 23
0
 def resolve(self, request, handler):
     reply = request.reply()
     zone = '\n'.join('{} 1 TXT "{}"'.format(
         request.q.qname,
         txt.strip(),
     ) for txt in records(self._records_file))
     if VERBOSE:
         sys.stderr.write(repr(zone) + '\n')
     reply.add_answer(*RR.fromZone(zone))
     return reply
Exemplo n.º 24
0
 def resolve(self, request: DNSRecord, handler):
     qname = request.q.qname
     domain = str(qname).strip(".")
     ip = self.backend.get_ip(domain)
     reply = request.reply()
     if ip:
         zone = "{} {} A {}".format(qname, self.ttl, ip)
         reply.add_answer(*RR.fromZone(zone))
     else:
         reply.header.rcode = getattr(RCODE, "NXDOMAIN")
     return reply
    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname

        if request.q.qtype == 16:
            records = ""
            for r in self.tokens:
                records += ". 60 TXT %s\n" % r

            resp = RR.fromZone(records)
        else:
            resp = RR.fromZone(". 60 A 127.0.0.1")  # for dig

        if request.q.qtype == 1 or request.q.qtype == 16:
            for rr in resp:
                a = copy.copy(rr)
                a.rname = qname
                reply.add_answer(a)

        return reply
Exemplo n.º 26
0
 def resolve(self, request, handler):
     reply = request.reply()
     if request.q.qtype == 15:
         mxrr = RR.fromZone("{} IN MX 10 mail.{}".format(
             request.q.qname, request.q.qname))
         reply.add_answer(*mxrr)
     elif request.q.qtype == 1 and "mail." in str(request.q.qname):
         arr = RR.fromZone("{} IN A {}".format(request.q.qname,
                                               DEST_SERVER))
         reply.add_answer(*arr)
     else:
         try:
             if handler.protocol == 'udp':
                 proxy_r = request.send('1.1.1.1', 53, timeout=10)
             else:
                 proxy_r = request.send('1.1.1.1', 53, tcp=True, timeout=10)
             reply = DNSRecord.parse(proxy_r)
         except socket.timeout:
             reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
     return reply
Exemplo n.º 27
0
 def _resolve(self, query: Query, reply, _):
     if query.domain != self._domain:
         raise exceptions.MissingDomainException()
     zone = self._zones.get(query.zone)
     if not zone:
         raise exceptions.MissingZoneException()
     response = zone.resolve(query)
     if not response:
         return
     for answer in response.answers:
         print('Answer: {}'.format(answer))
         reply.add_answer(*RR.fromZone(answer, ttl=response.ttl))
Exemplo n.º 28
0
    def resolve(self, request, handler):
        try:
            resprs = []

            for q in request.questions:
                if str(q.qname) == self.host + '.':
                    if self.hostrecord_ttl <= 0:
                        self.hostrecord = None
                        
                    if self.hostrecord is None:
                        for tr in self.trustable:
                            try:
                                print(tr)
                                self.hostrecord = DNSRecord.parse(DNSRecord.question(self.host).send(tr, 53, timeout=self.timeout)).get_a()
                                self.hostrecord_ttl = 50
                                break
                            except:
                                continue
                    else:
                        self.hostrecord_ttl -= 1

                    resprs.append(self.hostrecord)
                    print('[host]', self.hostrecord)
                    continue
           
                resp = requests.get(self.address + '?domain={domain}&type={type}'.format(**{
                    'domain': str(q.qname),
                    'type': q.qtype
                })).content
                resp = json.loads(resp)
                if isinstance(resp, list):
                    print(resp)
                    resprs += resp

            reply = request.reply()
            for r in resprs:
                reply.add_answer(
                    *(RR.fromZone('{host}. {ttl} {class} {type} {ip}'.format(**r))
                      if isinstance(r, dict)
                      else
                      [r])
                )

        except socket.timeout:
            reply = request.reply()
            reply.header.rcode = RCODE.NXDOMAIN
        # except:
#             reply = request.reply()
#             reply.header.rcode = RCODE.NXDOMAIN
#             return reply
            
        return reply
Exemplo n.º 29
0
 def resolve(self, request, handler):
     reply = request.reply()
     qname = request.q.qname
     if qname not in self.args.dnsname:
         print "Skipping: %s is not a configured DNS name." % (qname)
         return reply
     # Replace labels with request label
     for ip in self.get_qfs_ips():
         rr = RR.fromZone('. 0 IN A {}'.format(ip))[0]
         a = copy.copy(rr)
         a.rname = qname
         reply.add_answer(a)
     return reply
Exemplo n.º 30
0
 def resolve(self, request, handler):
     """
         Respond to DNS request - parameters are request packet & handler.
         Method is expected to return DNS response
     """
     reply = request.reply()
     qname = request.q.qname.idna()[:-1].lower()
     qtype = QTYPE[request.q.qtype]
     if qtype == 'TXT' and qname in self.txtMap:
         reply.add_answer(*RR.fromZone('{} IN TXT "{}"'.format(
             qname, self.txtMap[qname])))
     else:
         reply.header.rcode = RCODE.NXDOMAIN
     return reply
Exemplo n.º 31
0
    def resolve(self, request, handler):
        reply = request.reply()

        query = str(request.q.qname)
        if query != settings.CDN_DOMAIN:
            return reply

        client_ip, client_port = handler.client_address

        code_continent = self.get_continent_code_from_ip(client_ip)
        cdn_node_ip = self.get_cdn_node_ip(code_continent)

        if cdn_node_ip:
            dns_answer = '{} 300 IN A {}'.format(reply.q.qname, cdn_node_ip)
            reply.add_answer(*RR.fromZone(dns_answer))

        return reply
Exemplo n.º 32
0
def GetBINDRecords(domain):
    file = BINDPath(domain)
    f = open(file, "r")
    body = f.read()
    f.close()

    records = RR.fromZone(body)
    ss = ""
    for r in records:
        host = HostConvert(r, domain)
        ttl = r.ttl
        cl = CLASS.get(r.rclass)
        qt = QTYPE.get(r.rtype)
        record = r.rdata.toZone()
        line = '%-23s %-7s %-7s %-7s %s' % (host, ttl, cl, qt, record)
        ss += line + "\n"
    return ss
Exemplo n.º 33
0
    def resolve(self, request, handler):
        db = Data()
        reply = request.reply()
        print(type(request))
        print('------------')
        #print(request.q)
        host = None
        ip = None
        for i in request.questions:
            host = i.qname
            ip = db.get_ip_by_host(host)
            print("Host {0} got ip {1}".format(host, ip))
            break

        print('------------')
        reply.add_answer(*RR.fromZone("{0} 60 A {1}".format(host, ip[0])))
        return reply
Exemplo n.º 34
0
 def __init__(self, address, port, ttl, intercept, skip, nxdomain):
     """
         address/port    - upstream server
         ttl             - default ttl for intercept records
         intercept       - list of wildcard RRs to respond to (zone format)
         skip            - list of wildcard labels to skip
         nxdomain        - list of wildcard labels to retudn NXDOMAIN
     """
     self.address = address
     self.port = port
     self.ttl = parse_time(ttl)
     self.skip = skip
     self.nxdomain = nxdomain
     self.zone = []
     for i in intercept:
         if i == "-":
             i = sys.stdin.read()
         for rr in RR.fromZone(i, ttl=self.ttl):
             self.zone.append((rr.rname, QTYPE[rr.rtype], rr))
Exemplo n.º 35
0
    def resolve(self,request,handler):
        reply = request.reply()
        qname = request.q.qname
        qtype = QTYPE[request.q.qtype]

        if qtype == 'SRV':
            port = 389
            if qname.label[0] == '_kpasswd':
                port = 464
            a = RR.fromZone('. 60 IN SRV 0 100 %d 192.168.0.1' % port)[0]
            a.rname = qname
            reply.add_answer(a)
        else:
            # Replace labels with request label
            for rr in self.rrs:
                a = copy.copy(rr)
                a.rname = qname
                reply.add_answer(a)
        return reply
Exemplo n.º 36
0
    def __init__(self, proxy=False, upstream=None):
        # Prepare the RRs
        self.rrs = RR.fromZone(LOCALHOST_ZONE)

        # Set which domain to serve
        self.domains = set()

        # Set the upstream DNS server
        if proxy and upstream:
            try:
                self.upstream, self.upstream_port = upstream.split(":")
                self.upstream_port = int(self.upstream_port)
            except ValueError:
                self.upstream = upstream
                self.upstream_port = 53
            finally:
                self.proxy = True
        else:
            self.proxy = False

        self.lock = threading.Lock()
Exemplo n.º 37
0
    def __init__(self, proxy=False, upstream=None):
        # Prepare the RRs
        self.rrs = RR.fromZone(LOCALHOST_ZONE)

        # Set which domain to serve
        self.domains = set()

        # Set the upstream DNS server
        if proxy and upstream:
            try:
                self.upstream, self.upstream_port = upstream.split(":")
                self.upstream_port = int(self.upstream_port)
            except ValueError:
                self.upstream = upstream
                self.upstream_port = 53
            finally:
                self.proxy = True
        else:
            self.proxy = False

        self.lock = threading.Lock()
Exemplo n.º 38
0
 def resolve(self,request,handler):
     client_ip = handler.client_address[0]
     #print "Request from IP: {}".format(client_ip)
     qname = request.q.qname
     qtype = QTYPE[request.q.qtype]
     reply = request.reply()
     self.log.debug("{} request for {} by {}".format(qtype,qname,client_ip))
     #print "query: {}".format(qname)
     #print "query: {}".format(qname.matchGlob("*.yahoo.com"))
     # Try to resolve locally unless on skip list
     rules = self.get_matching_rules(client_ip,qname)
     self.log.debug("Matched rules: {}".format(rules))
     if any(rules):
         ## Collecting info on match for logging
         match_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
         match_name = client_ip
         match_hosts = [h.name for h in self.hosts if h.ip == client_ip]
         if any(match_hosts):
             match_name = ",".join(match_hosts)
         for rule in rules:
             if rule.action == 'monitor':
                 monitor.info({'time':match_time,'match_name':match_name,'client_ip':client_ip,'qname':str(qname)})
             if rule.action == 'redirect':
                 self.log.debug( "[{}] REDIRECT {}-->{} to {}".format(match_time,match_name,qname,rule.redirect) )
                 redir = rule.redirect
                 reply.add_answer(*RR.fromZone("{} 3600 IN A {}".format(qname,redir)))
                 return reply
             if rule.action == 'block':
                 self.log.debug( "[{}] BLOCKED {}({})-->{}".format(match_time,match_name,client_ip,qname) )
                 return reply
             if rule.action == 'allow':
                 self.log.debug( "[{}] ALLOWED {}({})-->{}".format(match_time,match_name,client_ip,qname) )
     ## If no match or action == 'allow', then proxy the request to IP_UP
     if handler.protocol == 'udp':
         proxy_r = request.send(self.UP_IP,self.UP_PORT)
     else:
         proxy_r = request.send(self.UP_IP,self.UP_PORT,tcp=True)
     reply = DNSRecord.parse(proxy_r)
     return reply
Exemplo n.º 39
0
    def handle(self, data, address):
        dns = self.parse(data)
        #print "get dns query from %s,query:%s" %(str(address),str(dns))
        find = False
        IPAddress = None
        for preg, ip in Hosts.iteritems():
            if dns.q.qname == preg:
                find = True
                IPAddress = ip
                break

        if find and dns.q.qtype == 1:  #only handle A record
            print 'domain:%s in hosts' % dns.q.qname

            dns = dns.reply()
            dns.add_answer(
                *RR.fromZone(" A ".join([str(dns.q.qname), IPAddress])))
            self.socket.sendto(dns.pack(), address)
        else:
            #print 'transfer for %s' % dns.q.qname
            response, serveraddress = udp_send(LOCALDNS, data)
            self.socket.sendto(response, address)
Exemplo n.º 40
0
    def resolve(self, request, handler):
        reply = request.reply()

        # we handle A queries only
        if QTYPE[request.q.qtype] == 'A':
            # filter db for this domain
            domain = str(request.q.qname).rstrip('.')
            server = Server.objects.get_for_dns_or_none(domain=domain)
            if server:
                # add the answer to the request
                reply.add_answer(*RR.fromZone(
                    '{domain} {ttl} A {ip}'.format(
                        domain=domain,
                        ttl=300,
                        ip=server.ip
                    )
                ))

        # if there's no anser already, send query upstream
        if not reply.rr:
            proxy_r = request.send('8.8.8.8', 53)
            reply = DNSRecord.parse(proxy_r)

        return reply
Exemplo n.º 41
0
 def __init__(self,zone):
     # Parse RRs
     self.rrs = RR.fromZone(zone)
Exemplo n.º 42
0
 def load(self):
     logging.info("Loading DNS information from cloud providers")
     self.zone = [(rr.rname,QTYPE[rr.rtype],rr) for rr in RR.fromZone(self.zone_file_generator())]