DNS处理模块 dnspython

news2024/9/26 5:21:02

DNS处理模块 dnspython

    • 标题介绍
    • 安装dnspython 模块
    • 常用方法介绍
    • 实践:DNS域名轮询业务监控

标题介绍

Dnspython 是 Python 的 DNS 工具包。它可用于查询、区域传输、动态更新、名称服务器测试和许多其他事情。
dnspython 模块提供了大量的 DNS 处理方法,最常用的方法是域名查询。
dspython 提供了一个DNS 解析器类–resolve,使用它的 reslover方法来实现域名的查询功能。

安装dnspython 模块

采用pip的方式直接安装

pip install dnspython

dns.resolve 源码如下


    def resolve(
        self,
        qname: Union[dns.name.Name, str],
        rdtype: Union[dns.rdatatype.RdataType, str] = dns.rdatatype.A,
        rdclass: Union[dns.rdataclass.RdataClass, str] = dns.rdataclass.IN,
        tcp: bool = False,
        source: Optional[str] = None,
        raise_on_no_answer: bool = True,
        source_port: int = 0,
        lifetime: Optional[float] = None,
        search: Optional[bool] = None,
    ) -> Answer: 
 
        resolution = _Resolution(
            self, qname, rdtype, rdclass, tcp, raise_on_no_answer, search
        )
        start = time.time()
        while True:
            (request, answer) = resolution.next_request()
            # Note we need to say "if answer is not None" and not just
            # "if answer" because answer implements __len__, and python
            # will call that.  We want to return if we have an answer
            # object, including in cases where its length is 0.
            if answer is not None:
                # cache hit!
                return answer
            assert request is not None  # needed for type checking
            done = False
            while not done:
                (nameserver, tcp, backoff) = resolution.next_nameserver()
                if backoff:
                    time.sleep(backoff)
                timeout = self._compute_timeout(start, lifetime, resolution.errors)
                try:
                    response = nameserver.query(
                        request,
                        timeout=timeout,
                        source=source,
                        source_port=source_port,
                        max_size=tcp,
                    )
                except Exception as ex:
                    (_, done) = resolution.query_result(None, ex)
                    continue
                (answer, done) = resolution.query_result(response, None)
                if answer is not None:
                    return answer

resolve 方法的定义如下:
参数解析:
● qname 指定查询的名称
● rdtype 指定查询的类型 默认是A记录

  • A记录,将主机名转换为IP地址;
  • MX记录,邮件交换记录,定义邮件服务器的域名;
  • CNAME记录,指别名记录,实现域名间的映射;
  • NS记录,标记区域的域名服务器及授权子域;
  • PTR记录,反向解析,与A记录相反,将IP转换为主机名;
  • SOA记录,SOA标记,一个起始授权区的定义。

● rdclass 指定查询的网络类型 ,可选的值有IN、CH与HS,默认是 IN
● tcp 是否启用tcp查询模式
● source 和source_port 指定 查询用的源地址和端口
● raise_on_no_answer 查询无结果的时候,是否需要抛出异常
● lifetime 声明周期配置参数,采用默认值

常用方法介绍

  1. A记录
import dns.resolver

domain = "www.baidu.com"
# 获取解析对象
query_object = dns.resolver.resolve(qname=domain, rdtype='A')  # 指定查询记录为A
print('查询对象:{}'.format(query_object))
# 应答对象
response_object = query_object.response  # 指定查询记录为 A
print('应答对象:{}'.format(response_object))
print("-"*20)
# 解析对象
answer_object = response_object.answer  # 指定查询记录为A
print('解析对象:{}'.format(answer_object))
# print(len(answer_object))
print('解析对象1:{}'.format(answer_object[0]))
print('解析对象2:{}'.format(answer_object[1]))

print("-"*20)
for i in answer_object:
    print(f"查询条目: {i}")
    for j in i.items:
        print(f"解析记录: {j}")

在这里插入图片描述

import dns.resolver
# 基本信息
domain = input("Please input domain: " )
dns_type = 'A'

