示例#1
0
    async def _get_record(self, request, client_writer):
        domain = str(request.questions[0].qname)[:-1]
        qtype = request.questions[0].qtype
        logger.info('dns_request: %s, %s', domain, qtype)

        if not self.conf.GET_PROXY.isgfwed_resolver(domain):
            # try resolve with getaddrinfo first
            logger.debug('not gfwed.')
            if qtype in (dnslib.QTYPE.A, dnslib.QTYPE.AAAA, dnslib.QTYPE.ANY):
                result_list = await resolve(domain, 0)
                response = request.reply()
                for result in result_list:
                    if result[0] == socket.AF_INET and qtype in (
                            dnslib.QTYPE.A, dnslib.QTYPE.ANY):
                        response.add_answer(
                            dnslib.RR(domain,
                                      dnslib.QTYPE.A,
                                      rdata=dnslib.A(result[1])))

                    elif result[0] == socket.AF_INET6 and qtype in (
                            dnslib.QTYPE.AAAA, dnslib.QTYPE.ANY):
                        response.add_answer(
                            dnslib.RR(domain,
                                      dnslib.QTYPE.AAAA,
                                      rdata=dnslib.AAAA(result[1])))
                return response

        await self.tcp_dns_record(request, client_writer)
示例#2
0
def pack_dns(dns, answers, soa=None):
    def content_type(x):
        #  valid ip
        if socket.inet_aton(x):
            return 'A'
        else:
            return 'CNAME'

    if answers:
        for ans in answers:
            # logger.info('ans ' + ans)
            if content_type(ans[1]) == 'A':
                dns.add_answer(
                    dnslib.RR(ans[0], dnslib.QTYPE.A, rdata=dnslib.A(ans[1])))
            elif content_type(ans[1]) == 'CNAME':
                dns.add_answer(
                    dnslib.RR(ans[0],
                              dnslib.QTYPE.CNAME,
                              rdata=dnslib.CNAME(ans[1])))
    elif soa:
        soa_content = soa[1].split()
        dns.add_auth(
            dnslib.RR(soa[0],
                      dnslib.QTYPE.SOA,
                      rdata=dnslib.SOA(soa_content[0], soa_content[1],
                                       (int(i) for i in soa_content[2:]))))
    return dns
示例#3
0
    def handle(self):
        try:
            data = self.get_data()
            query = dnslib.DNSRecord.parse(data)
            reply = query.reply()
            answers = []

            if reply.get_q().qtype == dnslib.QTYPE.TXT:
                try:
                    challenge_files = os.listdir(BaseDNSRequestHandler.challenges_path)
                    for challenge_file in challenge_files:
                        if challenge_file.startswith(str(reply.get_q().qname).strip('.')):
                            with open(os.path.join(BaseDNSRequestHandler.challenges_path,
                                                   challenge_file), 'r') as challenge_data:
                                answers.append(dnslib.RR(rname=reply.get_q().qname,
                                                         rtype=reply.get_q().qtype,
                                                         ttl=60,
                                                         rdata=dnslib.TXT(challenge_data.read().strip())))
                except OSError:
                    pass
            else:
                answers.append(dnslib.RR(rname=reply.get_q().qname,
                                         ttl=60,
                                         rdata=dnslib.A(LISTEN_ADDRESS)))

            for answer in answers:
                reply.add_answer(answer)
            self.send_data(reply.pack())
        except Exception as e:
            print(e)
示例#4
0
    def build_answer(self, d, err, aa, answer, authority, additional):
        # Construct answer
        reply = dnslib.DNSRecord(
            dnslib.DNSHeader(qr=1, aa=aa, rd=0, rcode=err, id=d.header.id))
        reply.questions = d.questions
        # answer section
        for rr in answer:
            print rr
            reply.add_answer(
                dnslib.RR(rtype=rr['type'],
                          rclass=rr['class'],
                          ttl=rr['ttl'],
                          rname=rr['name'],
                          rdata=dnslib.RDMAP[dnslib.QTYPE[rr['type']]](
                              rr['rdata'])))
        # authority section
        for rr in authority:
            reply.add_answer(
                dnslib.RR(rtype=rr['type'],
                          rclass=rr['class'],
                          ttl=rr['ttl'],
                          rdata=rr['rdata']))
        # additional section
        for rr in additional:
            reply.add_answer(
                dnslib.RR(rtype=QRTYPE[rr['type']],
                          rclass=QRCLASS[rr['class']],
                          ttl=rr['ttl'],
                          rdata=rr['rdata']))

        return reply.pack()
