dnspython: DNS处理库
2025-02-17
- dnspython是python实现的一个DNS工具包
- 支持几乎所有的记录类型,可以用于查询,传输并动态更新ZONE信息,支持TSIG(事务签名),验证信息和EDNS()(扩展DNS)
- 可以利用查询功能实现DNS服务监控以及解析结果的校验
- 可以代替nslooup和dig等工具,做到与现有平台的整合
# 源码安装dnspython
print('''
wget http://www.dnspython.org/kits/1.9.4/dnspython-1.9.4.tar.gz
tar zxvf dnspython-1.9.4.tar.gz
cd dnspython-1.9.4
python setup.py install
''')wget http://www.dnspython.org/kits/1.9.4/dnspython-1.9.4.tar.gz
tar zxvf dnspython-1.9.4.tar.gz
cd dnspython-1.9.4
python setup.py install模块域名解析方法
常用的方法:域名查询
dnspython提供的一个DNS解析器类--resolver. 他的query方法来实现域名的查询功能
定义语法
query(self,qname,rdtype=1,rdclass=1,tcp=False,source=None,raise_on_no_answer=True,source_port=0)参数的理解
- qname参数: 为查询的域名
- rdtype参数: 制定RR资源的类型
- A记录: 将主机名转换成IP地址
- MX记录: 邮件交换记录,定义邮件服务器的域名
- CNAME记录: 指别名记录,实现域名间的映射
- NS记录: 标记区域的域名服务器及授权子域
- PTR记录: 反向解析,与A记录相反,将IP转换成主机名
- SOA记录: SOA标记,一个其实授权区的定义
- reclass参数: 指定网路类型
- IN: 为默认,使用比较广泛
- CH HS
- tcp参数: 用于指定查询是否启用TCP协议,默认为False(不启用)
- source与source_port参数: 指定查询源地址与端口。默认值为:查询设备IP和0
- raise_on_no_answer参数:指定当查询无应答时,是否触发异常,默认为True
常见解析类型示例说明
- DNS解析类型包括
- A MX NS CNAME
- 用dnspython 的 dns.resolver.query 方式简单实现这些DNS类型的查询
# A记录查询
# 下面的代码却在的一个缺点就是,但域名存在CNAME解析的时候,就会报错
import dns.resolver
domain = input("请输入你的域名地址:")
A = dns.resolver.query(domain,'A') # 指定查询类型为A记录
print(A)
print(A.response.answer)
for i in A.response.answer: # 通过response.answer方法获取查询回应信息
for j in i.items: # 遍历回应信息,一般使用items,因为通过response.answer得到的可能不止一个DNS解析服务器
print(j.address)请输入你的域名地址:www.google.com
<dns.resolver.Answer object at 0x000001E1B2E27630>
[<DNS www.google.com. IN A RRset>]
31.13.97.248# MX记录
import dns.resolver
domain = input("请输入你的域名:")
MX = dns.resolver.query(domain,'MX') # 指定查询类型为MX记录
for i in MX: # 通过遍历回应查询结果,输出MX记录的preference及exchanger信息
print ("MX preference = ", i.preference, 'Mail exchanger = ', i.exchange)请输入你的域名:163.com
MX preference = 10 Mail exchanger = 163mx01.mxmail.netease.com.
MX preference = 50 Mail exchanger = 163mx00.mxmail.netease.com.
MX preference = 10 Mail exchanger = 163mx03.mxmail.netease.com.
MX preference = 10 Mail exchanger = 163mx02.mxmail.netease.com.# NS记录
# 在进行NS记录查询的时候,只限制输入一级域名,当输入的是二级域名的时候,会出现报错信息
import dns.resolver
domain = input("请输入你的域名(只限制输入一级域名):")
NS = dns.resolver.query(domain,'NS') # 指定查询类型为NS记录
for i in NS.response.answer:
for j in i.items:
print (j.to_text())请输入你的域名(只限制输入一级域名):baidu.com
ns3.baidu.com.
dns.baidu.com.
ns4.baidu.com.
ns2.baidu.com.
ns7.baidu.com.# CNAME记录
import dns.resolver
domain = input("请输入你的域名:")
CNAME = dns.resolver.query(domain,'CNAME') # 制定查询类型为CNAME记录
for i in CNAME.response.answer: # 对CNAME进行遍历查询
for j in i.items:
print(j.to_text())请输入你的域名:www.baidu.com
www.a.shifen.com.实践:DNS域名轮询业务监控
- 大部分DNS解析都是:一个域名对应一个IP地址
- 通过DNS轮询可以:一个域名对应多个IP,实现简单高效的负载均衡
- 弊端: 目标主机不可用时无法被自动剔除。
- 目标:
- 对当前的域名进行解析
- 通过服务端口探测实现自动监控
- 在解析中添加,删除IP
# 1. 实现域名的解析,获取域名所有的A记录解析列表
# 2. 对IP列表进行HTTP级别的探测
# 3. 通过dns.resolver.query() 获取域名A记录信息
# 4. 使用 httplib 模块的 request() 以GET方式请求监控页面,监控业务所有服务的IP是否服务正常
# 代码案例:dns.resolver.query()
import dns.resolver
import os
import httplib
iplist=[] # 定义域名IP列表变量
appdomain = "www.google.com.hk" # 定义业务域名
def get_iplist(domain=""): # 定义域名解析函数,解析成功的IP将被追加到iplist
try:
A = dns.resolver.query(domain,'A') # 解析A记录类型
except Exception, e:
print('DNS resovler error:'+str(e))
return
for i in A.response.answer:
for j in i.items:
print(j.address)
iplist.append(j.address) # 追加到iplist
def checkip(ip):
checkurl = ip + ":80"
getcontent = ""
httplib.socket.setdefaulttimeout(5) # 定义http连接超时时间(5)秒
conn = httplib.HTTPConnection(checkurl) # 创建http连接对象
try:
conn.request("GET","/",headers = {"Host": appdomain})
r = conn.getresponse()
getcontent = r.read(15) # 获取URL页面前15个字符,以便做可用性校验
finally:
if getcontent == "<!doctype html>": # 监控URL页的内容一般是事先定义好的,比如 “HTTP200” 等
print (ip + "[OK]")
else:
print (ip + "[Error]") # 这里可以放告警程序,可以是邮件,短信等
if __name__=="__main__":
if get_iplist(appdomain) and len(iplist)>0: # 条件,域名解析正确却至少返回一个IP
for ip in iplist:
checkip(ip)
else:
print ("DNS resolver error")