예제 #1
0
def main():
    print("Starting DNS Server")
    print("Loading cache from disk...")
    global cache
    cache = load_cache_from_disk(CACHE_FILE_NAME)
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("localhost", 53))
    while True:
        data_in_socket, _, _ = select([sock], [], [], 1)
        if not data_in_socket:
            continue
        conn, addr = sock.recvfrom(2048)
        clear_old_cache(cache)
        try:
            dns_record = DNSRecord.parse(conn)
        except DNSError:
            print("Can't parse DNS record")
            continue
        cache_records(dns_record, cache)
        if not dns_record.header.qr:
            response = find_record_in_cache(dns_record, cache)
            if response:
                response = response.pack()
            else:
                try:
                    response = dns_record.send(forward_server)
                    cache_records(DNSRecord.parse(response), cache)
                except (OSError, DNSError):
                    print("Server " + forward_server + "unavailable")
            sock.sendto(response, addr)
        save_cache_to_disk(cache, CACHE_FILE_NAME)
예제 #2
0
파일: server.py 프로젝트: Titankrot/dns
def run():
    cache = load_cache()
    sock = create_connection(53)
    while True:
        data, addr = sock.recvfrom(2048)
        try:
            dns_record = DNSRecord.parse(data)
        except DNSError:
            continue
        add_record(dns_record, cache)
        if not dns_record.header.qr:
            response = get_response(dns_record, cache)
            try:
                if response:
                    response = response.pack()
                else:
                    response = dns_record.send(GOOGLE)
                    add_record(DNSRecord.parse(response), cache)
                sock.connect(addr)
                sock.sendall(response)
                sock.close()
                sock = create_connection(53)
            except:
                pass
        if cache:
            upload_cache(cache)
예제 #3
0
		def get_reply(self,data):
			global dns_cache
			global args
			host,port = self.server.resolver.address,self.server.resolver.port
			request = DNSRecord.parse(data)

			domain=str(request.q.qname)
			if domain in dns_cache:
				if time.time()<dns_cache[domain][0]:
					if args is not None and args.verbose:
						display("[i] domain %s served from cache"%domain)
					rep=request.reply()
					rep.add_answer(*dns_cache[domain][1])
					return rep.pack()
			if args is not None and args.verbose:
				display("[i] domain %s requested using TCP server %s"%(domain, args.dns_server))
			data = struct.pack("!H",len(data)) + data
			response = send_tcp(data,host,port)
			response = response[2:]
			reply = DNSRecord.parse(response)
			#print(repr(reply))
			ttl=3600
			try:
				ttl=reply.rr[0].ttl
			except Exception:
				try:
					ttl=reply.rr.ttl
				except Exception:
					pass
			dns_cache[domain]=(int(time.time())+ttl, reply.rr)
			if len(dns_cache)>DNS_CACHE_SIZE:
				dns_cache.popitem(last=False)
			return response
예제 #4
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)
예제 #5
0
        def get_reply(self, data):
            global dns_cache
            global args
            host, port = self.server.resolver.address, self.server.resolver.port
            request = DNSRecord.parse(data)

            domain = str(request.q.qname)
            qtype = str(QTYPE.get(request.q.qtype))
            index = domain + "/" + qtype
            if not args.no_cache and index in dns_cache:
                if time.time() < dns_cache[index][0]:
                    if args is not None and args.verbose:
                        try:
                            display("[i] %s served value from cache: %s" %
                                    (index, ', '.join(
                                        [x.rdata
                                         for x in dns_cache[index][1]])))
                        except:
                            pass
                    rep = request.reply()
                    rep.add_answer(*dns_cache[index][1])
                    return rep.pack()
            if args is not None and args.verbose:
                display("[i] domain %s requested using TCP server %s" %
                        (domain, args.dns_server))
            data = struct.pack("!H", len(data)) + data
            response = send_tcp(data, host, port)
            response = response[2:]
            reply = DNSRecord.parse(response)
            if args.verbose:
                try:
                    display(
                        "[i] %s %s resolve to %s" %
                        (domain, qtype, ', '.join([x.rdata
                                                   for x in reply.rr])))
                except:
                    pass
            ttl = 3600
            try:
                ttl = reply.rr[0].ttl
            except Exception:
                try:
                    ttl = reply.rr.ttl
                except Exception:
                    pass
            dns_cache[index] = (int(time.time()) + ttl, reply.rr)
            if len(dns_cache) > DNS_CACHE_SIZE:
                dns_cache.popitem(last=False)
            return response