query_object = dns.resolver.resolve(qname=domain, rdtype='A')
for query_item in query_object.response.answer:
    for item in query_item.items:
        print("{}的A记录解析地址有:{}".format(domain, item))

在这里插入图片描述

  1. MX邮件记录
import dns.resolver
# 基本信息
domain = "163.com"
dns_type = 'MX'
# A记录解析效果
query_object = dns.resolver.resolve(domain, dns_type)  # 指定查询记录为MX
# 从应答的answer中获取查询记录
for query_item in query_object.response.answer:
# 获取解析的记录信息
    for item in query_item.items:
        print("邮件服务器权重:{},邮件服务器地址:{} ".format(domain,item))

在这里插入图片描述

import dns.resolver
# 基本信息
domain = "163.com"
dns_type = 'MX'
# 获取解析对象
# query_object1 = dns.resolver.query(domain,dns_type)      # query 后续可能不在支持
query_object = dns.resolver.resolve(domain, dns_type)   # 指定查询记录为A
print("MX记录的结果:{} ".format(query_object))
# 从应答的response中获取查询记录
resp_object = query_object.response
print("MX记录的结果:{}".format(resp_object))
# 查看answer对象
answer_object = resp_object.answer
print("解析对象:{}".format(answer_object))
# 查看解析条目对象
answer_object = resp_object.answer
for query_item in answer_object:
    print("查询条目:{}".format(query_item))
print('-' * 20)
# 查看解析后的记录条目--详情
# 1. preference 权重, exchange 替换服务器主机
query_item = resp_object.answer[0]
for item in query_item.items:
    print("邮件服务器权重:{},邮件服务器地址:{} ".format(item.preference,item.exchange))

在这里插入图片描述
在这里插入图片描述

  1. NS 记录结构
    NS(Name Server)域名服务器记录。用来表明由哪台服务器对该域名进行解析。在注册域名时,总有默认的DNS服务器,每个注册的域名都是由一个DNS域名服务器来进行解析的。但是需要注意的是只能输入一级域名,如:baidu.com;对于二级以及多级域名,如www.baidu.com、wenku.baidu.com则是错误的。
import dns.resolver
# 基本信息
domain = "jdy.com"
dns_type = 'NS'
# 获取解析对象
query_object = dns.resolver.resolve(domain, dns_type)   # 指定查询记录为NS
print("NS记录的结果:{} ".format(query_object))
print('-' * 20)
# 从应答的response中获取查询记录
resp_object = query_object.response
print("NS记录的结果:{}".format(resp_object))
print('-' * 20)
# 查看answer对象
answer_object = resp_object.answer
print("解析对象:{}".format(answer_object))
print('-' * 20)
# 查看解析条目对象
answer_object = resp_object.answer
for query_item in answer_object:
    print("查询条目:{}".format(query_item))
print('-' * 20)
# 查看解析后的记录条目 - 2
query_item = resp_object.answer[0]
for item in query_item:
    print("查询条目:{}".format(item))
    print("数据格式:{}".format(type(item)))
print('-' * 20)
query_item = resp_object.answer[0]
for item in query_item:
    print("查询条目:{}".format(item.to_text()))
    print("数据格式:{}".format(type(item.to_text())))

在这里插入图片描述

import dns.resolver
# 基本信息
domain = input("Please input domain: " )
dns_type = 'NS'
# NS记录解析效果
query_object = dns.resolver.resolve(domain, dns_type)  # 指定查询记录为A
# 从应答的answer中获取查询记录
for query_item in query_object.response.answer:
# 获取解析的记录信息
    for item in query_item.items:
        print("{}的NS记录解析结果有:{} ".format(domain,item))

在这里插入图片描述

  1. CNAME记录结构
