博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[python网络编程]DNSserver
阅读量:5989 次
发布时间:2019-06-20

本文共 3372 字,大约阅读时间需要 11 分钟。

在上一篇中,的最后我们提到因为hosts文件不支持正则,会导致我们的随机域名DNS查询失败。

使用DNS代理服务器能够解决问题,

以下是我用gevent写的小工具。非常easy。我们仅仅拦截匹配的A记录。然后发送DNS Response,假设不匹配,那么我们服务器就是一个DNS代理,转发请求。

# -*- coding=utf-8 -*-import structfrom cStringIO import StringIOfrom collections import namedtuplefrom gevent import socketfrom gevent.server import DatagramServerHex = lambda x : '0x{0:04x}'.format(x) # Hex(256) => "0x0100"QueryResult = namedtuple("DnsQuery",                 "transactionID,flags,questions,answerRrs \                 authorityRrs,additionalRrs,qname,qtype,qclass")LOCALDNS = ("114.114.114.114",53)Hosts = {    "*.ttt.com":"173.194.127.144", # google ip}def preg_match(preg,real):    """    only support '*'    >>>preg_match("www.*.test*.com","www.python.test.com")    True    >>>preg_match("www.*.test*.com","www.python.tes.com")    False    """    pre = 0    for s in preg.split('*'):        now = real.find(s)        if now < pre:            return False        pre = now +len(s)    return Truedef udp_send(address,data):    sock = socket.socket(type=socket.SOCK_DGRAM)    sock.connect(address)    sock.send(data)    response, address = sock.recvfrom(8192*4)    return response,addressclass DnsParser:        @classmethod    def parseQuery(self,query):        """               6a 02 01 00 00 01                         j.....        00 00 00 00 00 00 03 77 77 77 03 61 61 61 03 63  .......www.aaa.c        6f 6d 00 00 01 00 01                             om.....        dns query package like above        03 77 77 77 : three www        """        transactionID,flags,questions,answerRrs,authorityRrs,additionalRrs = map(Hex,struct.unpack("!6H",query[:12]))        quries = StringIO(query[12:])        c = struct.unpack("!c",quries.read(1))[0]        domain = []        while  c != '\x00':            n = ord(c)            domain.append(''.join(struct.unpack("!%sc" % n,quries.read(ord(c)))))            c = struct.unpack("!c",quries.read(1))[0]        domain = '.'.join(domain)        qtype,qclass = map(Hex,struct.unpack("!2H",quries.read()))        return QueryResult(transactionID,flags,questions,answerRrs,                            authorityRrs,additionalRrs,domain,qtype,qclass)    @classmethod    def generateReqponse(self,queryData,ip):        """        only support ipv4        """        return ''.join([queryData[:2],"\x81\x80\x00\x01\x00\x02\x00\x00\x00\x00",          queryData[12:],"\xc0\x0c","\x00\x01","\x00\x01","\x00\x00\x00\x1e","\x00\x04",          struct.pack('BBBB',*map(int,ip.split('.')))          ])class DnsServer(DatagramServer):    def handle(self,data,address):        query = DnsParser.parseQuery(data)        print "get dns query from %s,query:%s" %(str(address),str(query))        find = False        for preg,ip in Hosts.iteritems():            if preg_match(preg,query.qname):                find = True                break        if find and query.qtype == "0x0001": #only handle A record            print 'domain:%s in hosts' % query.qname            response = DnsParser.generateReqponse(data,ip)            self.socket.sendto(response,address)        else:            print 'transfer for %s' % query.qname            response,serveraddress = udp_send(LOCALDNS,data)            self.socket.sendto(response,address)if __name__ == "__main__":    DnsServer("192.168.9.178:53").serve_forever()

哈哈,刚好100行,不得不说python的强大。

来个截图:

功能有限。各位童鞋能够扩展,代码已经放到github,,有兴趣的童鞋一起完好。

你可能感兴趣的文章
常见的web网络攻击处理方案
查看>>
web 性能优化的一些方法
查看>>
基于vue + nuxt 打造 o2o教育商城系统(触屏版) 服务端渲染SSR
查看>>
——————【 正则表达式 】——————
查看>>
HTTP你可能还不知道的事。
查看>>
前端每周清单半年盘点之 Angular 篇
查看>>
Redis GEO 特性在 LBS 中的应用总结
查看>>
尝试在JavaScript中构建一个"Maybe"检测器
查看>>
SSM(SpringMVC|Spring|MyBatis的整合)
查看>>
Javascript 从异步函数到 Promise 到 Async/Await
查看>>
【译】log4j介绍
查看>>
vue集成raphael.js中国地图
查看>>
es6模块化编程
查看>>
一道关于javascript数据类型题目的思考
查看>>
ECSHOP 二次开发
查看>>
function作为构造函数和非构造函数调用的区别
查看>>
基于 Python 的简单自然语言处理实践
查看>>
测量资源加载时间 | chrome开发者工具
查看>>
css 四分之三的圆的实现
查看>>
swift cocoapods 我的安装之旅
查看>>