因为平时在测试DNS的时候有些操作手动完成不方便,所以需要用到脚本,而在Python里dnspython这个用于DNS操作的库十分强大,但是无奈网上大部分资料只列举了少部分的用法,所以记录一下我平时使用到的功能,基本上已经能应付大部分的使用场景了。想具体了解dnspython可以登录官方网站阅读使用文档.
常用工具
最常用的用法是调用默认的resolver发送解析请求,如
from dns import resolverans = resolver.query("www.baidu.com", "A") print("qname:",ans.qname) print ("reclass:",ans.rdclass) print ("rdtype:",ans.rdtype) print ("rrset:",ans.rrset) print ("response:",ans.response)
结果为
('qname:', <DNS name www.baidu.com.>) ('reclass:', 1) ('rdtype:', 1) ('rrset:', <DNS www.a.shifen.com. IN A RRset>) ('response:', <DNS message, ID 64940>)
在这里解析任务默认发送给系统默认的dns服务器,其中比较重要的是response,在dnspython的官方文档里,response属于类dns.message.Message,这个类也是许多DNS query请求的返回结果,下面详细介绍下这个类。
类的主要成员变量有:
int flags #The DNS flags of the message. int id #The query id; the default is a randomly chosen id. list of RRset addictional list of RRset answer list of RRset authority
flags属于返回DNS报文的标志位(详见《TCP/IP详解(卷一)》关于DNS的部分),可以利用以下代码打印DNS报文的各个标志位:
#!/bin/env python2.7 ans = resolver.query("www.baidu.com", "A")def FlagCount(flags, pos):if (flags/(2**pos))%2 == 1:return Trueelse:return Falsedef GetFlags(flags):QR_pos = 15AA_pos = 10TC_pos = 9RD_pos = 8RA_pos = 7QR_flag = FlagCount(flags, QR_pos)AA_flag = FlagCount(flags, AA_pos)TC_flag = FlagCount(flags, TC_pos)RD_flag = FlagCount(flags, RD_pos)RA_flag = FlagCount(flags, RA_pos)flag_dic = {"QR":QR_flag, "AA":AA_flag, "TC":TC_flag, "RD":RD_flag, "RA":RA_flag}print "flag:",for flag in flag_dic:if flag_dic[flag]:print flag,flags = ans.response.flagsGetFlags(flags)
返回结果为:
flag: AA RD QR RA
另外一个比较重要的类就是RRset,通常返回的三个section信息都使用这个类封装,常用的用法是使用类函数to_text()令解析结果以字符串形式显示。如:
ans = resolver.query("www.baidu.com", "A") for i in ans.response.answer:print i.to_text()
结果为:
www.baidu.com. 1200 IN CNAME www.a.shifen.com. www.a.shifen.com. 119 IN A 220.181.112.244 www.a.shifen.com. 119 IN A 220.181.111.188
使用实例:
A记录查询
#!/usr/bin/env python import dns.resolver domain = raw_input('Please input an domain: ') A = dns.resolver.query(domain, 'A')for i in A.response.answer:for j in i.items:print j.address
MX记录查询(注意输入域名不包括www)
#!/usr/bin/env python import dns.resolver domain = raw_input('Please input an domain: ') MX = dns.resolver.query(domain, 'MX') for i in MX:print 'MX preference =', i.preference, 'mail exchanger =', i.exchange
NS记录查询
#!/usr/bin/env python import dns.resolver domain = raw_input('Please input an domain: ') ns = dns.resolver.query(domain, 'NS') for i in ns.response.answer:for j in i.items:print j.to_text()
CNAME记录查询
#!/usr/bin/env python import dns.resolver domain = raw_input('Please input an domain: ') cname = dns.resolver.query(domain, 'CNAME') for i in cname.response.answer:for j in i.items:print j.to_text()