Attachment 'qns.py'

Download

   1 #!/usr/bin/env python
   2 import sys
   3 import time
   4 import datetime
   5 import threading
   6 import traceback
   7 import SocketServer
   8 from sets import Set
   9 
  10 import dnslib
  11 from dnslib import QTYPE, SOA, NS, A, AAAA, MX, CNAME
  12 from dnslib import DNSRecord, DNSHeader, RR, RCODE
  13 
  14 IP= '192.168.10.7'
  15 TTL = 60 * 5
  16 PORT = 5053
  17 
  18 #---------------- read zone -----------------------
  19 zone = {}  #Dict;  key is a domain name
  20           #value: Dict for rtype
  21                # value: RRSet
  22 cuts = Set([])  # delegation point; Set
  23 
  24 # ---- open zone data -------
  25 zonetxt = open('zone.txt').read()
  26 #print(zonetxt)
  27 
  28 z = '' # zone name
  29 for rr in RR.fromZone(zonetxt):
  30   name = str(rr.rname)
  31   if not(name in zone) :  #new name
  32      zone[name] = {}   # make empty node
  33   elif rr.rtype == QTYPE.CNAME :
  34      print 'CNAME error', zone[name], rr
  35 
  36   if QTYPE.CNAME in zone[name]: # CNAME exists
  37      print 'CNAME error', zone[name], rr
  38   if not(rr.rtype in zone[name]):  # new rtype -> rrset
  39      zone[name][rr.rtype] = Set([])  # empty query type
  40   zone[name][rr.rtype].add(rr)
  41 
  42   if rr.rtype == QTYPE.SOA :
  43     if z == '':
  44        z = name
  45        print 'SOA == ', z, zone[name]
  46     else :
  47       print 'SOA duplicate ', z, name
  48 
  49 if len(z)==0 :
  50    print 'No zone found'
  51    exit
  52 
  53 zsuffix = '.'+ z
  54 #----- remove out of zone name ------
  55 for name in zone:
  56   if not (name== z or name.endswith(zsuffix)) : 
  57      delete(zone[name])
  58      print 'Out of zone record',
  59   print name, (zone[name])
  60 
  61 rrs = zone[z]  # zone apex node
  62 if QTYPE.SOA in rrs:
  63    soa_record = rrs[QTYPE.SOA].copy().pop()
  64    ns_record = rrs[QTYPE.NS]
  65 
  66 print '---- zone apex record ----'
  67 print zone[z]
  68 print '-----'
  69 print 'SOA = ',soa_record 
  70 print 'NS = ', ns_record 
  71 
  72 #  delegation list 
  73 for name in zone:
  74   if name == z : continue
  75   if QTYPE.NS in zone[name]:
  76      cuts.add(name)
  77      print 'cut found: ', name
  78 print 'cuts =', cuts
  79 
  80 print '-------- Zone processed ---------'
  81 
  82 #------  zone server ---------
  83 IP= '192.168.10.7'
  84 TTL = 60 * 5
  85 PORT = 5053
  86 ServerIP = '192.168.10.7'
  87 
  88 def dns_response(packet):
  89     query = DNSRecord.parse(packet)
  90     print '--- query ---' 
  91     print query
  92     print '------------'
  93 
  94     reply = DNSRecord(DNSHeader(id=query.header.id, qr=1, aa=1), q=query.q)
  95     reply  #debug print
  96     qname = query.q.qname
  97     qtype = query.q.qtype
  98     qt = QTYPE[qtype]
  99     qn = str(qname).lower()
 100 
 101     if qn in zone :
 102        print zone[qn]
 103        if qtype in zone[qn]:
 104          for rr in zone[qn][qtype]: #rrset
 105 	   print 'found RRSet', rr
 106            reply.add_answer(rr) # answer RRSet
 107        elif (QTYPE.CNAME in zone[qn]) :
 108             print 'CNAME found. ---', zone[qn][QTYPE.CNAME]
 109 	    for rr in zone[qn][QTYPE.CNAME]:
 110        	      reply.add_answer(RR(qname, QTYPE.CNAME, ttl=TTL, rdata=rr.rdata))
 111 
 112        #    reply.add_answer(RR(qname, QTYPE.NS, ttl=TTL, rdata=rdata)
 113        else: #NoData response here
 114             reply.add_auth(soa_record)
 115 
 116     else:  # NXDomain
 117        if not (qn.endswith('.' + z)): return
 118        reply.add_auth(soa_record)
 119        #NoData response here may be
 120        reply.header.rcode = getattr(RCODE,'NXDOMAIN')
 121 
 122     print "---- Reply:\n", reply
 123     return reply.pack()
 124 
 125 #---------------------------------------------------------
 126 class BaseRequestHandler(SocketServer.BaseRequestHandler):
 127 
 128     def get_data(self):
 129         raise NotImplementedError
 130 
 131     def send_data(self, data):
 132         raise NotImplementedError
 133 
 134     def handle(self):
 135         now = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
 136         print "\n\n%s request %s (%s %s):" % (self.__class__.__name__[:3], now, self.client_address[0],
 137                                                self.client_address[1])
 138         try:
 139             data = self.get_data()
 140             print len(data), data.encode('hex')  # repr(data).replace('\\x', '')[1:-1]
 141             self.send_data(dns_response(data))
 142         except Exception:
 143             traceback.print_exc(file=sys.stderr)
 144 
 145 
 146 class UDPRequestHandler(BaseRequestHandler):
 147 
 148     def get_data(self):
 149         return self.request[0].strip()
 150 
 151     def send_data(self, data):
 152         return self.request[1].sendto(data, self.client_address)
 153 
 154 
 155 if __name__ == '__main__':
 156     print "Starting nameserver..."
 157 
 158     servers = [
 159         SocketServer.ThreadingUDPServer((ServerIP, PORT), UDPRequestHandler),
 160        # SocketServer.ThreadingTCPServer((ServerIP, PORT), TCPRequestHandler),
 161     ]
 162     for s in servers:
 163         thread = threading.Thread(target=s.serve_forever)  # that thread will start one more thread for each request
 164         thread.daemon = True  # exit the server thread when the main thread terminates
 165         thread.start()
 166         print "%s server loop running in thread: %s" % (s.RequestHandlerClass.__name__[:3], thread.name)
 167 
 168     try:
 169         while 1:
 170             time.sleep(1)
 171             sys.stderr.flush()
 172             sys.stdout.flush()
 173 
 174     except KeyboardInterrupt:
 175         pass
 176     finally:
 177         for s in servers:
 178             s.shutdown()

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2020-08-12 06:11:31, 4.8 KB) [[attachment:qns.py]]
  • [get | view] (2020-08-12 06:11:31, 4.7 KB) [[attachment:zone.py]]
  • [get | view] (2020-08-12 06:11:31, 0.3 KB) [[attachment:zone.txt]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.