示例#5
0
文件: search.py 项目: jwsi/dns-server
def _add_additional(addi_list):
    """
    Given a domain and an additional set,
    this function will add the A records for the UH DNS nameservers to the set.
    :param addi_list: Additional set to add to.
    """
    if addi_list == []:
        addi_list.append(
            dnslib.RR(rname="ns1.uh-dns.com.",
                      rtype=dnslib.QTYPE.A,
                      rdata=dnslib.A("18.130.161.247"),
                      ttl=3600))
        addi_list.append(
            dnslib.RR(rname="ns1.uh-dns.com.",
                      rtype=dnslib.QTYPE.AAAA,
                      rdata=dnslib.AAAA("2a05:d01c:35b:7601::4"),
                      ttl=3600))
        addi_list.append(
            dnslib.RR(rname="ns2.uh-dns.com.",
                      rtype=dnslib.QTYPE.A,
                      rdata=dnslib.A("18.130.86.161"),
                      ttl=3600))
        addi_list.append(
            dnslib.RR(rname="ns2.uh-dns.com.",
                      rtype=dnslib.QTYPE.AAAA,
                      rdata=dnslib.AAAA("2a05:d01c:35b:7600::4"),
                      ttl=3600))
示例#6
0
文件: main.py 项目: lhtest429/x386
        def handle(self):
            """
            处理dns 请求

            rebindflag 只有 True, 0 1 2 4个值,初始化是0,以后就在1,2之间变化,如果你手工设置rebindflag为‘True’,则record 返回remote_addr
            根据rebindflag 的值返回record的结果
            rebindflag=1 时候返回rebinding设置的IP
            rebindflag为0或者2的时候返回 正常IP(比如域名是:123.123.1.1.qingbx.com,则返回123.123.1.1
            域名的格式必须为IP.你注册的域名,这里IP为123.123.1.1, 控制的域名为qingbx.com
            你需要在域名注册商哪里将NS指向此DNS解析)

            :return:
            """
            record = ''
            ttl = int(common.conf_read('ttl'))
            record_type = common.conf_read('record_type')
            rebinding = common.conf_read('rebinding')
            rebindflag = int(common.conf_read('rebindflag'))

            client = self.client_address
            req = dnslib.DNSRecord.parse(self.packet).reply()
            qname = req.q.qname.__str__()

            if rebinding != 'False' and rebindflag == 1:
                if rebinding == 'True':
                    record = client[0]
                else:
                    record = rebinding
                common.conf_set({"rebindflag": "2"})
            else:
                record = common.analy_req(qname)
                common.conf_set({"rebindflag": "1"})

            try:
                if record:
                    # 构造DNS响应报文
                    try:
                        req.add_answer(
                            dnslib.RR(
                                qname,
                                eval('dnslib.QTYPE.{}'.format(record_type)),
                                rdata=eval(
                                    'dnslib.{}(record)'.format(record_type)),
                                ttl=ttl))
                    except:
                        record = '8.8.8.8'
                        req.add_answer(
                            dnslib.RR(
                                qname,
                                eval('dnslib.QTYPE.{}'.format(record_type)),
                                rdata=eval(
                                    'dnslib.{}(record)'.format(record_type)),
                                ttl=ttl))
                        print "not a needed domain"

                else:
                    print 'found query'
            except Exception, e:
                sys.exit(e.message)