def ingest_mdns_packet(mdns_pkt):
    logger.debug('Packet with Dot11, UDP, and Apple mDNS')

    # only parse MDNS names for 802.11 layer sniffing for now, easy to see what's a request from a client
    for mdns_pkt in mdns_pkt:
        if mdns_pkt.dport == 5353:
            logger.debug('Packet destination port 5353')
            try:
                d = DNSRecord.parse(mdns_pkt['Raw.load'])
                for q in d.questions:
                    if q.qtype == 255 and '_tcp.local' not in str(q.qname):
                        try:
                            src = mdns_pkt.getlayer('Dot11').addr3
                            name = str(q.qname).strip('.local')

                            # An mDNS Ethernet frame is a multicast UDP packet to:
                            # MAC address 01:00:5E:00:00:FB (for IPv4) or 33:33:00:00:00:FB (for IPv6)
                            # IPv4 address 224.0.0.251 or IPv6 address FF02::FB
                            # UDP port 5353
                            if src != '01:00:5e:00:00:fb':
                                create_or_update_client(
                                    src,
                                    datetime.utcfromtimestamp(mdns_pkt.time),
                                    name)

                        except AttributeError:
                            logger.error('Error parsing MDNS packet')
            except IndexError:
                pass
예제 #7
0
    def on_udp_query(self, req_data, addr):
        start_time = time.time()
        try:
            request = DNSRecord.parse(req_data)
            if len(request.questions) != 1:
                xlog.warn("query num:%d %s", len(request.questions), request)
                return

            domain = str(request.questions[0].qname)

            type = request.questions[0].qtype
            if type not in [1, 28]:
                xlog.warn("query:%s type:%d", domain, type)

            # xlog.debug("DNS query:%s type:%d from %s", domain, type, addr)

            ips = self.query(domain, type)

            reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1, auth=1), q=request.q)
            for ip_cn in ips:
                ipcn_p = ip_cn.split("|")
                ip = ipcn_p[0]
                if "." in ip and type == 1:
                    reply.add_answer(RR(domain, ttl=60, rdata=A(ip)))
                elif ":" in ip and type == 28:
                    reply.add_answer(RR(domain, rtype=type, ttl=60, rdata=AAAA(ip)))
            res_data = reply.pack()

            self.serverSock.sendto(res_data, addr)
            xlog.debug("query:%s type:%d from:%s, return ip num:%d cost:%d", domain, type, addr,
                       len(reply.rr), (time.time()-start_time)*1000)
        except Exception as e:
            xlog.exception("on_query except:%r", e)
예제 #8
0
    def switched_to(self, environment):
        rtype, current_val = self.current_value
        wanted_val = self.environments[environment]

        if set(current_val) != set(wanted_val):
            raise BespinError("The current value in ultradns is different than the specified value for this environment"
                , environment = environment
                , ultradns_has = current_val
                , specified = wanted_val
                )

        log.info("Seeing if %s has switched to %s(%s)", self.domain, environment, current_val)
        if rtype == "A":
            info = socket.getaddrinfo(self.domain, 80)
            found = [sockaddr[0] for _, _, _, _, sockaddr in info]
            if set(found) == set(current_val):
                return True
            else:
                log.info("Current value is %s", list(set(found)))

        if rtype == "CNAME":
            answer = DNSRecord.parse(DNSRecord(q=DNSQuestion(self.domain, QTYPE.CNAME)).send("8.8.8.8", 53)).short()
            if not answer:
                raise BespinError("couldn't resolve the domain", domain=self.domain)

            if answer == current_val[0]:
                return True
            else:
                log.info("Current value is %s", answer)

        return False
예제 #9
0
 def _catch_dns_answer(self, dns_request_id: int,
                       dns_socket: socket.socket):
     while True:
         raw_data, addr = dns_socket.recvfrom(4096)
         dns_query = DNSRecord.parse(raw_data)
         if dns_query.header.id == dns_request_id:
             return dns_query
예제 #10
0
    def handle(self, data, peer):
        rec = DNSRecord.parse(data)
        addrs = None
        auth = False
        if rec.q.qtype in (QTYPE.A, QTYPE.AAAA, QTYPE.ANY):
            addrs = self._registry.resolve(rec.q.qname.idna()) or set()

            if addrs:
                auth = True

                # answer AAAA queries for existing A records
                # with an successful but empty result
                if rec.q.qtype == QTYPE.AAAA:
                    addrs = None
                else:
                    log.debug("[namesrv] resolved %s to %s",
                              rec.q.qname.idna(), addrs)
            else:
                addr = self._resolve('.'.join(rec.q.qname.label))
                if addr:
                    addrs.add(addr)
                    log.debug("[namesrv] externally resolved %s to %s",
                              rec.q.qname.idna(), addrs)

            if addrs:
                addrs = list(addrs)

        self.socket.sendto(self._reply(rec, auth, addrs), peer)
