一、端口扫描
仅仅知道网络上的主机是否可达还不够,很多情况下,我们需要的是一个端口扫描器。使用端口扫描器吋以进行安全检测与**防范。例如,在2017年5月12日,全球范围内爆发了基于Windows网络共享协议的永恒之蓝(Wannacry)勒索蠕虫。仅仅五个小时,包 括美国、中国、俄罗斯以及整个欧洲在内的100多个国家都不问程度地遭受永恒之蓝病毒,尤其是高校、大型企业内网和政府机构专网,被的电脑被勒索支付高额赎金才能解密恢复文件,对重要数据造成严重损失。永恒之蓝利用Windows系统的445端口进行蠕虫,部分运营商已经在主干网络上封禁了 445端口,但是教育网以及大量企业内网并没有此限制,从而导致了永恒之蓝勒索蠕虫的泛滥。**
所以作为工程师,一方面需要在日常维护养成良好的习惯,如配置防火墙、进行网络隔离、关闭不必要的服务、及时更新补丁;另一方面可以掌握一些安全相关的工具,在日常中进行安全防范,在紧急悄况下进行安全检测。在这一小节,我们将介绍如何使用Python进行端口扫描。有了端口扫描器,我们可以快速了解主机打开了哪些不必要的端口,以便及时消灭安全隐患。
在这一小节中,我们将使用Python语言编写一个端口扫描器,然后介绍大名鼎鼎的端 口扫描工具nmap,最后,通过python-nmap在Python代码中调用nmap进行端口扫描。
1、使用nmap扫描端口
Python-nmap模块是对nmap命令的封装。nmap是知名的网络探测和安全扫描程序, 是Network Mapper的简称。nmap可以进行主机发现(Host Discovery)、端口扫描(Port Scanning)、版本侦测(Version Detection〉、操作系统侦测(Operating System Detection),nmap是网络管理员必用的软件之一。nmap因为功能强大、跨平台、开源、文档丰富等诸多优点,在安全领域使用非常广泛。
在使用之前,需要先安装nmap。如下所示:
(1)安装namp
-bash-4.2# yum -y install nmap
nmap的使用非常灵活,功能又很强大,因此nmap有很多命令行选项。使用nmap时, 首先需要确定要对哪些主机进行扫描,然后确定怎么进行扫描(如使用何种技术,对哪些端 口进行扫描)。
nmap具有非常灵活的方式指定需要扫描的主机,我们可以使用nmap命令的-sL选项 来进行测试。-sL选项仅仅打印IP列表,不会进行任何操作。如下所示:
Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 16:57 CST
Nmap scan report for 192.168.0.0 (192.168.0.0)
Nmap scan report for 192.168.0.1 (192.168.0.1)
Nmap scan report for 192.168.0.2 (192.168.0.2)
Nmap scan report for 192.168.0.3 (192.168.0.3)
Nmap done: 4 IP addresses (0 hosts up) scanned in 2.01 seconds
-bash-4.2# nmap -sL 192.168.1.80/30
Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 16:57 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Nmap scan report for 192.168.1.81 (192.168.1.81)
Nmap scan report for 192.168.1.82 (192.168.1.82)
Nmap scan report for 192.168.1.83 (192.168.1.83)
Nmap done: 4 IP addresses (0 hosts up) scanned in 2.01 seconds
nmap提供了非常灵活的方式来指定主机,包括同时指定多个IP、通过网段指定主机、通过通配符指定主机等。如下所示:
nmap -sL 47.100.98.242 14.215.177.39
nmap -sL 47.100.98.*
nmap -sL 47.100.98.242,243,245
nmap -sL 47.100.98.242-250
nmap -sL 47.100.98.* --exclude 47.100.98.242
nmap -sL 47.100.98.242/30
除了上面指定主机的方式,我们也可以将IP地址保存到文本中,通过-iL选项读取文件中的IP地址。如下所示:
-bash-4.2# vim ip.list
192.168.1.80
127.0.0.1
-bash-4.2# nmap -iL ip.list
Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 21:32 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Host is up (0.0000050s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
22/tcp open ssh
111/tcp open rpcbind
8888/tcp open sun-answerbook
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000060s latency).
Not shown: 995 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
111/tcp open rpcbind
631/tcp open ipp
8888/tcp open sun-answerbook
(2)扫描连续端口
-bash-4.2# nmap -p20-25 47.100.98.242
(3)不进行端口扫描,仅仅判断主机是否可达
nmap -sL ip
nmap -sn ip
测试
-bash-4.2# nmap -sL 192.168.1.80
Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 17:03 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Nmap done: 1 IP address (0 hosts up) scanned in 2.01 seconds
-bash-4.2# nmap -sn 192.168.1.80
Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 17:03 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Host is up.
Nmap done: 1 IP address (1 host up) scanned in 2.01 seconds
(4)主机发现
端口扫描是nmap的重点,除此之外,我们也可以使用nmap检查网络上所有在线的主机,实现类似前边小节中列出网络上所有活跃的主机的功能。使用-sP或-sn选项可以告诉nmap不要进行端口扫描,仅仅判断主机是否可达。如下所示:
[root@bogon ~]# nmap -sP 47.100.98.*
Starting Nmap 6.40 ( http://nmap.org ) at 2020-03-01 00:25 CST
Nmap done: 256 IP addresses (0 hosts up) scanned in 206.44 seconds
[root@bogon ~]# nmap -sn 47.100.98.*
Starting Nmap 6.40 ( http://nmap.org ) at 2020-03-01 00:35 CST
Nmap done: 256 IP addresses (0 hosts up) scanned in 205.38 seconds
(5)端口扫描
端口扫描是nmap最基本,也是最核心的功能,用于确定目标主机TCP/UDP端口的开放情况。不添加任何参数便是对主机进行端口扫描。默认情况下,nmap将会扫描1000个最常用的端口号。如下所示:
[root@192 ~]# nmap 10.166.224.140
在进行端口扫描时,nmap提供了大M的参数控制端口扫描。包括端口扫描协议、端口扫描类型、扫描的端口号。如下所示:
端口扫描协议:T (TCP)、U (UDP)、S (SCTP>、P (IP);
端口扫描类型:-sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans;
扫描的端口号:-p 80,443 -p 80-160
nmap中的端口扫描协议、扫描类型和端口号相关的选项,可以结合起来使用。如下所示:
-p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
nmap通过探测将端口划分为6个状态,下表给出了每个状态的含义。
端口状态 | 状态含义 |
---|---|
open | 端口是开放的 |
closed | 端口是关闭的 |
filtered | 端口被防火墙IDS/IPS屏蔽,无法确认其状态 |
unfiltered | 端口没有被屏蔽,但是否开放需要进一步确定 |
open|filtered | 端口是开放的或被屏蔽 |
closed|filtered | 端口是关闭的或被屏蔽 |
在进行端口扫描时,可以使用不同的端口扫描类型。常见的端口扫描类型如下:
TCP SYNC SCAN:半开放扫描,这种类沏的扫描为发送一个SYN包,启动一个TCP会话,并等待响应的数据包。如果收到的是一个reset包,表明端口是关闭的; 如果收到的是一个SYNC/ACK包,则表示端口是打开的。
TCP NULL SCAN: NULL扫描把TCP头中的所有标志位都设置为NULL。如果收到的是一个RST包,则表示相应的端口是关闭的。
TCP FIN SCAN : TCP FIN扫描发送一个表示结束一个活跃的TCP连接的FIN包, 让对方关闭连接。如果收到了一个RST包,则表示相应的端口是关闭的。 TCPXMASSCAN: TCPXMAS扫描发送PSH、FIN、URG和TCP标志位被设置为1的数据包,如果收到一个RST包,则表示相砬端口是关闭的。
(6)版本侦测
nmap在进行端口扫描时,还可以进行版本侦测。版本监测功能用于确定开放端口上运行的应用程序及版本信息。如下所示:
-bash-4.2# nmap -sV 10.166.224.140
Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 17:06 CST
Nmap scan report for 10.166.224.140 (10.166.224.140)
Host is up (0.00038s latency).
All 1000 scanned ports on 10.166.224.140 (10.166.224.140) are filtered
Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.13 seconds
(7)操作系统监测
操作系统侦测用于监测主机运行的操作系统类型及设备类型等信息。nmap拥有丰富的系统数据库,可以识别2600多种操作系统与设备类型。如下所示:
-bash-4.2# nmap -sO 192.168.1.80
Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 17:05 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Host is up (0.000018s latency).
Not shown: 249 closed protocols
PROTOCOL STATE SERVICE
1 open icmp
2 open|filtered igmp
6 open tcp
17 open udp
103 open|filtered pim
136 open|filtered udplite
255 open|filtered unknown
Nmap done: 1 IP address (1 host up) scanned in 3.21 seconds
2、使用python-nmap进行端口扫描
我们在上一小节中,花f较多的篇幅介绍nmap。Python的Python-nmap仅仅趋对nmap的封装,因此,要使用Python-nmap,必须先了解nmap。Python-nmap相对于nmap, 主要的改进在于对输出结果的处理。Python-nmap将nmap的输出结果保存到宇典之中,我们只需要通过Python的字典就可以获取到nmap的输出信息,不用像Shell脚本一样通过字符串处理和正则表达式来解析nmap的结果。Python-nmap将nmap的强大功能与Python语言优秀的表达能力进行了完美的结合,使用Python语言丰富的数据结构保存结果,以便后续继续进行处理,如使用Python-nmap生成相关的报告。
Python-nmap是开源的库,因此,在使用之前需要手动进行安装。如下所示:
pip3 install python-nmap
Python-nmap的使用非常简单,我们只要创建一个PortScarmer对象,并调用对象的 scan方法就能够完成基本的nmap端口扫描。如下所示:
-bash-4.2# ipython
Python 3.8.1 (default, Mar 9 2020, 12:35:12)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import nmap
In [2]: nm = nmap.PortScanner()
In [3]: nm.scan('192.168.1.80','22-1000')
Out[3]:
{'nmap': {'command_line': 'nmap -oX - -p 22-1000 -sV 192.168.1.80',
'scaninfo': {'tcp': {'method': 'syn', 'services': '22-1000'}},
'scanstats': {'timestr': 'Thu May 14 17:13:44 2020',
'elapsed': '8.15',
'uphosts': '1',
'downhosts': '0',
'totalhosts': '1'}},
'scan': {'192.168.1.80': {'hostnames': [{'name': '192.168.1.80',
'type': 'PTR'}],
'addresses': {'ipv4': '192.168.1.80'},
'vendor': {},
'status': {'state': 'up', 'reason': 'localhost-response'},
'tcp': {22: {'state': 'open',
'reason': 'syn-ack',
'name': 'ssh',
'product': 'OpenSSH',
'version': '6.6.1',
'extrainfo': 'protocol 2.0',
'conf': '10',
'cpe': 'cpe:/a:openbsd:openssh:6.6.1'},
111: {'state': 'open',
'reason': 'syn-ack',
'name': 'rpcbind',
'product': '',
'version': '2-4',
'extrainfo': 'RPC #100000',
'conf': '10',
'cpe': ''}}}}}
当我们创建PortScanner对象时,Python-nmap会检査系统中是否已经安装了 nmap,如果没有安装,抛出PortScannerError异常。调用PortScanner对象的scan方法进行扫描以后就可以通过该类的其他方法获取本次扫描的信息。如命令行参数、主机列表、扫描的方法等。如下所示:
In [4]: nm.command_line()
Out[4]: 'nmap -oX - -p 22-1000 -sV 192.168.1.80'
In [5]: nm.scaninfo()
Out[5]: {'tcp': {'method': 'syn', 'services': '22-1000'}}
In [6]: nm.all_hosts() #所有主机
Out[6]: ['192.168.1.80']
Python-nmap还提供了以主机地址为键,获取单台主机的详细信息。包括获取主机网络状态、所有的协议、所有打开的端口号,端口号对应的服务等。如下所示:
In [8]: nm['192.168.1.80'].state()
Out[8]: 'up'
In [9]: nm['192.168.1.80'].all_protocols()
Out[9]: ['tcp']
In [10]: nm.scan('47.100.98.242,127.0.0.2','21-25')
Out[10]:
{'nmap': {'command_line': 'nmap -oX - -p 21-25 -sV 47.100.98.242,127.0.0.2',
'scaninfo': {'error': ['Failed to resolve "47.100.98.242,127.0.0.2".\nWARNING: No targets were specified, so 0 hosts scanned.\n'],
'warning': ['WARNING: No targets were specified, so 0 hosts scanned.\n'],
'tcp': {'method': 'syn', 'services': '21-25'}},
'scanstats': {'timestr': 'Thu May 14 17:22:06 2020',
'elapsed': '16.00',
'uphosts': '0',
'downhosts': '0',
'totalhosts': '0'}},
'scan': {}}
In [11]: nm['192.168.1.80'].key()
Out[11]: dict_keys(['hostnames', 'addresses', 'vendor', 'status', 'tcp'])
二、使用IPy进行IP管理
在网络设计中,首先要做的就是规划IP地址。IP地址规划的好坏直接影响路由算法的效率,包括网络性能和扩展性。在IP地址规划中,需要进行大量的IP地址计算,包括网段、网络掩码、广播地址、子网数、IP类型等计算操作。在大量的计算操作中,如果没有一个好的工具,计算IP地址是一个很无趣有容易出错的事情。在Perl语言中,可以使用NET::IP模块,在Python语言中,可以使用开源的IPy模块进行操作。
1、IPy模块介绍
IPy模块是一个处理IP地址的模块,它能够自动识别IP地址的版本、IP地址的类型。使用IPy模块,可以方便地进行IP地址的计算。
IPy模块是第三方的开源模块,因此,在使用之前需要进行安装。直接使用pip安装即可:
pip install ipy
2、IPy模块的基本使用
IPy模块有一个IP类,这个类几乎可以接受任何格式的IP地址和网段。如下所示:
In [1]: import IPy
In [2]:from IPy import IP
In [3]: IP(0x7f000001)
Out[3]: IP('127.0.0.1')
In [4]: IP('127.0.0.1')
Out[4]: IP('127.0.0.1')
In [5]: IP('127.0.0.0/30')
Out[5]: IP('127.0.0.0/30')
In [6]: IP('1080:0:0:0:8:800:200C:417A')
Out[6]: IP('1080::8:800:200c:417a')
In [7]: IP('127.0.0.0-127.255.255.255')
Out[7]: IP('127.0.0.0/8')
IP类包含了许多的方法,用来进行灵活的IP地址操作。例如:
(1)version:获取IP地址的版本
In [9]: IP('127.0.0.0-127.255.255.255')
Out[9]: IP('127.0.0.0/8')
In [10]: IP('10.0.0.0/8').version()
Out[10]: 4
In [11]: IP('::1').version()
Out[11]: 6
(2)len:得到子网IP地址的个数
In [12]: IP('127.0.0.0/30').len()
Out[12]: 4
In [13]: IP('127.0.0.0/28').len()
Out[13]: 16
(3)iptype:返回IP地址的类型
In [14]: IP('127.0.0.1').iptype()
Out[14]: 'LOOPBACK'
In [15]: IP('8.8.8.8').iptype()
Out[15]: 'PUBLIC'
(4)int:返回IP地址的整数形式
In [16]: IP('8.8.8.8').int()
Out[16]: 134744072
(5)strHex:返回IP地址的十六进制形式
In [17]: IP('8.8.8.8').strHex()
Out[17]: '0x8080808'
(6)strBin:返回IP地址的二进制形式
In [18]: IP('8.8.8.8').strBin()
Out[18]: '00001000000010000000100000001000'
有一个方便的函数能够将IP转换为不同的格式,在工作环境中将会非常有用。例如,以数宇的形式在数据库中存储IP地址,在数据库中存储IP地址有两种形式,第一种是以变长字符串的形式将IP地址保存到数据库中,另一种是将IP地址转换为整数以后保存到数据库中。将IP地址转换为整数进行存储能够有效地节省存储空间,提高数据库的存储效率和访问速度。因此,在最佳实践中,我们一般将IP地址以数字的形式保存到数据库中。需要 IP地址时,再将数字形式的IP地址转换为字符串格式的IP地址。这个需求十分常见,因 此,MySQL提供了两个函数,分别用以将字符串形式的IP地址转换为数据格式的IP地址,以及将数字格式的IP地址转换为字符串形式的IP地址。如下所示:
mysql> select INET_ATON('10.166.224.14');
+----------------------------+
| INET_ATON('10.166.224.14') |
+----------------------------+
| 178708494 |
+----------------------------+
1 row in set (0.00 sec)
mysql> select INET_NTOA('178708494');
+------------------------+
| INET_NTOA('178708494') |
+------------------------+
| 10.166.224.14 |
+------------------------+
1 row in set (0.00 sec)
除了使用MySQL自带的函数以外,我们也可以使用IP类提供的int方法将字符串形式的IP地址转换为数字形式的IP地址。要将数字形式的IP地址转换会字符串形式的IP地址,可以直接使用数字的方式创建IP对象。如下所示:
In [9]: IP('178708494')
Out[9]: IP('10.166.224.14')
In [10]: '{0}'.format(IP("178708494"))
Out[11]: '10.166.224.14'
3、网段管理
IP类的构造函数可以接受不同格式的IP地址,也可以接受网段。如下所示:
In [1]: from IPy import IP
In [2]: IP('127.0.0.0/24')
Out[2]: IP('127.0.0.0/24')
In [3]: IP('127.0.0.0-127.255.255.255')
Out[3]: IP('127.0.0.0/8')
In [4]: IP('127.0.0.0/127.255.255.255')
Out[4]: IP('127.0.0.0/31')
网段包含多个IP地址,我们可以直接使用len方法或者Python内置的len函数得到网段中IP地址的个数,也可以直接使用for循环迭代网段,以此遍历各个IP。如下所示:
In [19]: ips = IP('10.166.224.144/28')
In [20]: ips.len()
Out[20]: 16
In [21]: len(ips)
Out[21]: 16
In [22]: ip = [ip for ip in ips]
In [23]: ip = [ip for i in ips]
In [24]: ip
Out[24]:
[[IP('10.166.224.144'),
IP('10.166.224.145'),
IP('10.166.224.146'),
IP('10.166.224.147'),
IP('10.166.224.148'),
通过IP类,我们也可以方便地判断一个IP是否属于一个网段,判断子网是否包含于另一个网段中,以及两个网段是否有重叠。如下所示:
In [25]: '10.166.224.146' in IP('10.166.224.144/28')
//测试ip是否在某网段内
Out[25]: True
In [16]: '10.166.224.144' in IP('10.166.224.144/28')
Out[16]: True
In [17]: IP('10.166.224.144/29') in IP('10.166.224.144/28')
Out[17]: True
In [18]: IP('10.166.224.0/28').overlaps('10.166.224.144/28')
Out[18]: 0
对于网段,我们可以方便地获取网络地址掩码以及网络的广播地址。如下所示:
In [22]: ips.netmask()
Out[22]: IP('255.255.255.240')
In [23]: ips.broadcast()
Out[23]: IP('10.166.224.159')
三、使用dnspython解析DNS
1、dnspython简介与安装
dnspython是Python实现的一个DNS工具集,它支持几乎所有的记录类型,可以用于查询、传输并动态更新ZONE信息,同时支持TSIG(事务签名)验证消息和EDNS0(扩展DNS)。使用dnspython可以代替Linux命令行下的nslookup以及dig等工具。
dnspython是第三方的开源模块,因此,使用之前需要先进行安装:
pip3 install dnspython
2、使用dnspython进行域名解析
dnspython提供了丰富的API,其中,高层次的API根据名称和类型执行查询操作,低层次的API可以直接更新ZONE信息、消息、名称和记录。在所有的API中,最常使用的是域名查询。dnspython提供了一个DNS解析类resolver,使用它的query方法可以实现域名的查询功能。
dns.resolver.query(qname,rdtype=1,rdclass=1,tcp=False,source=None,raise_on_no_answer=True,source_port=0)
query方法各参数的含义如下:
qname:査询的域名;
rdtype:指定RR资源;
A:地址记录(Address),返回域名指向的IP地址;
NS:域名服务器记录(Name Server),返回保存下一级域名信息的服务器地址。该记录只能设罝为域名,不能设置为IP地址;
MX:邮件记录(Mail exchange),返回接收电子邮件的服务器地址;
CNAME:规范名称记录(Canonical Name),别名记录,实现域名间的映射;
PTR:逆向査询记录(Pointer Record),反向解析,与A记录相反,将IP地址转换为主机名。
rdclass:网络类型;
tcp:指定査询是否启用TCP协议;
source:査询源的地址;
source_port:査询源的端口 ;
raise_on_no_answer:指定査询无应答时是否触发异常,默认为True。
在使用dnspython查询DNS相关信息之前,我们先简单了解一下dig命令,以便对照查看Python程序的输出结果与dig命令的输出结果。
dig的全称是domain information groper,它是一个灵活探测DNS的工具,可以执行DNS査找,并显示从查询的名称服务器返回的答案。由于dig命令灵活易用、输出明确, 因此,大多数DNS管理员都使用dig解决DNS问题。
在我的主机上运行dig命令査找dnspython.org域名的信息。运行结果如下:
[root@192 ~]# dig qiniu.lexizhi.com
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> qiniu.lexizhi.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35907
;; flags: qr rd ra; QUERY: 1, ANSWER: 12, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;qiniu.lexizhi.com. IN A
;; ANSWER SECTION:
qiniu.lexizhi.com. 5 IN CNAME www.lexizhi.com.qiniudns.com.
www.lexizhi.com.qiniudns.com. 5 IN CNAME dt003.china.line.qiniudns.com.
dt003.china.line.qiniudns.com. 5 IN CNAME tinychinacdnweb.qiniu.com.w.kunlunno.com.
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.231
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.234
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.232
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.233
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 219.147.157.66
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.228
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.235
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.229
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.230
;; Query time: 633 msec
;; SERVER: 192.168.79.2#53(192.168.79.2)
;; WHEN: 一 3月 02 17:29:51 CST 2020
;; MSG SIZE rcvd: 300
(1)在Python代码中,可以使用dnspython查询A记录。如下所示:
from __future__ import print_function
import dns.resolver
data = dns.resolver.query('www.lexizhi.com', 'A')
for item in data:
print(item)
输出结果如下:
47.100.98.242
(2)使用dnspython实现NS记录,查询方法如下:
from __future__ import print_function
import dns.resolver
data = dns.resolver.query('dnspython.org', 'NS')
for item in data:
print(item)
输出结果如下:
ns-343.awsdns-42.com.
ns-518.awsdns-00.net.
ns-1253.awsdns-28.org.
ns-2020.awsdns-60.co.uk.
从输出结果来看,使用dig命令或dnspython模块都是一样的。如果在命令行操作,建议使用dig命令。如果要使用程序管理DNS或查询DNS的内容,则推荐使用dnspython模块。