示例#7
0
    def handle(self): 
        global count       
        count=count+1 #序号
        request_data = self.request[0]
        client_socket = self.request[1]
        #内部搜索
        d=DNSRecord.parse(request_data)
        qname=str(d.q.qname)
        qid=d.header.id
        search=cache.get(qname)
        #print(qname)
        if search:
            ret=d.reply()
            # 不良网站
            if search=="0.0.0.0":
                ret.add_answer(dnslib.RR(qname,QTYPE.TXT,rdata=dnslib.TXT(warning)))
            else:
                ret.add_answer(dnslib.RR(qname,rdata=dnslib.A(search)))
            ret.header.id=qid
            if debug_print:
                print(time.asctime( time.localtime(time.time())),"  ",
                count,"  ",self.client_address,qname)
            elif debug_print2:
                print("\n\n\n")
                print("*******Request Data***********")
                print(d)
                print("********Client Address********")
                print(self.client_address)
                print("********Search Name***********")
                print(qname)
                print("********Search IP*************")
                print(search)

            client_socket.sendto(bytes(ret.pack()), self.client_address)
        else:
            # 将请求转发到 外部 DNS
            redirect_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            redirect_socket.sendto(request_data, (DNS_server, 53))
            response_data, address = redirect_socket.recvfrom(8192)

            if debug_print:
                print(time.asctime( time.localtime(time.time())),"  ",
                count,"  ",self.client_address,qname)
            elif debug_print2:
                print("\n\n\n")
                print("*******Request Data***********")
                print(d)
                print("********Client Address********")
                print(self.client_address)
                print("********Search Name***********")
                print(qname)
                print("********Search IP*************")
                print(DNSRecord.parse(response_data))
            # 将外部响应响应给客户
            client_socket.sendto(response_data, self.client_address)
示例#8
0
    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname

        # Refuse queries thaat are not for our domain
        if tuple(map(str.lower, map(qname._decode, qname.label[-2:]))) != \
            tuple(map(str.lower, map(self.domain._decode, self.domain.label[-2:]))):
            reply.header.rcode = dnslib.RCODE.REFUSED
            return reply

        # Answer questions about the root domain name
        # TODO(supersat): We don't need to implement this, right?
        if len(qname.label) <= 3:
            if request.q.qtype == dnslib.QTYPE.A:
                reply.add_answer(
                    dnslib.RR(qname,
                              dnslib.QTYPE.A,
                              ttl=300,
                              rdata=self.server_ip))
            return reply

        subdomain = qname._decode(qname.label[1]).lower()
        hostname = qname._decode(qname.label[0]).lower()
        if BASE36_SHA256_HASH.match(subdomain) and len(qname.label) == 4:
            if hostname == '_acme-challenge' and \
                (request.q.qtype == dnslib.QTYPE.TXT or \
                request.q.qtype == dnslib.QTYPE.ANY):
                txt = self.redis.get('acme-dns-01-chal:{}'.format(subdomain))
                if txt:
                    reply.add_answer(
                        dnslib.RR(qname,
                                  dnslib.QTYPE.TXT,
                                  ttl=300,
                                  rdata=dnslib.TXT(txt)))
                else:
                    reply.header.rcode = dnslib.RCODE.NXDOMAIN
            elif IPV4_REGEX.match(hostname) and \
                (request.q.qtype == dnslib.QTYPE.A or \
                request.q.qtype == dnslib.QTYPE.ANY):
                try:
                    ip = tuple(map(int, hostname.split('-')))
                    reply.add_answer(
                        dnslib.RR(qname,
                                  dnslib.QTYPE.A,
                                  ttl=300,
                                  rdata=dnslib.A(ip)))
                except:
                    reply.header.rcode = dnslib.RCODE.NXDOMAIN
            else:
                reply.header.rcode = dnslib.RCODE.NXDOMAIN
            return reply

        reply.header.rcode = dnslib.RCODE.NXDOMAIN
        return reply
示例#9
0
 def pack_dns(self, dns, answers, soa=None):
     content_type = lambda x: 'A' if re.match('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', x) else 'CNAME'
     if answers:
         for ans in answers:
             if content_type(ans[1]) == 'A':
                 dns.add_answer(dnslib.RR(ans[0], dnslib.QTYPE.A, rdata=dnslib.A(ans[1])))
             elif content_type(ans[1]) == 'CNAME':
                 dns.add_answer(dnslib.RR(ans[0], dnslib.QTYPE.CNAME, rdata=dnslib.CNAME(ans[1])))
     elif soa:
         soa_content = soa[1].split()
         dns.add_auth(dnslib.RR(soa[0], dnslib.QTYPE.SOA,
                                rdata=dnslib.SOA(soa_content[0], soa_content[1], (int(i) for i in soa_content[2:]))))
 
     return dns