예제 #11
0
파일: proxy.py 프로젝트: snipertulip/XX-Net
 def resolve(self, request, handler):
     if handler.protocol == 'udp':
         proxy_r = request.send(self.address, self.port)
     else:
         proxy_r = request.send(self.address, self.port, tcp=True)
     reply = DNSRecord.parse(proxy_r)
     return reply
예제 #12
0
    def parse(self, data):
        try:
            dns = DNSRecord.parse(data)
        except Exception as e:
            print e

        return dns
예제 #13
0
def query_server(server, packet, results, errors):
    'Query a DNS server'

    s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
    s.connect(server)

    s.send(packet)  # Forward the request to the nameserver

    # Q: Why would we ever get this big of a packet in return?
    # A: Because with IPv6, it's technically feasible
    response, addr = s.recvfrom(65535)

    try:
        data = DNSRecord.parse(response)  # Parse the response

    except Exception:
        return  # For some reason the packet was bad

    error = data.header.get_rcode()
    if error:
        errors.append(error)  # There was an error with the request
        return

    try:
        qtype = data.q.qtype
        answers = [i.rdata for i in data.rr if i.rtype == qtype]

        results.append(answers[0])  # Just add the first acceptable answer

    except IndexError:
        errors.append(3)
예제 #14
0
 def handle(self):
     request = DNSRecord.parse(self.request[0])
     socket = self.request[1]
     reply = request.reply()
     answer = self.q_processors[reply.q.qtype](reply.q.qname)
     reply.add_answer(answer)
     socket.sendto(reply.pack(), self.client_address)
예제 #15
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
예제 #16
0
def parse_udp_dns_packet(ip):
    """
    Parses UDP DNS packet.
    """
    d = DNSRecord.parse(ip.data.data)
    q = str(d.q.qname).strip(".")
    if QTYPE[
            d.q.
            qtype] == 'A' and d.header.rcode == RCODE.NOERROR and d.header.a > 0:
        fn = q
        content = ''
        for a in d.rr:
            if QTYPE[a.rtype] == "CNAME":
                q = q + " " + str(a.rdata).strip(".")
            elif QTYPE[a.rtype] == 'A':
                content = content + str(a.rdata) + " " + q + "\n"
        if content != '':
            try:
                f = open("/tmp/pitm/hostsdir/" + fn, "w")
                f.write(content)
                f.close()
            except:
                pass
            print("%s" % (fn))
    else:
        print("Skipped QTYPE %s q=%s RCODE %s Answer = %d" %
              (QTYPE[d.q.qtype], q, RCODE[d.header.rcode], d.header.a))
예제 #17
0
    def show(self):
        print("")
        self.showText("Udp Datagram", 4)
        self.showText("source \t: (port) " + str(self.src), 5)
        self.showText("destination \t: (port) " + str(self.dst), 5)

        print()
        if type(self.application) != list:
            if self.application['description'].lower() == "domain name server":
                self.showText(
                    self.application['description'] +
                    "{}".format("REQUEST" if self.dst == self.
                                application['port number'] else " RESPONSE"),
                    5)
                data = DNSRecord.parse(self.data)
                for line in str(data).split("\n"):
                    self.showText(line, 6)
            elif self.application['description'].lower(
            ) == "bootstrap protocol server":
                self.bootppacket.show()
            elif self.application['description'].lower() == "HTTPSREQUEST":
                print('we are here')
            else:
                self.showText(
                    self.application['description'] +
                    "{}".format("REQUEST" if self.dst == self.
                                application['port number'] else " RESPONSE"))
        else:
            self.showText(hexlify(self.data), 6)

        print()
        print()
예제 #18
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
예제 #19
0
    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
예제 #20
0
파일: server.py 프로젝트: kefkahacks/pupy
    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
예제 #21
0
def clean_dns(domain, verbose=True):
    target_addr = ('8.8.8.8', 53)
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    send_time = time.time()
    client.sendto(DNSRecord.question(domain).pack(), target_addr)
    client.settimeout(1)
    cnt = 0
    ret = ''
    if verbose:
        print('start to query {}'.format(domain))
    try:
        while True:
            cnt += 1
            response, _ = client.recvfrom(1024)
            recv_time = time.time()
            ret = [str(x.rdata) for x in DNSRecord.parse(response).rr if x.rtype == 1]
            if verbose:
                print(
                    '    {}th arrived, cost {}ms, response is {}'.format(cnt, int((recv_time - send_time) * 1000), ret))
    except socket.timeout as e:
        pass
    finally:
        client.close()
    if verbose:
        print('query end. result is {}'.format(ret))
    return ret
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")])

    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 "\n".join([ "  %s" % l for l in str(reply).split("\n")])

    s.sendto(reply.pack(), peer)
