[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 ...
随机推荐
- hdu 4455 Substrings(找规律&DP)
Substrings Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- 一周学会Mootools 1.4中文教程:(6)动画
先看一下动画的参数设置: 参数: fps - (number:默认是50) 每秒的帧数. unit - (string:默认是 false) 单位,可为 'px','em',或 '%'. link - ...
- SSE && WebSockets
SSE && WebSockets 参考 http://www.bitscn.com/school/HTMLCSS/201402/194940.html WebSockets 定义了一 ...
- XSS CSRF
XSS CSRF XSS 参考 https://zh.wikipedia.org/wiki/%E8%B7%A8%E7%B6%B2%E7%AB%99%E6%8C%87%E4%BB%A4%E7%A2%BC ...
- 批处理[Batch]
批处理 1. 定义:就是一堆DOS命令按一定顺序排列而形成的集合. 英文译为BATCH,批处理文件后缀BAT就取的前三个字母. 示例1:a.bat @echo off Netstat –a –n &g ...
- SQL Server 中同时操作的例子:
在SQL 中同一逻辑阶段的操作是同时发生的. 先有一个例子做为带入: declare @x as int =1;declare @y as int =2;set @x=@y;set @y=@x;sel ...
- nat123外网SSH访问内网LINUX的N种方法
一,动态公网IP环境 1,环境描述: 路由器分配的是动态公网IP,且有路由管理权限,LINUX主机部署在路由内网.如何实现外网SSH访问内网LINUX主机? 2,解决方案: 使用nat123动态域名解 ...
- How to choose between zombie.js and PhantomJS for automated web testing? [closed]
How to choose between zombie.js and PhantomJS for automated web testing? [closed] How to choose betw ...
- Codeforces Round #242 (Div. 2) <A-D>
CF424 A. Squats 题目意思: 有n(n为偶数)个x和X,求最少的变换次数,使得X的个数为n/2,输出变换后的序列. 解题思路: 统计X的个数ans,和n/2比較,少了的话,须要把n/2- ...
- ANDROID对文件的操作
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.Inp ...