示例#10
0
    def domain2ip(self, qdomain, ips):
        ans = []
        if type(ips) == list:
            for ip in ips:
                ans.append({
                    qdomain:
                    dnslib.RR(qdomain, rdata=dnslib.A(ip), ttl=self.ttl)
                })
        elif type(ips) == str:
            ans.append({
                qdomain:
                dnslib.RR(qdomain, rdata=dnslib.A(ips), ttl=self.ttl)
            })

        return ans
示例#11
0
 def evaluate(self):
   parts = self._qname.split(".")
   for part in parts:
     opt = part
     arg = []
     if "-" in part:
       _tmp = part.split("-")
       opt = _tmp[0]
       arg = _tmp[1:]
     #print(opt + "(" + str(arg) + ")")
     _func_ptr = getattr(self, "_handle_opt_{0}".format(opt), None)
     if _func_ptr is None:
       continue
     result = _func_ptr(*arg)
     if result is None:
       continue
     for entry in result:
       upper_rt = entry['rtype'].upper()
       rt_val = getattr(dnslib.QTYPE, upper_rt)
       rd_class = getattr(dnslib, upper_rt)
       self._add_func_ptr(dnslib.RR(
         rname = self._qname,
         ttl = DEFAULT_TTL,
         rclass = self._qclass,
         rtype = rt_val,
         rdata = rd_class(entry['data'])
       ))
示例#12
0
        def handle(self):
            record = ''
            ttl = int(common.conf_read('ttl'))
            record_type = common.conf_read('type')
            rebinding = common.conf_read('rebinding')
            rebindflag = int(common.conf_read('rebindflag'))

            client = self.client_address
            req = dnslib.DNSRecord.parse(self.packet).reply()
            qname = req.q.qname.__str__()

            if rebinding != 'False' and rebindflag == 1:
                if rebinding == 'True': record = client[0]
                else: record = rebinding
                common.conf_set({"rebindflag": "2"})
            else:
                record = common.analy_req(qname)
                common.conf_set({"rebindflag": "1"})

            try:
                if record:
                    req.add_answer(
                        dnslib.RR(qname,
                                  eval('dnslib.QTYPE.{}'.format(record_type)),
                                  rdata=eval(
                                      'dnslib.{}(record)'.format(record_type)),
                                  ttl=ttl))
                else:
                    print 'found query'
            except Exception, e:
                print e
                exit()
示例#13
0
    def run(self):
        fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        fd.bind(('', 53))

        while True:
            try:
                packet, isp_dns_address = fd.recvfrom(8192)
                req = dnslib.DNSRecord.parse(packet)

                a = req.reply()
                q_name = req.get_q().qname
                q_type = req.get_q().qtype
                q_type_str = dnslib.QTYPE.get(q_type)

                if q_type_str == 'A':
                    a.add_answer(
                        dnslib.RR(q_name,
                                  dnslib.QTYPE.A,
                                  rdata=dnslib.A(SERVER_PUBLIC_IP),
                                  ttl=600))

                    lock.acquire()
                    k = str(q_name)
                    domain_dns_dict[k] = isp_dns_address[0]
                    delete_later(domain_dns_dict, k)
                    lock.release()

                print('dns request : ', q_name, q_type_str, isp_dns_address)
                sys.stdout.flush()
                fd.sendto(a.pack(), isp_dns_address)
            except Exception as e:
                print(e)
                sys.stdout.flush()
示例#14
0
文件: server.py 项目: eaufavor/laDNSp
def prepare_reply(answer, request):
    #pack anwsers
    qname = request.q.qname
    qtype = request.q.qtype
    qt = dnslib.QTYPE[qtype]
    rcode = 0

    reply = dnslib.DNSRecord(\
                dnslib.DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),\
                                 q=request.q)
    bad_reply = dnslib.DNSRecord(dnslib.DNSHeader(\
                            id=request.header.id, qr=1, aa=1, ra=1,\
                            rcode=rcode), q=request.q)

    record_class = getattr(dnslib, str(qt))
    empty_ans = True
    if rcode == 0:
        rcode = answer[1]
    for a in answer[0]:
        empty_ans = False
        reply.add_answer(dnslib.RR(rname=qname, rtype=qtype,\
                     rclass=1, ttl=10, rdata=record_class(a)))

    #print "---- Reply:\n", reply
    # if failed, send back error code
    if empty_ans and rcode > 0:
        reply = bad_reply

    return reply.pack()