예제 #23
0
    def encrypt(self, raw_request, port, key):
        """
        See protocolhandler.py
        """
        data = raw_request[0].strip()
        try:
            request = DNSRecord.parse(data)
            q = request.questions[0]
            query = str(q.get_qname()).split(".")[::-1]
            if query[3] == Domains.ENCRYPT.value:
                self._send_data(request, port, Opcodes.KEY.value, key)
                self.fragments.clear()
                return 1
            elif query[3] == Domains.CONFIRM.value:
                if query[4] == Domains.ENCRYPT.value:
                    self._send_data(request, port, Opcodes.ACK.value, None)
                    self.fragments.clear()
                    return 2
            else:
                # Return back to SYNC state, will perform SYNC-REQUEST
                self.logger.debug(
                    f"{self.ip}: Client not in ENCRYPT. Falling back to SYNC")
                return 0

        except DNSError:
            self.logger.debug(f"[{self.ip}] encrypt: DNS Query Malformed")
            return 1
예제 #24
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')

        return reply
def device_finder(device_name='appletv', service_type=['_tcp'],_socket_timeout=5):
    UDP_IP="0.0.0.0"
    UDP_PORT=5353
    MCAST_GRP = '224.0.0.251'
    sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind( (UDP_IP,UDP_PORT) )

    mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

    for host in service_type:
         name = host+'.local'

         # dns = dpkt.dns.DNS('\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01')
         # print name
         # dns.qd[0].name=name
         dns_v2 = DNSRecord.parse(str('\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01').encode('utf-8'))
         dns_v2=dns_v2.question(qname=name)


         sock.sendto(dns_v2.pack(),(MCAST_GRP,UDP_PORT))
    sock.settimeout(_socket_timeout)
    out_put_final_name=None
    while out_put_final_name==None:
        out_put_final_name=_device_loop(sock, device_name)
        _socket_timeout+=1
        sock.settimeout(_socket_timeout)


    return out_put_final_name
예제 #26
0
파일: proxy.py 프로젝트: Macronut/Proxy46
 def cache(self, request, server):
     v6enable = server[1][0].find('.') == -1
     tcpenable = server[1][0] == '8.8.4.4'
     proxy_r = request.send(server[1][0],server[1][1],tcp=tcpenable,timeout=self.timeout,ipv6=v6enable)
     reply = DNSRecord.parse(proxy_r)
     save_cache(server, str(request.q.qname)[:-1], reply)
     return reply
예제 #27
0
    def switched_to(self, environment):
        rtype, current_val = self.current_value
        wanted_val = self.environments[environment]

        if set(current_val) != set(wanted_val):
            raise BespinError(
                "The current value in ultradns is different than the specified value for this environment",
                environment=environment,
                ultradns_has=current_val,
                specified=wanted_val,
            )

        log.info("Seeing if %s has switched to %s(%s)", self.domain, environment, current_val)
        if rtype == "A":
            info = socket.getaddrinfo(self.domain, 80)
            found = [sockaddr[0] for _, _, _, _, sockaddr in info]
            if set(found) == set(current_val):
                return True
            else:
                log.info("Current value is %s", list(set(found)))

        if rtype == "CNAME":
            answer = DNSRecord.parse(DNSRecord(q=DNSQuestion(self.domain, QTYPE.CNAME)).send("8.8.8.8", 53)).short()
            if not answer:
                raise BespinError("couldn't resolve the domain", domain=self.domain)

            if answer == current_val[0]:
                return True
            else:
                log.info("Current value is %s", answer)

        return False
예제 #28
0
파일: pr0cks.py 프로젝트: insertion/pr0cks
		def resolve(self,request,handler):
			if handler.protocol == 'udp':
				proxy_r = request.send(self.address,self.port)
			else:
				proxy_r = request.send(self.address,self.port,tcp=True)
			reply = DNSRecord.parse(proxy_r)
			return reply
