[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 ...
随机推荐
- 小鱼提问2 属性访问器中get,set再用public修饰行吗,private呢?
/// <summary> /// 是否有一个用户正在连接服务器中 /// </summary> public bool IsConnectting { get { retur ...
- linux install nginx error
1 2 3 4 5 6 7 8 9 10 11 [mahao01@127.0.0.1 nginx-1.2.9]$ make make -f objs/Makefile make[1]: Enterin ...
- R与数据分析旧笔记(八)多重共线性
多重共线性(线性代数叫线性相关) 多重共线性(线性代数叫线性相关) 1.什么是多重共线性 2.多重共线性对回归模型的影响 3.利用计算特征根发现多重共线性 4.Kappa()函数 例题1 考虑一个有六 ...
- ffmpeg用法
1. help ffmpeg.exe -h > help.txt 2. 解码: ffmpeg -i 123.264 123.yuv ffmpeg -i 123.264 -vframes 200 ...
- linux内核升级图文攻略
Linux内核概览 Linux是一个一体化内核(monolithic kernel)系统. 设备驱动程序可以完全访问硬件. Linux内的设备驱动程序可以方便地以模块化(modularize)的形式设 ...
- Codeforces 430B Balls Game(Two Pointers)
[题目链接] http://codeforces.com/contest/430/problem/B [题目大意] 祖玛游戏,给出一个序列,表示祖玛球的颜色序列,三个或者以上的球碰在一起就会发生消除, ...
- TerminateThread函数学习
终结一个线程. BOOL WINAPI TerminateThread( _Inout_ HANDLE hThread, _In_ DWORD dwExitCode ); Parameter ...
- UIImageView图片视图的基本概念和使用方法
IOS学习笔记(十)之UIImageView图片视图的基本概念和使用方法(博客地址: http://blog.csdn.net/developer_jiangqq ) Author:hmjiangqq ...
- compass安装教程
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 简单的web三层架构系统【第一版】
SQLhelper助手类编写: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using Sys ...