示例#15
0
    def dns_response(self, data):

        request = dnslib.DNSRecord.parse(data)

        self.logger.debug("request:%s" % request)

        reply = dnslib.DNSRecord(dnslib.DNSHeader(id=request.header.id,
                                                  qr=1,
                                                  aa=1,
                                                  ra=1),
                                 q=request.q)

        qname = request.q.qname
        qn = str(qname)
        qtype = request.q.qtype
        qt = dnslib.QTYPE[qtype]

        addrs = self.resolve(qname, qt)

        if qt in ["A", "MX", "NS", "AAAA"]:
            for item in addrs:
                reply.add_answer(
                    dnslib.RR(rname=qname,
                              rtype=self.rtypes[qt],
                              rclass=1,
                              ttl=self.TTL,
                              rdata=self.rdatatypes[qt](item)))
                self.logger.debug("DNS reply:%s:%s" % (qt, reply))
        else:
            #TODO:*1 add the other record types e.g. SOA & txt & ...
            self.logger.error("did not find type:\n%s" % request)

        return reply.pack()
示例#16
0
    async def handle_query(
        self,
        request: DNSRecord,
        source: TSource,
    ) -> DNSRecord:
        if source[0] not in self.network:
            return None
        reply = request.reply()
        gave_answers = False

        for question in request.questions:
            orig_qname = question.qname
            self.validate_query_label(orig_qname)
            if not orig_qname.matchSuffix(self.hostname):
                raise Exception('Request for non local domain.')
            qname = orig_qname.stripSuffix(self.hostname)
            qtype = question.qtype
            self.logger.debug('Question %r %r', qname, QTYPE[qtype])

            records = self.get_records(qname, qtype)
            for record in records:
                reply.add_answer(dnslib.RR(
                    rname=orig_qname,
                    rtype=qtype,
                    rdata=record,
                ))
                gave_answers = True

        if not gave_answers:
            self.logger.debug('No answers')
            reply.header.set_rcode(RCODE.NXDOMAIN)

        return reply
示例#17
0
文件: search.py 项目: jwsi/dns-server
def _soa_search(record, rr_list, auth_list, addi_list, authority):
    """
    Searches and adds any SOA records for the domain.
    :param record: Overall record for domain
    :param rr_list: Current record list for the domain
    :param auth_list: Authority list for the domain
    :param addi_list: Additional list for the domain
    :param authority: Add record to authority list or answer list.
    """
    try:
        soa_record = record["SOA"]
        ttl = int(soa_record["ttl"])
        times = soa_record["times"]
        times = list(map(lambda time: int(time), times))
        rr = dnslib.RR(rname = record["domain"],
                                 rtype = dnslib.QTYPE.SOA,
                                 rdata = dnslib.SOA(mname = soa_record["mname"],
                                                    rname = soa_record["rname"],
                                                    times = times),
                                 ttl   = ttl)
        if authority:
            auth_list.append(rr)
        else:
            rr_list.append(rr)
            _add_authority(record["domain"], auth_list)
            _add_additional(addi_list)
    except:
        parent_domain = record["domain"].split(".", 1)[1:][0]
        p_rr_list, _, _ = search(domain=parent_domain, q_type=dnslib.QTYPE.SOA)
        auth_list.extend(p_rr_list)