예제 #29
0
    def handle(self, data, address):
        # parse udp datagram as dns request record
        try:
            request = DNSRecord.parse(data)
        except:
            # no real dns request, so simple close connection
            self.socket.close()
        else:
            # extract domain from dns request
            domain = str(request.get_q().get_qname())

            self.logger.debug('%s requested domain: %s' % (address, domain))

            # if that is the dns server name check
            if domain.startswith(self.proxy_ip_reversed):
                self.socket.sendto(request.reply(data="deiner Mutter").pack(), address)
                return

            # decide if mapped or not
            if self.is_mapped(domain):
                response = self.handle_mapped(domain, request)
            else:
                response = self.handle_forwarded(domain, request)

            # answer
            self.socket.sendto(response.pack(), address)
예제 #30
0
 def parse(self, data):
     """解析数据"""
     try:
         dns = DNSRecord.parse(data)
     except Exception as e:
         printRed(e)
     return dns
예제 #31
0
파일: udpchk.py 프로젝트: genzj/socks5chk
def test_udp(typ, addr, port, user=None, pwd=None, host='8.8.8.8'):
    s = socks.socksocket(
        socket.AF_INET,
        socket.SOCK_DGRAM)  # Same API as socket.socket in the standard lib
    try:
        s.set_proxy(socks.SOCKS5, addr, port, True, user,
                    pwd)  # SOCKS4 and SOCKS5 use port 1080 by default
        # Can be treated identical to a regular socket object
        # Raw DNS request
        req = b"\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x05\x62\x61\x69\x64\x75\x03\x63\x6f\x6d\x00\x00\x01\x00\x01"
        s.sendto(req, (host, 53))
        (rsp, address) = s.recvfrom(4096)
        print('packet received: ')
        print(binascii.b2a_hex(rsp))
        record = DNSRecord.parse(rsp)
        print('DNS response:')
        print(record)
        if rsp[0] == req[0] and rsp[1] == req[1]:
            print("UDP check passed")
        else:
            print("Invalid response")
    except socket.error as e:
        print('socket error')
        print(repr(e))
        raise
    except socks.ProxyError as e:
        print('proxy error')
        print(e.msg)
        raise
    except DNSError as e:
        print('DNS record parse error')
        print(e)
        raise
예제 #32
0
파일: dnsd.py 프로젝트: lmyzzu/etc
 def resolve(self, request, handler):
     try:
         proxy_r = request.send(self.address, self.port, tcp=True)
     except socket.error:
         return DNSRecord()
     reply = DNSRecord.parse(proxy_r)
     return reply
예제 #33
0
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)
예제 #34
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')

        return reply
예제 #35
0
    async def __handle_response(self, response, peer):
        """
        本地没查到,本服务做递归DNS查询,其他服务器返回的结果
        :return:
        """
        record = DNSRecord.parse(response)
        id = record.header.id

        qname = str(record.q.qname)
        qtype = record.q.qtype
        qclass = record.q.qclass

        if id not in self.peers:
            self.logger.info(
                "Unknown Response ({0:s}): {1:s} {2:s} {3:s}".format(
                    "{0:s}:{1:d}".format(*peer), CLASS.get(qclass),
                    QTYPE.get(qtype), qname))

            return

        addr = self.peers[id]
        request = self.requests[id]
        reply = request.reply()
        reply.add_answer(*record.rr)
        del self.peers[id]
        del self.requests[id]
        self.transport.sendto(reply.pack(), addr)
        self.logger.info(f"==Reply from {peer}")
예제 #36
0
    def resolve(self, request, handler):
        qname = request.q.qname
        reply = request.reply()
        # Note responses have TTL 4, as in Amazon's Dynamo DNS
        print(qname)

        if qname == 'alternator':
            ip = random.choice(livenodes)
            reply.add_answer(
                *dnslib.RR.fromZone('{} 4 A {}'.format(qname, ip)))

        # 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
