难点在于DNS server的搭建,然而非常简单,安装dnslib就有DNS server:zoneresolver.py,稍作修改即可使用
# -*- coding: utf-8 -*- from __future__ import print_function import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dj_apache.settings") import django django.setup() import copy import re from dnslib import RR,QTYPE,RCODE from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger from logview.models import * class MysqlLogger(): def log_data(self, dnsobj): pass def log_error(self, handler, e): pass def log_pass(self, *args): pass def log_prefix(self, handler): pass def log_recv(self, handler, data): pass def log_reply(self, handler, reply): pass def log_request(self, handler, request): domain = request.q.qname.__str__() if domain.endswith('dnslog.ml.'): udomain = re.search(r'\.([^\.]+)\.dnslog\.ml\.',domain) if udomain: user = User.objects.filter(udomain__exact=udomain.group(1)) if user: dnslog = DNSLog(user=user[0],http_host=domain,type=QTYPE[request.q.qtype]) dnslog.save() def log_send(self, handler, data): pass def log_truncated(self, handler, reply): pass class ZoneResolver(BaseResolver): """ Simple fixed zone file resolver. """ def __init__(self,zone,glob=False): """ Initialise resolver from zone file. Stores RRs as a list of (label,type,rr) tuples If 'glob' is True use glob match against zone file """ self.zone = [(rr.rname,QTYPE[rr.rtype],rr) for rr in RR.fromZone(zone)] self.glob = glob self.eq = 'matchGlob' if glob else '__eq__' def resolve(self,request,handler): """ Respond to DNS request - parameters are request packet & handler. Method is expected to return DNS response """ reply = request.reply() qname = request.q.qname qtype = QTYPE[request.q.qtype] for name,rtype,rr in self.zone: # Check if label & type match if getattr(qname,self.eq)(name) and (qtype == rtype or qtype == 'ANY' or rtype == 'CNAME'): # If we have a glob match fix reply label if self.glob: a = copy.copy(rr) a.rname = qname reply.add_answer(a) else: reply.add_answer(rr) # Check for A/AAAA records associated with reply and # add in additional section if rtype in ['CNAME','NS','MX','PTR']: for a_name,a_rtype,a_rr in self.zone: if a_name == rr.rdata.label and a_rtype in ['A','AAAA']: reply.add_ar(a_rr) if not reply.rr: reply.header.rcode = RCODE.NXDOMAIN return reply if __name__ == '__main__': import argparse,sys,time p = argparse.ArgumentParser(description="Zone DNS Resolver") p.add_argument("--zone","-z",required=True, metavar="<zone-file>", help="Zone file ('-' for stdin)") p.add_argument("--port","-p",type=int,default=53, metavar="<port>", help="Server port (default:53)") p.add_argument("--address","-a",default="", metavar="<address>", help="Listen address (default:all)") p.add_argument("--glob",action='store_true',default=False, help="Glob match against zone file (default: false)") p.add_argument("--udplen","-u",type=int,default=0, metavar="<udplen>", help="Max UDP packet length (default:0)") args = p.parse_args() if args.zone == '-': args.zone = sys.stdin else: args.zone = open(args.zone) resolver = ZoneResolver(args.zone,args.glob) logger = MysqlLogger() print("Starting Zone Resolver (%s:%d) [%s]" % ( args.address or "*", args.port, "UDP")) for rr in resolver.zone: print(" | ",rr[2].toZone(),sep="") print() if args.udplen: DNSHandler.udplen = args.udplen udp_server = DNSServer(resolver, port=args.port, address=args.address, logger=logger) udp_server.start()
zone.txt
*.dnslog.ml. IN NS ns1.howmp.com. *.dnslog.ml. IN NS ns2.howmp.com. *.dnslog.ml. IN A 106.186.118.146
使用命令python zoneresolver.py --zone zone.txt --glob 即可启动server
其中在log_request中加入自己的处理逻辑即可