示例#18
0
文件: search.py 项目: jwsi/dns-server
def _naptr_search(record, rr_list, auth_list, addi_list):
    """
    Searches and returns a list of NAPTR records for the domain.
    :param record: Overall record for domain
    :param rr_list: Current record list for the domain
    :param auth_list: Authority list for the domain
    :param addi_list: Additional list for the domain
    """
    try:
        naptr_record = record["NAPTR"]
        ttl = int(naptr_record["ttl"])
        for value in naptr_record["value"]:
            rr_list.append(dnslib.RR(rname = record["domain"],
                                     rtype = dnslib.QTYPE.NAPTR,
                                     rdata = dnslib.NAPTR(order       = int(value["order"]),
                                                          preference  = int(value["preference"]),
                                                          flags       = value["flags"].encode('utf-8'),
                                                          service     = value["service"].encode('utf-8'),
                                                          regexp      = (value.get("regexp") or "").encode('utf-8'),
                                                          replacement = value["replacement"]),
                                     ttl   = ttl))
            _add_authority(record["domain"], auth_list)
            _add_additional(addi_list)
    except:
        pass
示例#19
0
文件: search.py 项目: jwsi/dns-server
def _alias_search(q_type, record, rr_list, auth_list, addi_list):
    """
    If no A or AAAA records exist this function will add any fixed alias records.
    :param q_type: Query type (A or AAAA) alias records accepted.
    :param record: Record from DB.
    :param rr_list: resource record list.
    :param auth_list: authority list.
    :param addi_list: additional list.
    """
    try:
        alias_record = record["ALIAS"]
        ttl = int(alias_record["ttl"])
        question = dnslib.DNSRecord.question(alias_record["domain"], qtype=dnslib.QTYPE[q_type])
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(1)
        sock.bind(("", 0)) # Bind to any available IP and port.
        sock.sendto(question.pack(), ("10.0.0.2", 53))
        res = dnslib.DNSRecord.parse(sock.recv(4096))
        sock.close()
        for r in res.rr:
            ip = str(r.rdata)
            if q_type == dnslib.QTYPE.A:
                rdata = dnslib.A(ip)
            elif q_type == dnslib.QTYPE.AAAA:
                rdata = dnslib.AAAA(ip)
            rr_list.append(dnslib.RR(rname=record["domain"],
                                     rtype=q_type,
                                     rdata=rdata,
                                     ttl=ttl))
            _add_authority(record["domain"], auth_list)
            _add_additional(addi_list)
    except:
        pass
示例#20
0
    def try_tox3_resolve(self, reply, name, domain, req_name):
        if not name.startswith("_"):
            return None

        encrypted = name.replace(".", "")[1:]
        try:
            b = notsecure32_decode(encrypted)
            nonce = b[:4] + (b"\0" * 20)
            ck = b[4:36]
            payload = b[36:]
            dec_name = self.cryptocore.dsrep_decode_name(ck, nonce, payload)
        except Exception:
            return None

        try:
            dec_name = dec_name.decode("utf8")
        except UnicodeDecodeError:
            return None

        query = self.db.query(User).filter(
            and_(User.name == name, User.domain == domain))
        user = query.one()

        if not user:
            return None

        msg = binascii.unhexlify(user.toxid)
        nonce_reply = b[:4] + b"\x01" + (b"\0" * 19)
        ct = self.cryptocore.dsrec_encrypt_key(ck, nonce_reply, msg)
        key_part = notsecure32_encode(ct).decode("ascii")

        base = "v=tox3;id={0}".format(key_part).encode("utf8")
        reply.add_answer(dnslib.RR(req_name, 16, ttl=0,
                                   rdata=dnslib.TXT(base)))
        return reply
示例#21
0
def SendDnsData(data, s, addr):
    global Remote_dns_server
    global Remote_dns_port
    '''dns请求报文'''
    request_packet = dnslib.DNSRecord.parse(data)
    '''dns请求报文的域名'''
    domain = request_packet.get_q().get_qname()
    '''dns响应报文'''
    response_packet = request_packet.reply()
    ip = Search_key_ip(str(domain))
    if ip != None:
        print(domain, ':', ip)
        response_packet.add_answer(
            dnslib.RR(domain, dnslib.QTYPE.A, rdata=dnslib.A(ip), ttl=60))
        s.sendto(response_packet.pack(), addr)
    else:
        data = AddEDNSOption(data, addr[0])
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(5)
        sock.sendto(data, (Remote_dns_server, Remote_dns_port))
        while True:
            try:
                rspdata = sock.recv(4096)
            except Exception as e:
                logging.warn("Recv:\t%s" % e)
                break
            s.sendto(rspdata, addr)
            break
