[python网络编程]DNSserver
在上一篇中,使用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,有兴趣的童鞋一起完好。
[python网络编程]DNSserver的更多相关文章
- Python 网络编程(二)
Python 网络编程 上一篇博客介绍了socket的基本概念以及实现了简单的TCP和UDP的客户端.服务器程序,本篇博客主要对socket编程进行更深入的讲解 一.简化版ssh实现 这是一个极其简单 ...
- Python 网络编程(一)
Python 网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...
- Python学习(22)python网络编程
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
- Day07 - Python 网络编程 Socket
1. Python 网络编程 Python 提供了两个级别访问网络服务: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口 ...
- python网络编程-01
python网络编程 1.socket模块介绍 ①在网络编程中的一个基本组件就是套接字(socket),socket是两个程序之间的“信息通道”. ②套接字包括两个部分:服务器套接字.客户机套接字 ③ ...
- 《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档
Foundations of Python Network Programing,Third Edition <python网络编程>,本书中的代码可在Github上搜索fopnp下载 本 ...
- Python网络编程基础pdf
Python网络编程基础(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1VGwGtMSZbE0bSZe-MBl6qA 提取码:mert 复制这段内容后打开百度网盘手 ...
- python 网络编程(Socket)
# from wsgiref.simple_server import make_server## def RunServer(environ,start_response):# start_resp ...
- python 网络编程 IO多路复用之epoll
python网络编程——IO多路复用之epoll 1.内核EPOLL模型讲解 此部分参考http://blog.csdn.net/mango_song/article/details/4264 ...
随机推荐
- MySql连接异常解决
这两天遇到一个mysql连接的问题,找人弄了好几天也没弄好,先看一下报错信息: ============================================================ ...
- python,redis简单订阅
python连接redis import redis r =redis.Redis(host='192.168.199.11',port = 6379 ,db = 0) r.publish('chan ...
- JavaScript 鸭子模型
Javascript:由 “鸭子类型” 得出来的推论 背景 学动态语言的都知道一句话:“如果它走起来像鸭子,而且叫起来像鸭子,那么它就是鸭子”,Javascript也支持鸭子类型,下文就说说鸭子类型在 ...
- 关于Android Launcher图标上面动态改变数字的实现
由于项目需要使用到类似小米应用商店的图标数字提示功能,谷歌百度了许多文章都没看到有真正意义上的实现(没有在国外网站上搜索),有实现在APP内部的一个ImageView上面更新数字的,当然这种太简单无非 ...
- SSD的优势
谈过SSD的发展历史后,现在我们来讲解下SSD相比传统HDD(机械硬盘)的优势. 相信很多读者只要有听说过SSD,必定都会听到对SSD优点的一个字总结:快! 但这一个字要如何去理解呢?很多人可能还不太 ...
- 使用vi编辑binary文件
原理:使用xxd将当前文件转成hex格式,编辑,然后再转回去 /usr/bin/xxd xxd - make a hexdump or do the reverse 例子: 用binary模式启动vi ...
- Oracle 局域网布置数据库服务器,客户端连接提示TNS:无监听器的解决实现
Oracle布置在局域网中的服务器的时候,用本地PL SQL 链接没有丝毫的问题. 但是,如果用远程客户端的PL SQL 链接的时候却出现了“TNS:无监听器”的问题. 首先,就是进行了服务器端的监听 ...
- Android适配器Adapter学习
在开发中我们需要绑定一些数据展现到桌面上,这是就需要AdapterView.AdapterView是ViewGroup的子类,它决定了怎么展现视图通过Adapter来绑定特殊的数据类型. Adapte ...
- popupwindow 模拟新浪、腾讯title弹框效果
.jpg外部引用 原始文档 MainActivity.java外部引用 原始文档 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...
- Python BeautifulSoup4 使用指南
前言: 昨天把传说中的BeautifulSoup4装上了,还没有装好的童鞋,请看本人的上一篇博客: Python3 Win7安装 BeautifulSoup,依照里面简单的步骤就能够把Beautifu ...