import dns.resolver
# 基本信息
domain = "www.baidu.com"
dns_type = 'CNAME'
# 获取解析对象
query_object = dns.resolver.resolve(domain, dns_type)   # 指定查询记录为CNAME
print("CNAME记录的结果:{} ".format(query_object))
print('-' * 20)
# 从应答的response中获取查询记录
resp_object = query_object.response
print("CNAME记录的结果:{}".format(resp_object))
print('-' * 20)
# 查看answer对象
answer_object = resp_object.answer
print("解析对象:{}".format(answer_object))
print('-' * 20)
# 查看解析条目对象
answer_object = resp_object.answer
for query_item in answer_object:
    print("查询条目:{}".format(query_item))
print('-' * 20)
# 查看解析后的记录条目 - 2
query_item = resp_object.answer[0]
for item in query_item:
    print("查询条目:{}".format(item))

在这里插入图片描述

import dns.resolver
# 基本信息
domain = input("Please input domain: " )
dns_type = 'CNAME'
# NS记录解析效果
query_object = dns.resolver.resolve(domain, dns_type)  # 指定查询记录为A
# 从应答的answer中获取查询记录
for query_item in query_object.response.answer:
# 获取解析的记录信息
    for item in query_item.items:
        print("{}的CNAME记录解析结果有:{} ".format(domain,item))

在这里插入图片描述

实践:DNS域名轮询业务监控

大部分的 DNS 解析都是一个域名对应一个 IP 址,但是通过 DNS 轮循技术可以做到个域名对应多个IP,从而实现最简单且高效的负载平衡,
不过此方案最大的弊端是目标主机不可用时无法被自动剔除,因此做好业务主机的服务可用监控至关重要。
本示例通过分析当前域名的解析 IP,再结合服务端口探测来实现自动监控,在域名解析中添加、删除 IP 时无须对监控脚本进行更改。

  • 步骤
  • 实现域名的解析,获取域名所有的A记录解析IP列表;
  • 对IP列表进行HTTP级别的探测。
"""
代码思路:
    1. 获取有效IP列表
        获取记录类型
        将获取的值添加到列表中
    2. 对IP列表里面的值进行检测
        创建IP地址的连接
        尝试发起请求
        对请求的响应内容进行判断,并输出结果
    3. 测试主程序
        先获取IP列表,然后对IP进行测试
"""
import dns.resolver
import http.client
import re


# 准备工作
iplist = []  #定义域名IP列表
appdomain = 'www.baidu.com' #定义业务域名

# 判断解析的数据是不是IP
def is_ipv4(ip):
    # 使用正则表达式检查是否为IPv4地址
    pattern = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
    return re.match(pattern, ip) is not None
def get_iplist(domain=""):
    try:
        dns_type = 'A'
        ip_result = dns.resolver.resolve(domain, dns_type)
    except Exception as e:
        print("dns解析失败:{}".format(str(e)))
        return False
    # 将获取的值添加到列表中
    for rdata in ip_result:
        if is_ipv4(rdata.address):  #要判断是不是IP需要 加上address
            iplist.append(rdata.address)
		    print(type(data))   #<class 'dns.rdtypes.IN.A.A'>
		    print(type(data.address))   #<class 'str'>

    return True
def checkip(ip):
    conn = http.client.HTTPConnection(ip, port=80, timeout=10)
    try:
        conn.request("GET", "/", headers={"Host": appdomain})
        response = conn.getresponse()
        if response.status == 200:
            first_bytes = response.read(6)
            if first_bytes.startswith(b"<html>") or first_bytes.startswith(b"<!DOCT"):
                print("{} 状态: Ok".format(ip))
            else:
                print("{} 状态: 可能不是HTML内容".format(ip))
        else:
            print("{} 状态码: {}".format(ip, response.status))
    except Exception as e:
        print("网络超时或者地址访问异常,请重试: {}".format(str(e)))
    finally:
        conn.close()
# 测试主程序
if __name__ == '__main__':
    if get_iplist(appdomain) and len(iplist) > 0:
        for ip in iplist:
            # print("{} 的正常解析IP有: {}".format(appdomain,ip))
            checkip(ip)
    else:
        print("dns 解析后的IP地址有误")

  1. A记录解析的IP地址必须能够被ping正常测试,否则失败
  2. 正常的126.com虽然可以正常,但是测试失败。
    因为格式不一致,测试失败。
    将二进制格式转为普通的utf-8格式
    str(b’sdfads’,“utf-8”)
    for rdata in ip_result:
        if is_ipv4(rdata.address):  #要判断是不是IP需要 加上address
            iplist.append(rdata.address)
		    print(type(data))   #<class 'dns.rdtypes.IN.A.A'>
		    print(type(data.address))   #<class 'str'>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink 实时数仓(五)【DWD 层搭建(三)交易域事实表】