示例#22
0
    def handle(self):
        packet_bytes = self.request[0]
        packet_socket = self.request[1]
        parsed = False
        try:
            dnsreq = dnslib.DNSRecord.parse(packet_bytes)
            parsed = True
        except dnslib.DNSError:
            pass
        if parsed:
            logging.debug('IN FROM ADDRESS: %s, INTERFACE: %s, LLMNR DNS packet:\n%s' % (
                self.client_address,
                self.server.ifindex,
                repr(dnsreq)
            ))
            if dnslib.OPCODE.get(dnsreq.header.opcode) != 'QUERY':
                return
            if dnsreq.header.qr:
                # this is response
                if dnsreq.header.q != 1:
                    return
            else:
                # this is query
                if dnsreq.header.q != 1:
                    return
                if dnsreq.header.a != 0:
                    return
                if dnsreq.header.auth != 0:
                    return
                if dnsreq.header.aa:  # RFC 4795: flag C
                    return

                hostname = str(dnsreq.q.qname)
                if functools.reduce(
                        operator.or_,
                        (hostname == _hostname for _hostname in self.server.hostname_list),
                        False
                ):
                    dnsresp = dnsreq.reply(0, 0)
                    if dnsreq.q.qclass == dnslib.CLASS.IN:
                        if dnsreq.q.qtype == dnslib.QTYPE.AAAA:
                            for ipaddress in self.server.dispatcher.get_addresses_ipv6(self.server.ifindex):
                                dnsresp.add_answer(dnslib.RR(
                                    dnsreq.q.qname.idna(),
                                    dnslib.QTYPE.AAAA,
                                    ttl=60,
                                    rdata=dnslib.AAAA(ipaddress)
                                ))
                        else:
                            return
                    else:
                        return
                    dnsresp.header.aa = 0  # RFC 4795: flag C
                    packet_socket.sendto(dnsresp.pack(), self.client_address)
                    logging.debug('OUT TO ADDRESS: %s, LLMNR DNS packet:\n%s' % (
                        self.client_address, repr(dnsresp)
                    ))
示例#23
0
文件: records.py 项目: nhairs/nserver
 def to_resource_record(self) -> dnslib.RR:
     """Convert Record to a dnslib Resource Record"""
     resource_record = dnslib.RR(
         rname=self.resource_name,
         rtype=self._qtype,
         rdata=self._class(**self._record_kwargs),
         ttl=self.ttl,
     )
     return resource_record
示例#24
0
文件: search.py 项目: jwsi/dns-server
def _add_authority(domain, auth_list):
    """
    Given a domain and an authority set,
    this function will add the UH DNS nameservers to the set if they don't already exist.
    :param domain: Domain to be authoritative over.
    :param auth_list: Auth set to add to.
    """
    record1 = dnslib.RR(rname=domain,
                  rtype=dnslib.QTYPE.NS,
                  rdata=dnslib.NS("ns1.uh-dns.com"),
                  ttl=3600)
    record2 = dnslib.RR(rname=domain,
                  rtype=dnslib.QTYPE.NS,
                  rdata=dnslib.NS("ns2.uh-dns.com"),
                  ttl=3600)
    if record1 not in auth_list:
        auth_list.append(record1)
    if record2 not in auth_list:
        auth_list.append(record2)
示例#25
0
 def _fast_add_answer(self, rt, rd):
   self._rsp.add_answer(
     dnslib.RR(
       rname=self._qname, 
       ttl=DEFAULT_TTL,
       rclass=self._req.q.qclass, 
       rtype=rt, 
       rdata=rd
     )
   )
示例#26
0
 def handle(self):
     data = self.request[0]
     d = dnslib.DNSRecord.parse(data)
     id = d.header.id
     sock = self.request[1]
     res = dnslib.DNSRecord(dnslib.DNSHeader(qr=1, aa=1, ra=1, id=id),
                            q=dnslib.DNSQuestion(qname),
                            a=dnslib.RR(qname,
                                        rdata=dnslib.A("101.226.103.106"),
                                        ttl=3))
     sock.sendto(bytes(res.pack()), self.client_address)