예제 #37
0
파일: server.py 프로젝트: liuyug/homedns
def lookup_upstream(request, server, proxy):
    """
    use TCP mode when proxy enable
    """
    reply = None
    try:
        message = '\tForward to server %(ip)s:%(port)s(%(priority)s)' % server
        message += ' with %s mode' % ('TCP' if server['tcp'] else 'UDP')
        if server['proxy'] and proxy:
                message += ' and proxy %(type)s://%(ip)s:%(port)s' % proxy
        logger.info(message)

        r_data = sendto_upstream(
            request.pack(),
            server['ip'],
            server['port'],
            tcp=server['tcp'],
            timeout=server['timeout'],
            proxy=proxy if server['proxy'] else None,
        )
        reply = DNSRecord.parse(r_data)
        if reply.rr:
            logger.info('\tReturn from %(ip)s:%(port)s:' % server)
            bogus_rr = []
            for r in reply.rr:
                rqn = r.rname
                rqt = QTYPE[r.rtype]
                if rqt in ['A', 'AAAA'] and str(r.rdata) in globalvars.bogus_nxdomain:
                    bogus_rr.append(r)
                    logger.warn('\t*** Bogus Answer: %s(%s) ***' % (r.rdata, rqt))
                else:
                    logger.info('\t\t%s(%s)' % (r.rdata, rqt))
            if bogus_rr:
                for r in bogus_rr:
                    reply.rr.remove(r)
                hack_ip = globalvars.config['smartdns']['bogus_nxdomain']['hack_ip']
                if hack_ip:
                    rqt = 'AAAA' if ':' in hack_ip else 'A'
                    hack_r = RR(
                        rname=rqn,
                        rtype=getattr(QTYPE, rqt),
                        rclass=1, ttl=60 * 5,
                        rdata=getattr(dnslib, rqt)(hack_ip),
                    )
                    reply.rr.append(hack_r)
                reply.set_header_qa()
        else:
            logger.info('\tReturn from %(ip)s:%(port)s: \n\t\tN/A' % server)
    except socket.error as err:
        frm = '%(ip)s:%(port)s(%(priority)s)' % server
        if server['proxy']:
            frm += ' (with proxy %(ip)s:%(port)s)' % proxy
        logger.error('\tError when lookup from %s: %s' % (frm, err))
    except Exception as err:
        if logger.isEnabledFor(logging.DEBUG):
            traceback.print_exc()
        frm = '%(ip)s:%(port)s(%(priority)s)' % server
        logger.error('\tError when lookup from %s: %s' % (frm, err))
    return reply
예제 #38
0
def getRecord(host, query):
    d = DNSRecord.question(query, "A")
    check, responce = queryNode(d.pack(), (host, 53))
    try:
        record = DNSRecord.parse(responce)
        return record
    except DNSError, e:
        return False
예제 #39
0
def send_req_to_server(server_addr, name):
    client_req = DNSRecord(DNSHeader(id=ID), q=DNSQuestion(name, getattr(QTYPE, "A")))
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect((server_addr, 53))
    s.send(client_req.pack())
    resp = s.recv(2048)
    dns_resp = DNSRecord.parse(resp)
    logging.warning("Got answer from server {}".format(dns_resp))
예제 #40
0
 def handle(self, data, peer):
     rec = DNSRecord.parse(data)
     addr = None
     if rec.q.qtype in (QTYPE.A, QTYPE.AAAA):
         addr = self._registry.resolve(rec.q.qname.idna())
         if not addr:
             addr = self._resolve('.'.join(rec.q.qname.label))
     self.socket.sendto(self._reply(rec, addr), peer)
예제 #41
0
    def get_reply(self,data):
        host,port = self.server.resolver.address,self.server.resolver.port

        request = DNSRecord.parse(data)
        self.log_request(request)

        if self.protocol == 'tcp':
            data = struct.pack("!H",len(data)) + data
            response = send_tcp(data,host,port)
            response = response[2:]
        else:
            response = send_udp(data,host,port)

        reply = DNSRecord.parse(response)
        self.log_reply(reply)

        return response
예제 #42
0
 def _greenlet_runnable(self):
     while True:
         (buf, address) = self.sock.recvfrom(10240)
         try:
             record = DNSRecord.parse(buf)
         except struct.error:
             pass  # log maybe later
         else:
             self.handle(record, address)
예제 #43
0
 def finish(self):
     self.socket.sendto(self.response_packet, self.client_address)
     for answer in DNSRecord.parse(self.response_packet).rr:
         log.info(
             "client_ip: {} rname: {} rtype: {} rdata: {}".format(
                 self.client_address[0],
                 str(answer.rname).strip("."), answer.rtype, answer.rdata,
             )
         )
예제 #44
0
파일: server.py 프로젝트: amis92/dns-proxy
 def receive_and_handle(self, udpSocket):
     rlist, wlist, xlist = select.select([udpSocket], [], [], timeout)
     if not rlist:
         return
     data, addr = udpSocket.recvfrom(BUFFER_SIZE)
     request = DNSRecord.parse(data)
     self.logger.debug("handling request from '{addr}'".format(addr=addr))
     response = first_or_default(self.server.config.behaviors, request).handle(request)
     if response:
         udpSocket.sendto(response.pack(), addr)