前言 今天开始交易域事实表的创建&#xff0c;上一节流量域中的表&#xff08;其实就是一个 kafka 主题&#xff09;数据来自于日志&#xff0c;而交易域的数据来自于业务系统&#xff0c;业务表之间是有关联性的。 我们之前在离线数仓中&#xff08;声明粒度&#xff08;最细粒…

oracle数据库监控数据库中某个表是否正常生成

事情经过&#xff1a; 公司某业务系统每月25日0点会自动生成下个月的表&#xff0c;表名字是tabname_202407的格式。由于7月25日0点做系统保养的时候重启了应用系统服务&#xff0c;导致8月份的表没有生成。最终操作业务影响&#xff0c;为此决定对这个表进行监控&#xff0c;…

Depth Anything——强大的单目深度估计模型

概述 单目深度估计&#xff08;Monocular Depth Estimation, MDE&#xff09;是一项在计算机视觉领域中非常重要的技术&#xff0c;它旨在从单张图像中恢复出场景的三维结构。这项技术对于机器人导航、自动驾驶汽车、增强现实&#xff08;AR&#xff09;和虚拟现实&#xff08…

DVWA(SQL注入)medium、high

medium &#xff08;1&#xff09;判断注入是字符型还是数值型 数值型&#xff0c;获得了用户信息。 id 1 or 11 &#xff08;2&#xff09;查询字段数 为3时报错&#xff0c;代表字段数为2。 1 order by 3 &#xff08;3&#xff09;显示字段顺序 1 union select 1,2 &…

大数据与人工智能:数据隐私与安全的挑战_ai 和 数据隐私

前言 1.背景介绍 随着人工智能(AI)和大数据技术的不断发展&#xff0c;我们的生活、工作和社会都在不断变化。这些技术为我们提供了许多好处&#xff0c;但同时也带来了一系列挑战&#xff0c;其中数据隐私和安全是最为关键的之一。数据隐私和安全问题的出现&#xff0c;主要…

Redis7.x安装系列教程(一)单机部署

1、前言&环境准备说明 本文及接下来3篇将详细介绍在linux环境Redis7.X源码安装系列教程&#xff0c;从最简单的单机部署开始&#xff0c;逐步升级主从部署、哨兵部署和集群部署。 环境准备&#xff1a;如果有条件的用云服务器&#xff0c;如果没有的使用VMware 虚拟机&am…

【精通Redis】Redis事务

文章目录 前言一、标准事务1.1 标准事务的特性1.2 标准事务的生命周期1.3 事务的作用 二、Redis事务2.1 Redis事务的特性2.2 Redis事务与普通事务的区别 三、Redis事务常用命令总结 前言 我们在使用Redis的时候&#xff0c;有时为了处理多个结构&#xff0c;需要向Redis中一次…

Python数据结构实战:列表、字典与集合的高效使用

前言 在编程中&#xff0c;选择合适的数据结构对于提高程序效率至关重要。本文将介绍Python中最常用的数据结构——列表&#xff08;list&#xff09;、字典&#xff08;dict&#xff09;和集合&#xff08;set&#xff09;&#xff0c;并探讨它们的内部实现以及如何高效地使用…

The operation was rejected by your operating system. code CERT_HAS_EXPIRED报错解决

各种报错&#xff0c;试了清缓存&#xff0c;使用管理员权限打开命令行工具&#xff0c;更新npm&#xff0c;都不好使 最终解决&#xff1a;删除 c:/user/admin/ .npmrc

我的最爱之《达明一派》