示例#27
0
def add_answer_to_query(required_data, query):
    qtype = query.q.qtype
    q = query.q

    # Для каждого типа запроса добавляем интересующий ответ
    if qtype == dnslib.QTYPE.A:
        # Добавляем все A адреса
        for addr in required_data.addresses:
            query.add_answer(
                dnslib.RR(rname=q.qname,
                          rclass=q.qclass,
                          rtype=q.qtype,
                          ttl=required_data.remain_ttl(),
                          rdata=dnslib.A(addr)))
    if qtype == dnslib.QTYPE.AAAA:
        # Добавляем все AAAA адреса
        for addr in required_data.addresses:
            query.add_answer(
                dnslib.RR(rname=q.qname,
                          rclass=q.qclass,
                          rtype=q.qtype,
                          ttl=required_data.remain_ttl(),
                          rdata=dnslib.AAAA(addr)))
    if qtype == dnslib.QTYPE.NS:
        # Добавляем все NS серверы
        for addr in required_data.servers:
            query.add_answer(
                dnslib.RR(rname=q.qname,
                          rclass=q.qclass,
                          rtype=q.qtype,
                          ttl=required_data.remain_ttl(),
                          rdata=dnslib.NS(addr)))
    if qtype == dnslib.QTYPE.PTR:
        # Добавляем PTR
        query.add_answer(
            dnslib.RR(rname=q.qname,
                      rclass=q.qclass,
                      rtype=q.qtype,
                      ttl=required_data.remain_ttl(),
                      rdata=dnslib.PTR(required_data.name)))
示例#28
0
 def handle(self):
     request = dnslib.DNSRecord.parse(self.packet).reply()
     qname = str(request.q.qname)
     record, ttl, recordType = self.server.getRecord(qname)
     answer = dnslib.DNSRecord.question(qname)
     request.add_answer(
         dnslib.RR(qname,
                   getattr(dnslib.QTYPE, recordType),
                   rdata=getattr(dnslib, recordType)(record),
                   ttl=ttl))
     print('[%s] %s %s %s' %
           (time.time(), self.client_address, qname, record))
     self.wfile.write(request.pack())
def test_on_client_request_with_cache_expired(greendns):
    qname = "qqq.com"
    id = 1024
    s = init_greendns_session(greendns, qname, dnslib.QTYPE.A, id)
    res = dnslib.DNSRecord(dnslib.DNSHeader(qr=1, aa=1, ra=1),
                           q=dnslib.DNSQuestion(qname),
                           a=dnslib.RR(qname,
                                       rdata=dnslib.A("101.226.103.106"),
                                       ttl=3))
    greendns.cache.add(("qqq.com.", 1), res, 3)
    time.sleep(4)
    is_continue, raw_resp = greendns.on_client_request(s)
    assert is_continue
    assert not raw_resp
def test_shuffer_A(greendns):
    qname = "qq.com"
    id = 1024
    s = init_greendns_session(greendns, qname, dnslib.QTYPE.A, id)
    res = dnslib.DNSRecord(dnslib.DNSHeader(qr=1, aa=1, ra=1),
                           q=dnslib.DNSQuestion(qname),
                           a=dnslib.RR(qname,
                                       dnslib.QTYPE.CNAME,
                                       rdata=dnslib.CNAME("https.qq.com"),
                                       ttl=3))
    res.add_answer(dnslib.RR(qname, rdata=dnslib.A("101.226.103.106"), ttl=3))
    res.add_answer(dnslib.RR(qname, rdata=dnslib.A("101.226.103.107"), ttl=3))
    greendns.cache.add(("qq.com.", 1), res, 3)
    d = None
    for i in range(10):
        is_continue, raw_resp = greendns.on_client_request(s)
        assert not is_continue
        assert raw_resp
        d = dnslib.DNSRecord.parse(raw_resp)
        if str(d.rr[1].rdata) == "101.226.103.107":
            break
    assert d.rr[0].rtype == dnslib.QTYPE.CNAME
    assert str(d.rr[1].rdata) == "101.226.103.107"