예제 #45
0
        def get_reply(self,data):
            global dns_cache
            global args
            host,port = self.server.resolver.address,self.server.resolver.port
            request = DNSRecord.parse(data)


            domain=str(request.q.qname)
            qtype=str(QTYPE.get(request.q.qtype))
            index=domain+"/"+qtype
            if not args.no_cache and index in dns_cache:
                if time.time()<dns_cache[index][0]:
                    if args is not None and args.verbose:
                        try:
                            display("[i] %s served value from cache: %s"%(index, ', '.join([x.rdata for x in dns_cache[index][1]])))
                        except:
                            pass
                    rep=request.reply()
                    rep.add_answer(*dns_cache[index][1])
                    return rep.pack()
            if args is not None and args.verbose:
                display("[i] domain %s requested using TCP server %s"%(domain, args.dns_server))
            data = struct.pack("!H",len(data)) + data
            response = send_tcp(data,host,port)
            response = response[2:]
            reply = DNSRecord.parse(response)
            if args.verbose:
                try:
                    display("[i] %s %s resolve to %s"%(domain, qtype, ', '.join([x.rdata for x in reply.rr])))
                except:
                    pass
            ttl=3600
            try:
                ttl=reply.rr[0].ttl
            except Exception:
                try:
                    ttl=reply.rr.ttl
                except Exception:
                    pass
            dns_cache[index]=(int(time.time())+ttl, reply.rr)
            if len(dns_cache)>DNS_CACHE_SIZE:
                dns_cache.popitem(last=False)
            return response
예제 #46
0
def send_req_and_print_resp(packet, port):
    sock = socket(AF_INET, SOCK_DGRAM)
    sock.sendto(packet, ("localhost", port))
    resp = sock.recv(2048)

    print("Client got response:")
    try:
        print(DNSRecord.parse(resp))
    except DNSError:
        print(resp)
    sock.close()
예제 #47
0
파일: middlewares.py 프로젝트: vognev/dhns
 def handle_dns_packet(self, query: DNSRecord, answer: DNSRecord):
     if query.q.qname.matchSuffix(self.suffix):
         try:
             local_a = DNSRecord.parse(query.send(self.address, port=self.port))
             for rr in local_a.rr:
                 answer.add_answer(rr)
             return True
         except:
             pass
         finally:
             return True
예제 #48
0
파일: udp_server.py 프로젝트: vognev/dhns
 def process(self):
     with self._lock:
         buf, addr = self._sock.recvfrom(512)
     try:
         query = DNSRecord.parse(buf)
         print("DNS Q %s FROM: %s:%d" % (query.q.qname, addr[0], addr[1]))
         answer = self._handler.handle(query)
         with self._lock:
             self._queue.append((addr, answer))
     except Exception as e:
         traceback.print_exc()
예제 #49
0
파일: proxy.py 프로젝트: Macronut/Proxy46
 def map46(self, request, server):
     v6enable = server[1][0].find('.') == -1
     request.q.qtype = DNS_AAAA_RECORD
     temp_proxy_r = request.send(server[1][0], server[1][1], timeout=self.timeout, ipv6=v6enable)
     temp_reply = DNSRecord.parse(temp_proxy_r)
     iplist = map_ip(server, str(request.q.qname)[:-1], temp_reply)
     request.q.qtype = DNS_A_RECORD
     reply = request.reply()
     for ip in iplist:
         reply.add_answer(RR(rname=request.q.qname, rtype=request.q.qtype, rclass=1, ttl=TTL, rdata=A(ip)))
     return reply
예제 #50
0
파일: dns_server.py 프로젝트: zhao-ji/gecko
    def request_upstream_DNS(self):
        log.info("request the upstream DNS")
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.connect((self.selected_DNS, 53))
        sock.send(self.packet)
        response_packet = sock.recv(1024)
        self.wfile.write(response_packet)

        cache_key = "cache:{}:{}".format(self.qtype, self.qname)
        response_parse_ret = DNSRecord.parse(response_packet)
        cache_db.setex(
            cache_key, RECORD_CACHE_TIME, dumps(response_parse_ret.rr))
예제 #51
0
def handleDatagram(udp):
    ((src, sport), (dst, dport)) = udp.addr
    if sport != 53 and dport != 53:
        #chop.tsprnt("STOP: %s:%s->%s:%s (%i:%i)" % (src, sport, dst, dport, len(udp.data), len(udp.ip)))
        udp.stop()
        return

    try:
        o = DNSRecord.parse(udp.data)
    except KeyError, e:
        chop.prnt("Key error: %s" % str(e))
        return