达明一派&#xff0c;是我最爱。刘以达(Tats)与黄耀明(Anthony Wong)在1980年代的香港组成的二人流行音乐组合&#xff0c;在90年代&#xff0c;网络还没兴起时&#xff0c;那是卡带流行的岁月。90年代&#xff0c;我与好友&#xff0c;同考大学&#xff0c;他留在了南充读读书…

世媒讯带您了解什么是媒体邀约

什么是媒体邀约&#xff1f;其实媒体邀约是一种公关策略&#xff0c;旨在通过邀请媒体记者和编辑参加特定的活动、发布会或其他重要事件&#xff0c;以确保这些活动能够得到广泛的报道和关注。通过这种方式&#xff0c;企业和组织希望能够传达重要信息&#xff0c;提高品牌知名…

网络监控软件的作用是什么|企业用的六款网络监控软件

网络监控软件是干什么的呢&#xff1f;它是用来管理网络安全的&#xff0c;尤其是对于企业而言至关重要&#xff0c;下面我为你推荐六款知名的网络监控软件。 1. 安企神 功能特点&#xff1a; 全面监控&#xff1a;提供电脑屏幕监控、文件操作监控、聊天记录监控等功能&#…

全开源图床系统源码

一款专为个人需求设计的高效图床解决方案&#xff0c;集成了强大的图片压缩功能与优雅的前台后台管理界面。 项目结构精简高效&#xff0c;提供自定义图片压缩率与尺寸设置&#xff0c;有效降低存储与带宽成本。 支持上传JPEG、PNG、GIF格式图片并转换为WEBP格式&#xff0c;…

算法:BFS 解决多源最短路问题

目录 多源最短路 题目一&#xff1a;矩阵 题目二&#xff1a;飞地的数量 题目三&#xff1a;地图中的最高点 题目四&#xff1a;地图分析 多源最短路 首先想要知道多源最短路&#xff0c;就先要明白单源最短路&#xff0c;bfs解决单源最短路问题前面学习过&#xff0c;单…

leetcode-二叉树oj题1(共三道)--c语言

目录 a. 二叉树的概念以及实现参照博客&#xff1a; 一、三道题的oj链接 二、每题讲解 1.单值二叉树 a. 题目&#xff1a; b. 题目所给代码 c. 思路 d. 代码&#xff1a; 2. 相同的树 a. 题目 b. 题目所给代码 c. 思路 d. 代码 3. 二叉树的前序遍历 a. 题目 b.…

J029_UDP通信

一、需求描述 实现UDP的通信 1.1 一发一收 1.1.1 ClientTest1 package com.itheima.udp;import java.net.*;import static java.net.InetAddress.*;//完成udp通信快速入门&#xff0c;实现一收一发 public class ClientTest1 {public static void main(String[] args) thro…

递归 35

方法递归 递归算法 package File;public class digui {public static void main(String[] args) {//猴子吃桃//f(10)1//f(n)-f(n)/2—1f&#xff08;n1&#xff09;//f(n)F(n1)2System.out.println(f(3));}public static int f(int n){if (n10){return 1;}else {return 2*f(n1)…

MEME币热潮结束了?上市成功率仅1.4%!迷因暴富梦醒?洗量超容易,热潮都是假?

近年来&#xff0c;随着加密货币行业的蓬勃发展&#xff0c;各种迷因币(meme coins)也在此浪潮之中纷纷崛起。然而&#xff0c;在专门用于创造迷因币的平台"pump.fun"上&#xff0c;绝大多数迷因币都无法真正成功发行和上市。 最新的数据显示&#xff0c;近日Solana迷…

golang国内proxy设置

go env -w GOPROXYhttps://goproxy.cn,direct经常使用的两个, goproxy.cn 和 goproxy.io 连接分别是 https://goproxy.cn https://goproxy.io 如果遇到某些包下载不下来的情况&#xff0c;可尝试更换数据源 更推荐使用https://goproxy.cn 速度快&#xff0c;缓存的包多 提醒…

树莓派5进行YOLOv8部署的4种不同部署方式检测速度对比:pytorch、onnx、ncnn、tflite

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…