在上一篇中,使用scrapy改动源IP发送请求的最后我们提到因为hosts文件不支持正则,会导致我们的随机域名DNS查询失败。

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

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

# -*- coding=utf-8 -*-
import struct
from cStringIO import StringIO
from collections import namedtuple
from gevent import socket
from gevent.server import DatagramServer Hex = 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 True def 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,address class 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的强大。

来个截图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlZ3VhbmdoYWlkYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

功能有限。各位童鞋能够扩展,代码已经放到github,https://github.com/Skycrab/PyDnsProxy,有兴趣的童鞋一起完好。

最新文章

  1. SQL Server 索引
  2. PPP(杜撰)
  3. IOS-委托代理(degegate)
  4. Matlab 霍夫变换 ( Hough Transform) 直线检测
  5. 保持查询语法指示的联接顺序Option(Force order)
  6. 图片放大缩小(和ViewPager配合使用流畅显示)--第三方开源--PhotoView
  7. WPF之小动画三
  8. 在ASP.NET中各种跳转控制
  9. Zookeeper集群安装详解
  10. html行内元素 和 块状元素 总结
  11. HDU 6200 2017沈阳网络赛 树上区间更新,求和
  12. 本博客由CSDN迁移而来,显示不正常的博文会慢慢修复!
  13. 复习上学期的HTML+CSS(1)
  14. Java垃圾回收器的工作原理
  15. 【Java并发.2】线程安全性
  16. Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。
  17. MySQL性能调优的10个方法 - mysql数据库栏目
  18. Android BLE蓝牙详细解读
  19. sql in语句
  20. java中使用jdbc配置连接串时mysql 5.6与5.7版本“编码”参数有区别!

热门文章

  1. Python的maketrans() 方法
  2. “-Xmx1024m -Xms1024m -Xmn512m -Xss256k”——Java运行参数(转)
  3. 一起来看看css中的单位
  4. android小知识之SparseArray(HaspMap替换)
  5. 微信平台BAE
  6. 专访CEO何朝曦:深信服高速成长的秘诀
  7. BZOJ 1101 [POI2007]Zap(莫比乌斯反演)
  8. 《Linux内核设计与实现》内存管理札记
  9. Android 动画animation 深入分析
  10. sublime test3 使用技巧