예제 #52
0
    def resolve(self, request, handler):
        global OPTIONS

        queue = Queue.Queue()

        reply = None
        for i in range(OPTIONS.retry):
            for addr in self.addresses:
                request2 = copy.deepcopy(request)

                encrypted = addr[0][:1] in ["x", "X"]
                if encrypted:
                    addr = (addr[0][1:],) + addr[1:]
                    EncryptDNSRecord(request2)

                def put(request, encrypted, *send_args, **send_kwargs):
                    try:
                        if self.request_bind_address:
                            result = request_send(request, *send_args, \
                                                  bind_address = \
                                                  self.request_bind_address, \
                                                  **send_kwargs)
                        else:
                            result = request.send(*send_args, **send_kwargs)
                    except socket.timeout:
                        pass
                    else:
                        queue.put((encrypted, result))

                t = Thread(target = put, \
                           args = (request2, encrypted,) + addr, \
                           kwargs = {"timeout": OPTIONS.timeout})
                t.daemon = True
                t.start()

            for _ in self.addresses:
                try:
                    encrypted, r = queue.get(timeout = OPTIONS.timeout)
                except Queue.Empty:
                    continue

                reply = DNSRecord.parse(r)
                if encrypted:
                    EncryptDNSRecord(reply)

                if IsAcceptable(reply):
                    return reply

        if not reply:
            raise DNSError("No reply received for the request")

        return reply
예제 #53
0
 def handle(self, data, peer):
     rec = DNSRecord.parse(data)
     addr = None
     if rec.q.qtype in (QTYPE.A, QTYPE.AAAA):
         log.debug('Quering DNS')
         addr = self._registry.resolve(rec.q.qname.idna())
         if not addr:
             strArr = []
             for l in rec.q.qname.label:
                 strArr.append(str(l,'utf-8'))
             domainName = '.'.join(strArr)
             addr = self._resolve(domainName)
     log.debug('Sending request to %s', addr)
     self.socket.sendto(self._reply(rec, addr), peer)
예제 #54
0
    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()
예제 #55
0
    def resolve(self,request,handler):
        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
예제 #56
0
파일: server.py 프로젝트: liuyug/homedns
def dns_response(handler, data):
    try:
        request = DNSRecord.parse(data)
    except Exception as err:
        logger.error('Parse request error: %s' % err)
        return
    qn = request.q.qname
    qt = QTYPE[request.q.qtype]
    logger.debug('\n' + str(request))

    local = False
    if 'local' in globalvars.config['server']['search']:
        local = lookup_local(handler, request)
    if local:
        logger.warn('\tRequest "%s(%s)" is in "local" list.' % (qn, qt))
    elif 'upstream' in globalvars.config['server']['search']:
        proxy = globalvars.config['smartdns']['proxy']
        qn2 = str(qn).rstrip('.')
        for name, param in globalvars.rules.items():
            if param['rule'].isBlock(qn2):
                logger.warn('\tRequest "%s(%s)" is in "%s" list.' % (qn, qt, name))
                best_dns = None
                servers = []
                for group in param['upstreams']:
                    servers.extend(globalvars.upstreams[group])
                for server in servers:
                    if best_dns is None:
                        best_dns = server
                    elif best_dns['priority'] < server['priority']:
                        best_dns = server
                reply = lookup_upstream(request, best_dns, proxy)
                if reply:
                    best_dns['priority'] += (5 if best_dns['priority'] < 100 else 0)
                    logger.debug('\n' + str(reply))
                    handler.send_data(reply.pack())
                else:
                    best_dns['priority'] += (-10 if best_dns['priority'] > 0 else -1)
                # only use first matching rule
                break
    # update
    for value in globalvars.rules.values():
        rule = value['rule']
        if rule.isNeedUpdate(value['refresh']):
            rule.async_update()
    for value in globalvars.local_domains.values():
        domain = value['domain']
        if domain.isNeedUpdate(value['refresh']):
            domain.async_update()
예제 #57
0
 def resolve(self,request,handler):
     reply = request.reply()
     qname = request.q.qname
     qtype = QTYPE[request.q.qtype]
     if qname.matchGlob("api-*padsv.gungho.jp."):
         host = self.hostaddr
         reply.add_answer(RR(qname,QTYPE.A,rdata=A(host)))
         self.onDNSEvent(str(qname)[:-1])
         time.sleep(0.5) # we need to sleep until the proxy is up, half a second should do it...
     # Otherwise proxy
     if not reply.rr:
         if handler.protocol == 'udp':
             proxy_r = request.send(self.address,self.port)
         else:
             proxy_r = request.send(self.address,self.port,tcp=True)
         reply = DNSRecord.parse(proxy_r)
     return reply